Javaでは、ファイルから特定の行を読み取る方法はありますか?たとえば、32行目またはその他の行番号を読み取ります。
Javaでは、ファイルから特定の行を読み取る方法はありますか?たとえば、32行目またはその他の行番号を読み取ります。
回答:
ファイル内の行に関する事前の知識がない限り、前の31行を読み取らずに32行目に直接アクセスする方法はありません。
これは、すべての言語とすべての最新のファイルシステムに当てはまります。
つまり、32行目が見つかるまで、単に行を読み取るだけです。
小さなファイルの場合:
String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)
大きなファイルの場合:
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line32 = lines.skip(31).findFirst().get();
}
私が知っていることではありませんが、あなたができることは、BufferedReaderのreadline()関数を使用して何もしない最初の31行をループすることです
FileInputStream fs= new FileInputStream("someFile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for(int i = 0; i < 31; ++i)
br.readLine();
String lineIWant = br.readLine();
もちろん、Joachimは正解です。Chrisの代替実装(ファイル全体をロードするためだけの小さなファイルの場合)は、Apacheからcommons-ioを使用することです(ただし、おそらく、これは、他のことにも役立つ場合は、理にかなっています)。
例えば:
String line32 = (String) FileUtils.readLines(file).get(31);
indexed-file-reader(Apache License 2.0)を試してみてください。IndexedFileReaderクラスにはreadLines(int from、int to)というメソッドがあり、キーが行番号で値が読み取られた行であるSortedMapを返します。
例:
File file = new File("src/test/resources/file.txt");
reader = new IndexedFileReader(file);
lines = reader.readLines(6, 10);
assertNotNull("Null result.", lines);
assertEquals("Incorrect length.", 5, lines.size());
assertTrue("Incorrect value.", lines.get(6).startsWith("[6]"));
assertTrue("Incorrect value.", lines.get(7).startsWith("[7]"));
assertTrue("Incorrect value.", lines.get(8).startsWith("[8]"));
assertTrue("Incorrect value.", lines.get(9).startsWith("[9]"));
assertTrue("Incorrect value.", lines.get(10).startsWith("[10]"));
上記の例では、50行で構成されるテキストファイルを次の形式で読み取ります。
[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN
Disclamer:このライブラリを作成しました
他の答えで述べたように、以前にオフセット(ポインタ)を知らなければ、正確な行に到達することはできません。したがって、すべての行のオフセット値を格納する一時インデックスファイルを作成することで、これを実現しました。ファイルが十分に小さい場合は、個別のファイルを必要とせずに、インデックス(offset)をメモリに格納できます。
The offsets can be calculated by using the RandomAccessFile
RandomAccessFile raf = new RandomAccessFile("myFile.txt","r");
//above 'r' means open in read only mode
ArrayList<Integer> arrayList = new ArrayList<Integer>();
String cur_line = "";
while((cur_line=raf.readLine())!=null)
{
arrayList.add(raf.getFilePointer());
}
//Print the 32 line
//Seeks the file to the particular location from where our '32' line starts
raf.seek(raf.seek(arrayList.get(31));
System.out.println(raf.readLine());
raf.close();
詳細については、java docsもご覧ください。https: //docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode
複雑さ:ファイル全体を1回読み取るため、これはO(n)です。メモリ要件に注意してください。大きすぎてメモリに収まらない場合は、上記のようにArrayListではなくオフセットを格納する一時ファイルを作成します。
注意:すべてが「32」行で必要な場合は、他のクラスでも利用可能なreadLine()を「32」回呼び出すだけです。上記のアプローチは、特定の行を(もちろん行番号に基づいて)複数回取得する場合に役立ちます。
よろしくお願いします!
別の方法。
try (BufferedReader reader = Files.newBufferedReader(
Paths.get("file.txt"), StandardCharsets.UTF_8)) {
List<String> line = reader.lines()
.skip(31)
.limit(1)
.collect(Collectors.toList());
line.stream().forEach(System.out::println);
}
Java 8では
小さなファイルの場合:
String line = Files.readAllLines(Paths.get("file.txt")).get(n);
大きなファイルの場合:
String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line = lines.skip(n).findFirst().get();
}
Java 7
String line;
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
for (int i = 0; i < n; i++)
br.readLine();
line = br.readLine();
}
public String readLine(int line){
FileReader tempFileReader = null;
BufferedReader tempBufferedReader = null;
try { tempFileReader = new FileReader(textFile);
tempBufferedReader = new BufferedReader(tempFileReader);
} catch (Exception e) { }
String returnStr = "ERROR";
for(int i = 0; i < line - 1; i++){
try { tempBufferedReader.readLine(); } catch (Exception e) { }
}
try { returnStr = tempBufferedReader.readLine(); } catch (Exception e) { }
return returnStr;
}
それは私のために働きます:私は単純なテキストファイルを読むという答えを組み合わせました
しかし、文字列を返す代わりに、文字列のLinkedListを返しています。次に、必要な行を選択できます。
public static LinkedList<String> readFromAssets(Context context, String filename) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename)));
LinkedList<String>linkedList = new LinkedList<>();
// do reading, usually loop until end of file reading
StringBuilder sb = new StringBuilder();
String mLine = reader.readLine();
while (mLine != null) {
linkedList.add(mLine);
sb.append(mLine); // process line
mLine = reader.readLine();
}
reader.close();
return linkedList;
}
また、BufferedReaderのサブクラスであるLineNumberReaderを確認することもできます。readlineメソッドの他に、行番号にアクセスするためのsetter / getterメソッドもあります。ファイルからデータを読み取る間、読み取られた行数を追跡するのに非常に役立ちます。
skip()関数を使用して、行の先頭からスキップできます。
public static void readFile(String filePath, long lineNum) {
List<String> list = new ArrayList<>();
long totalLines, startLine = 0;
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
totalLines = Files.lines(Paths.get(filePath)).count();
startLine = totalLines - lineNum;
// Stream<String> line32 = lines.skip(((startLine)+1));
list = lines.skip(startLine).collect(Collectors.toList());
// lines.forEach(list::add);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
list.forEach(System.out::println);
}
それらはすべて間違っています。私はこれを約10秒で書きました。これにより、メインメソッドでobject.getQuestion( "linenumber")を呼び出すだけで、必要な行を返すことができました。
public class Questions {
File file = new File("Question2Files/triviagame1.txt");
public Questions() {
}
public String getQuestion(int numLine) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(file));
String line = "";
for(int i = 0; i < numLine; i++) {
line = br.readLine();
}
return line; }}