を使用してファイルを1行ずつ読み取る必要がありますがjava.nio
、一度に1行ずつ読み取るnio
ような方法はありません。readline()
どのような解決策がありますか?
9 に答える
制限が気に入らないことは理解していますが、IOパッケージにアクセスできないか、何らかの理由でインポートが許可されていない場合は、一番上の答えは役に立ちません...
完全にIOフリーにする2つの方法:
java.nio.file.Files.lines
、.utilパッケージの一部であり、bufferedReaderのような.ioパッケージではない行のストリームを返します。java.nio.file.Files.readAllLines
、反復可能な行のコレクションを返します。iterator
またはを使用しfor each
て1行を抽出します。
乾杯
なんで?NIOは行の読み取りをサポートしていません。毎秒数百万行を読むことができますが、それでBufferedReader.readLine().
十分だと思います。
Oracleはチュートリアルで例を紹介します。 https://docs.oracle.com/javase/tutorial/essential/io/file.html#streams
Path file = ...;
try (InputStream in = Files.newInputStream(file);
BufferedReader reader =
new BufferedReader(new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.println(x);
}
あなたを使用しjava.nio.file.Files
て行うことができます:
Path path = FileSystems.getDefault().getPath("/path/to", "file.txt");
Files.lines(path).forEach(line ->
// consume line
);
lines(path)
メソッドがを返すので、Stream
次のように最初の行(存在する場合)だけを読み取るなど、StreamAPIの他のメソッドを利用できます。
Optional<String> firstLine = Files.lines(path).findFirst();
わたしにはできる....
public static void main(String[] args) throws IOException
{
RandomAccessFile aFile = new RandomAccessFile
("F:\\DetailsMy1.txt", "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1);
StringBuffer line = new StringBuffer();
while(inChannel.read(buffer) > 0)
{
buffer.flip();
for (int i = 0; i < buffer.limit(); i++)
{
char ch = ((char) buffer.get());
if(ch=='\r'){
System.out.print(line+"[EOL]");
line=new StringBuffer();
}else{
line.append(ch);
}
}
buffer.clear(); // do something with the data and clear/compact it.
}
inChannel.close();
aFile.close();
}
上記のEJPおよびその他のサポートについては、次の記事を参照してください。http ://www.javaworld.com/article/2078654/java-se/java-se-five-ways-to-maximize-java-nio-and- nio-2.html
特に、「NIOはパフォーマンス上の利点で宣伝されることがよくありますが、応答性が高いと言った方が正確です。場合によっては、NIOのパフォーマンスは基本的なJava I/Oよりも劣ります。たとえば小さなファイルの単純なシーケンシャル読み取りおよび書き込みの場合。 、単純なストリームの実装は、対応するイベント指向のチャネルベースのコーディングよりも2〜3倍高速である可能性があります。また、非多重化チャネル(つまり、別々のスレッドのチャネル)は、セレクターを登録するチャネルよりもはるかに低速になる可能性があります。シングルスレッドで。」
場合によっては、NIOのパフォーマンスが基本的なJava I/Oよりも悪いというステートメントを強調します。著者は、NIOが正しい選択であるかどうかの迅速な分析を推進するために、質問のリストをフォローアップします。あなた(または次に来る人)がまだNIOを追求することを決定した場合は、コード例でその使用法の良い説明があります。
1)linesメソッドを使用してBufferedReaderをStreamに変換できます
List<String> list = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
list = br.lines().collect(Collectors.toList());
}
2)Files.linesメソッドを使用して直接ストリームを取得します。
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream
.filter(s -> s.endswith("/"))
.map(String::toUpperCase)
.forEach(System.out::println);
}
DanielBraunが彼の回答で指摘しているように、linesメソッドの代わりにreadAllLinesメソッドを使用することもできます。違いは、ドキュメントから直接です。
readAllLinesとは異なり、このメソッドはすべての行をリストに読み込むのではなく、ストリームが消費されるときに遅延してデータを入力します。
Javaドキュメントのパッケージの概要ページには、Streamsに関する簡潔でわかりやすい概要が記載されています。また、この記事では、Javaでファイルを1行ずつ読み取る他のいくつかの方法についても説明します。
NIOは通常、ダイレクトメモリアクセスまたはブロックを介したバルクデータ転送のいずれかを行うために使用されます。それは他のことをしますが、他の機能はデータアクセスのブロックと非ブロックともっと関係があります。
そのため、NIOを使用してデータをすばやく(または非ブロッキング方式で)取得することをお勧めします。ただし、「行ごとに読み取る」場合は、NIOが使用可能なデータを読み込んだ後に、行検出を実行する方が適切です。これは、NIOが読み取ったばかりのバッファに「行読み取り」ファサードを配置することで簡単に実装できます。
単に使用してください: https ://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path-
EDIT(人間が読める形式の翻訳、MeetTitanに関して):つまり、use-ファイルの行を表す表現java.nio.file.Files.lines(Path)
を返しStream<String>
ます。これは、JavaAPIによって提供されるメソッドです。詳細を確認するには、Javadocを参照してください。したがって、最も関連性の高い情報は次のとおりですFiles.lines()
。Java1.8以降に存在します。これを使って。