以下に示すような標高を含む地形データがあります
また、各ファイルは1,440,000行で構成されています
.
.
.
183
192
127
.
.
.
フルデータメモリを無駄にロードせずに、ファイルから特定の行に直接アクセスするにはどうすればよいですか?(Androidの場合)
以下に示すような標高を含む地形データがあります
また、各ファイルは1,440,000行で構成されています
.
.
.
183
192
127
.
.
.
フルデータメモリを無駄にロードせずに、ファイルから特定の行に直接アクセスするにはどうすればよいですか?(Androidの場合)
あなたの最善の選択肢は、テキストファイルをSQLiteデータベースに変換することだと思います。
おそらくBufferedInputStreamを使用することをお勧めします:http: //developer.android.com/reference/java/io/BufferedInputStream.html
java.nio.FileChannel.read(buffers、start、number)を使用できると思います。
startは開始オフセットを意味し、numberは読み取るバイト数です。
ファイルをバイナリ形式に変更できる場合は、目的の位置に直接シークして、必要な値を読み取ることができます。そうでない場合は、おそらく1行ずつ読み取り、必要な行を返す必要があります(行の長さが異なる可能性があるため、バイト位置を計算できないと仮定します)。
少し長すぎて遊んだ後、私はこれを手に入れました(しかしそれはテストされていません):
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;
}
レコードが固定長の場合は、計算して目的のバイト位置に直接移動できます。
レコードが可変長であるが、非常に大きなファイルの順次識別情報(レコード番号など)が含まれている場合は、平均レコード長に基づいて開始位置を推測し、その少し前を探してから、前方に読んで見つける価値があるかもしれません。目的の行(すでにそれを過ぎている場合は少しバックアップします)。
最初から数える以外にレコードを識別する方法がない場合は、それを行う必要があります。理想的には、スキャン中にオブジェクトを作成し、ガベージコレクターにそれらをクリーンアップさせることについてぶつからない方法でそうするでしょう...