web-dev-qa-db-ja.com

行のノンブロッキング(NIO)読み取り

_Java.nio_を使用してファイルを1行ずつ読み取る必要がありますが、nioにはreadline()のようなメソッドがありません。どのような解決策がありますか?

13
Aashwin Jain

NIOは通常、ダイレクトメモリアクセスまたはブロックを介したバルクデータ転送のいずれかを行うために使用されます。それは他のことをしますが、他の機能はデータアクセスのブロックと非ブロックともっと関係があります。

そのため、NIOを使用してデータをすばやく(または非ブロッキング方式で)取得することをお勧めします。ただし、「行ごとに読み取る」場合は、NIOが使用可能なデータを読み込んだ後に行検出を実行する方が適切です。これは、NIOが読み取ったばかりのバッファに「行読み取り」ファサードを配置することで簡単に実装できます。

0
Edwin Buck

制限が気に入らないことは承知していますが、IOパッケージにアクセスできないか、何らかの理由でインポートが許可されていない場合、一番上の答えは役に立ちません。 。

それを完全に行う2つの方法IO無料:

  1. Java.nio.file.Files.lines、行のストリームを返します。これは.utilパッケージの一部であり、bufferedReaderのような.ioパッケージではありません。

  2. Java.nio.file.Files.readAllLines、反復可能な行のコレクションを返します。 iteratorまたはfor eachを使用して1行を抽出します。

乾杯

12
Daniel Braun

どうして? NIOは行の読み取りをサポートしていません。 BufferedReader.readLine().を使用すると、1秒間に数百万行を読み取ることができます。これで十分です。

5
user207421

オラクルは、チュートリアルで例を紹介しています。 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);
}
3
photom

_Java.nio.file.Files_ を使用すると、次のことができます。

_Path path = FileSystems.getDefault().getPath("/path/to", "file.txt");
Files.lines(path).forEach(line ->
    // consume line
);
_

lines(path)メソッドは Stream を返すため、最初の行だけを読み取るなど、Stream APIの他のメソッドを利用できます(存在する場合)。と:

_Optional<String> firstLine = Files.lines(path).findFirst();
_
3
ericbn

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とは異なり、このメソッドはすべての行をリストに読み込むのではなく、ストリームが消費されるときに遅延してデータを入力します。

package summary page from Java docsは、Streamsに関する簡潔でわかりやすい概要を示しています。また、この article には、 Javaでファイルを1行ずつ読み取る。

1
ChrisOdney

上記の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
heyhey2k

単に使用してください: https://docs.Oracle.com/javase/8/docs/api/Java/nio/file/Files.html#lines-Java.nio.file.Path-

EDIT(人間が読める形式の翻訳、MeetTitanに関して):つまり、Java.nio.file.Files.lines(Path)を使用します-ファイルの行を表す_Stream<String>_を返します。これは、Java APIによって提供されるメソッドです。詳細を確認するには、Javadocを参照してください。したがって、最も関連性の高い情報は次のとおりです。Files.lines()はJava 1.8。使用してください。

0
polemoser

わたしにはできる....

 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();
    }
0
Vinay