У меня есть данные ландшафта, которые содержат отметки, как показано ниже
И каждый файл состоит из 1440 000 строк
.
.
.
183
192
127
.
.
.
как я могу получить доступ к конкретным строкам непосредственно из файла без расточительной загрузки полной памяти? (в Android)
Я считаю, что ваш лучший вариант - преобразовать ваш текстовый файл в базу данных SQLite.
Вероятно, вы захотите использовать BufferedInputStream: http://developer.android.com/reference/java/io/BufferedInputStream.html
Если вы можете изменить файл в двоичном формате, вы можете напрямую искать нужную позицию и читать нужное значение. Если нет, вам, вероятно, придется читать его по очереди и возвращать нужную строку (при условии, что вы не можете вычислить позицию байта, так как строки могут иметь разную длину).
Поиграв слишком долго, я получил это (это было непроверено):
File f = new File ("yourfile.txt");
HashMap <Integer, String> result = readLines(f, 1, 5, 255);
String line5 = result.get(5); // or null if the file had no line 5
private static HashMap <Integer, String> readLines(File f, int... lines) {
HashMap<Integer, String> result = new HashMap<Integer, String>();
HashSet<Integer> linesSet = new HashSet<Integer>();
for (int line : lines) {
linesSet.add(Integer.valueOf(line));
}
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
int line = 1; // starting at line 1
String currentLine = null;
while ((currentLine = br.readLine()) != null) {
Integer i = Integer.valueOf(line);
if (linesSet.contains(i))
result.put(i, currentLine);
line++;
}
} catch (FileNotFoundException e) {
// file not found
} catch (UnsupportedEncodingException e) {
// bad encoding specified
} catch (IOException e) {
// could not read
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
// ignore.
}
}
}
return result;
}
Я думаю, вы можете использовать java.nio.FileChannel.read (буферы, начало, номер).
start означает начальное смещение, а число - количество прочитанных байтов.
Если записи фиксированной длины, вы можете рассчитать и перейти непосредственно к позиции байта нужного.
Если записи являются переменной длиной, но включают в себя последовательную идентификационную информацию (например, номер записи) для очень большого файла, было бы целесообразно угадать исходную позицию на основе средней длины записи, попытаться немного до этого, а затем прочитать вперед, чтобы найти нужная строка (если вы уже прошли мимо нее немного назад).
Если нет способа идентифицировать запись, отличную от подсчета с самого начала, вам придется это сделать. В идеале вы сделали бы это таким образом, чтобы не трястись о создании объектов во время сканирования, а затем, когда сборщик мусора очистил их...
int
, гарантированно имеет фиксированную длину, довольно легко (возможно, -endianess) для чтения / записи, потенциально меньше по размеру («123 \ n» уже 4 байта) и легче чтобы вычислить желаемую позицию, чем текстовое представление, где вы можете иметь\r\n
, заголовки спецификации и другие подводные камни.