Javaでプレーンテキストファイルを読み取る


933

Javaでファイルのデータを読み書きする方法はいくつかあるようです。

ファイルからアスキーデータを読みたい。可能な方法とその違いは何ですか?


24
また、「建設的ではない」と締めくくることにも同意しません。幸いにも、これは重複として閉じられる可能性があります。ファイルの内容から文字列を作成する方法などの良い答えはファイルを文字列に読み込む最も簡単な方法は何ですか?ファイルを読み取るための最も単純なクラスは何ですか?
Jonik 2013

ループなし:{{{Scanner sc = new Scanner(file、 "UTF-8"); sc.useDelimiter( "$ ^"); //何も一致しない正規表現String text = sc.next(); sc.close(); }}}
Aivar 2014

3
ファイル全体を文字列に読み取るには、Pythonに "read()"のようなものはないほど興味深い
kommradHomer

2
これは、これを行う最も簡単な方法です。mkyong.com
java

回答:


567

ASCIIはTEXTファイルなのでReaders、読み取りに使用します。Javaは、を使用したバイナリファイルからの読み取りもサポートしていますInputStreams。読み込まれているファイルが巨大な場合BufferedReaderは、FileReader読み込みパフォーマンスを向上させる必要があります。

の使用方法についてこの記事を読みますReader

またThinking In Javaというこの素晴らしい(まだ無料の)本をダウンロードして読むことをお勧めします。

Java 7の場合

new String(Files.readAllBytes(...))

(ドキュメント) または

Files.readAllLines(...)

(ドキュメント)

Java 8の場合

Files.lines(..).forEach(...)

(ドキュメント)


14
リーダーの選択は、ファイルのコンテンツが何のために必要かによって異なります。ファイルが小さめで必要な場合は、FileReaderを使用してすべて(または少なくとも十分な大きさのチャンク)を読み取る方が高速です(ベンチマーク:1.8〜2倍)。1行ずつ処理している場合は、BufferedReaderを使用してください。
ヴラド

3
「Files.lines(..)。forEach(...)」を使用する場合、行の順序は保持されますか?私の理解では、この操作後の順序は任意です。
Daniil Shevelev

39
Files.lines(…).forEach(…)行の順序は保持されませんが、@ Dashで並列実行されます。順序が重要な場合は、を使用できますFiles.lines(…).forEachOrdered(…)。これにより、順序が保持されます(ただし検証されませんでした)。
Palec、2015

2
@Palecこれは興味深いですがFiles.lines(...).forEach(...)、並列に実行されると書かれているドキュメントから引用できますか?これは、を使用してストリームを明示的に並列にする場合にのみ当てはまると思いましたFiles.lines(...).parallel().forEach(...)
クリトスキリアクー2015

3
私の元の公式は完全ではありません、@ KlitosKyriacou。ポイントは、forEach順序を保証するものではなく、その理由は簡単な並列化です。順序を維持する場合は、を使用しますforEachOrdered
Palec 2015年

687

小さなファイルを読み取る私のお気に入りの方法は、BufferedReaderとStringBuilderを使用することです。それは非常に単純で要点があります(特に効果的ではありませんが、ほとんどの場合は十分です)。

BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        sb.append(line);
        sb.append(System.lineSeparator());
        line = br.readLine();
    }
    String everything = sb.toString();
} finally {
    br.close();
}

Java 7以降、try-with-resources(自動クローズ)機能を使用する必要があると指摘する人もいます。

try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        sb.append(line);
        sb.append(System.lineSeparator());
        line = br.readLine();
    }
    String everything = sb.toString();
}

このような文字列を読み取る場合、通常はとにかく1行ごとに文字列を処理したいので、この実装に進みます。

実際にファイルを文字列に読み込むだけの場合は、常にApacheを使用します。 クラスIOUtils.toString()メソッドで Commons IOを。ここでソースを見ることができます:

http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html

FileInputStream inputStream = new FileInputStream("foo.txt");
try {
    String everything = IOUtils.toString(inputStream);
} finally {
    inputStream.close();
}

そして、Java 7でさらにシンプルに:

try(FileInputStream inputStream = new FileInputStream("foo.txt")) {     
    String everything = IOUtils.toString(inputStream);
    // do something with everything string
}

6
最後の行に達した場合、改行(\ n)の追加を停止するように少し調整しました。code while(line!= null){sb.append(line); line = br.readLine(); // curlineが最後の行でない場合にのみ新しい行を追加します。if(line!= null){sb.append( "\ n"); }}code
Ramon Fincken 2013

2
Apache Common IOと同様に、IOUtils#toString()はsun.misc.IOUtils#readFully()であり、Sun / Oracle JREに含まれています。
gb96 2013

3
チャーが速い列よりのStringBuilderに付加されるsb.append(「\ N」)に優先して性能常にコールsb.append(「\ n」)のための
GB96

2
FileReaderはFileNotFoundExceptionをスローし、BufferedReadはIOExceptionをスローする可能性があるため、キャッチする必要があります。
カマチ2014年

4
リーダーを直接使用する必要はなく、ioutilsも必要ありません。java7には、ファイル全体またはすべての行を読み取るための組み込みメソッドがあります。docs.oracle.com / javase / 7 / docs / api / java / nio / file / およびdocs.oracle.com/javase/7/docs/apiを
nio

142

最も簡単な方法はScanner、Java のクラスとFileReaderオブジェクトを使用することです。簡単な例:

Scanner in = new Scanner(new FileReader("filename.txt"));

Scanner 文字列や数値などを読み取るためのメソッドがいくつかあります。これについての詳細は、Javaのドキュメントページを参照してください。

たとえば、コンテンツ全体をに読み込みStringます。

StringBuilder sb = new StringBuilder();
while(in.hasNext()) {
    sb.append(in.next());
}
in.close();
outString = sb.toString();

また、特定のエンコーディングが必要な場合は、次の代わりにこれを使用できますFileReader

new InputStreamReader(new FileInputStream(fileUtf8), StandardCharsets.UTF_8)

28
while(in.hasNext()){System.out.println(in.next()); }
Gene Bo

16
@Hissainしかし、より使いやすいBufferedReader
イエス・ラモス

3
それをトライキャッチで囲む必要があります
Rahal Kanishka

@JesusRamosそうじゃない、なぜそう思うの?これより何が簡単while ((line = br.readLine()) != null) { sb.append(line); }ですか?
ローン侯爵


57

外部ライブラリを使用せずにそれを行う別の方法を次に示します。

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public String readFile(String filename)
{
    String content = null;
    File file = new File(filename); // For example, foo.txt
    FileReader reader = null;
    try {
        reader = new FileReader(file);
        char[] chars = new char[(int) file.length()];
        reader.read(chars);
        content = new String(chars);
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(reader != null){
            reader.close();
        }
    }
    return content;
}

10
または使用「トライ・リソースを持つ」トライ(FileReaderのリーダー=新規FileReader(ファイル))
エルナンEche

3
私はfile.length()に気づきました、これはutf-16ファイルでどのようにうまく機能しますか?
ウェイン

5
この手法は、read()がバッファーを埋めることを前提としています。文字数がバイト数と等しいこと。バイト数がメモリに収まること。バイト数が整数に収まること。-1
ローン侯爵2014

1
@HermesTrismegistus私はそれが間違っている4つの理由を提供しました。StefanReichは私に同意するのに完全に正しいです。
ローンズオブローン

34

さまざまな方法でベンチマークを行う必要がありました。私の調査結果についてコメントしますが、要するに、最も速い方法は、FileInputStreamよりも単純な古いBufferedInputStreamを使用することです。多くのファイルを読み取る必要がある場合は、3つのスレッドで合計実行時間を約半分に減らしますが、スレッドを追加すると、パフォーマンスが低下し、スレッドが1つだけの場合よりも20スレッドで完了する場合の方が3倍長くなります。

前提として、ファイルを読み取り、その内容に対して意味のあることを行う必要があります。この例では、ログから行を読み取り、特定のしきい値を超える値を含む行を数えています。だから私はワンライナーのJava 8Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";"))はオプションではないとます。

Java 1.8、Windows 7、およびSSDドライブとHDDドライブの両方でテストしました。

6つの異なる実装を作成しました。

rawParse:FileInputStreamではなくBufferedInputStreamを使用し、バイト単位で行を読み取ります。これは他のシングルスレッドアプローチよりも優れていますが、非ASCIIファイルの場合は非常に不便です。

lineReaderParse:FileReaderでBufferedReaderを使用し、行ごとに読み取り、String.split()を呼び出して行を分割します。これはrawParseよりも約20%遅くなります。

lineReaderParseParallel:これはlineReaderParseと同じですが、いくつかのスレッドを使用します。これは、すべてのケースで全体的に最速のオプションです。

nioFilesParse:java.nio.files.Files.lines()を使用します

nioAsyncParse:完了ハンドラーとスレッドプールでAsynchronousFileChannelを使用します。

nioMemoryMappedParse:メモリマップファイルを使用します。これは、他のどの実装よりも実行時間を少なくとも3倍長くするのは本当に悪い考えです。

これらは、クアッドコアi7およびSSDドライブでそれぞれ4 MBの204個のファイルを読み取るための平均時間です。ファイルは、ディスクキャッシュを回避するためにオンザフライで生成されます。

rawParse                11.10 sec
lineReaderParse         13.86 sec
lineReaderParseParallel  6.00 sec
nioFilesParse           13.52 sec
nioAsyncParse           16.06 sec
nioMemoryMappedParse    37.68 sec

SSDで実行した場合とSSDを約15%高速化した場合のHDDドライブで実行した場合の違いは、予想よりも小さいことがわかりました。これは、ファイルが断片化されていないHDDで生成され、それらが順次読み取られるため、回転するドライブがSSDとほぼ同じように動作するためです。

nioAsyncParse実装のパフォーマンスが低いことに驚きました。間違った方法で何かを実装したか、NIOを使用したマルチスレッド実装と、完了ハンドラーがjava.io APIを使用したシングルスレッド実装と同じ(またはさらに悪い)を実行しました。さらに、CompletionHandlerを使用した非同期解析は、コードの行数がはるかに長く、古いストリームでの単純な実装よりも正しく実装するのが難しいです。

6つの実装に続いて、それらすべてを含むクラスに加えて、ファイル数、ファイルサイズ、同時実行の度合いを試すことができるパラメーター化可能なmain()メソッドを実装します。ファイルのサイズは変動してプラスマイナス20%であることに注意してください。これは、すべてのファイルがまったく同じサイズであることによる影響を回避するためです。

rawParse

public void rawParse(final String targetDir, final int numberOfFiles) throws IOException, ParseException {
    overrunCount = 0;
    final int dl = (int) ';';
    StringBuffer lineBuffer = new StringBuffer(1024);
    for (int f=0; f<numberOfFiles; f++) {
        File fl = new File(targetDir+filenamePreffix+String.valueOf(f)+".txt");
        FileInputStream fin = new FileInputStream(fl);
        BufferedInputStream bin = new BufferedInputStream(fin);
        int character;
        while((character=bin.read())!=-1) {
            if (character==dl) {

                // Here is where something is done with each line
                doSomethingWithRawLine(lineBuffer.toString());
                lineBuffer.setLength(0);
            }
            else {
                lineBuffer.append((char) character);
            }
        }
        bin.close();
        fin.close();
    }
}

public final void doSomethingWithRawLine(String line) throws ParseException {
    // What to do for each line
    int fieldNumber = 0;
    final int len = line.length();
    StringBuffer fieldBuffer = new StringBuffer(256);
    for (int charPos=0; charPos<len; charPos++) {
        char c = line.charAt(charPos);
        if (c==DL0) {
            String fieldValue = fieldBuffer.toString();
            if (fieldValue.length()>0) {
                switch (fieldNumber) {
                    case 0:
                        Date dt = fmt.parse(fieldValue);
                        fieldNumber++;
                        break;
                    case 1:
                        double d = Double.parseDouble(fieldValue);
                        fieldNumber++;
                        break;
                    case 2:
                        int t = Integer.parseInt(fieldValue);
                        fieldNumber++;
                        break;
                    case 3:
                        if (fieldValue.equals("overrun"))
                            overrunCount++;
                        break;
                }
            }
            fieldBuffer.setLength(0);
        }
        else {
            fieldBuffer.append(c);
        }
    }
}

lineReaderParse

public void lineReaderParse(final String targetDir, final int numberOfFiles) throws IOException, ParseException {
    String line;
    for (int f=0; f<numberOfFiles; f++) {
        File fl = new File(targetDir+filenamePreffix+String.valueOf(f)+".txt");
        FileReader frd = new FileReader(fl);
        BufferedReader brd = new BufferedReader(frd);

        while ((line=brd.readLine())!=null)
            doSomethingWithLine(line);
        brd.close();
        frd.close();
    }
}

public final void doSomethingWithLine(String line) throws ParseException {
    // Example of what to do for each line
    String[] fields = line.split(";");
    Date dt = fmt.parse(fields[0]);
    double d = Double.parseDouble(fields[1]);
    int t = Integer.parseInt(fields[2]);
    if (fields[3].equals("overrun"))
        overrunCount++;
}

lineReaderParseParallel

public void lineReaderParseParallel(final String targetDir, final int numberOfFiles, final int degreeOfParalelism) throws IOException, ParseException, InterruptedException {
    Thread[] pool = new Thread[degreeOfParalelism];
    int batchSize = numberOfFiles / degreeOfParalelism;
    for (int b=0; b<degreeOfParalelism; b++) {
        pool[b] = new LineReaderParseThread(targetDir, b*batchSize, b*batchSize+b*batchSize);
        pool[b].start();
    }
    for (int b=0; b<degreeOfParalelism; b++)
        pool[b].join();
}

class LineReaderParseThread extends Thread {

    private String targetDir;
    private int fileFrom;
    private int fileTo;
    private DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private int overrunCounter = 0;

    public LineReaderParseThread(String targetDir, int fileFrom, int fileTo) {
        this.targetDir = targetDir;
        this.fileFrom = fileFrom;
        this.fileTo = fileTo;
    }

    private void doSomethingWithTheLine(String line) throws ParseException {
        String[] fields = line.split(DL);
        Date dt = fmt.parse(fields[0]);
        double d = Double.parseDouble(fields[1]);
        int t = Integer.parseInt(fields[2]);
        if (fields[3].equals("overrun"))
            overrunCounter++;
    }

    @Override
    public void run() {
        String line;
        for (int f=fileFrom; f<fileTo; f++) {
            File fl = new File(targetDir+filenamePreffix+String.valueOf(f)+".txt");
            try {
            FileReader frd = new FileReader(fl);
            BufferedReader brd = new BufferedReader(frd);
            while ((line=brd.readLine())!=null) {
                doSomethingWithTheLine(line);
            }
            brd.close();
            frd.close();
            } catch (IOException | ParseException ioe) { }
        }
    }
}

nioFilesParse

public void nioFilesParse(final String targetDir, final int numberOfFiles) throws IOException, ParseException {
    for (int f=0; f<numberOfFiles; f++) {
        Path ph = Paths.get(targetDir+filenamePreffix+String.valueOf(f)+".txt");
        Consumer<String> action = new LineConsumer();
        Stream<String> lines = Files.lines(ph);
        lines.forEach(action);
        lines.close();
    }
}


class LineConsumer implements Consumer<String> {

    @Override
    public void accept(String line) {

        // What to do for each line
        String[] fields = line.split(DL);
        if (fields.length>1) {
            try {
                Date dt = fmt.parse(fields[0]);
            }
            catch (ParseException e) {
            }
            double d = Double.parseDouble(fields[1]);
            int t = Integer.parseInt(fields[2]);
            if (fields[3].equals("overrun"))
                overrunCount++;
        }
    }
}

nioAsyncParse

public void nioAsyncParse(final String targetDir, final int numberOfFiles, final int numberOfThreads, final int bufferSize) throws IOException, ParseException, InterruptedException {
    ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(numberOfThreads);
    ConcurrentLinkedQueue<ByteBuffer> byteBuffers = new ConcurrentLinkedQueue<ByteBuffer>();

    for (int b=0; b<numberOfThreads; b++)
        byteBuffers.add(ByteBuffer.allocate(bufferSize));

    for (int f=0; f<numberOfFiles; f++) {
        consumerThreads.acquire();
        String fileName = targetDir+filenamePreffix+String.valueOf(f)+".txt";
        AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get(fileName), EnumSet.of(StandardOpenOption.READ), pool);
        BufferConsumer consumer = new BufferConsumer(byteBuffers, fileName, bufferSize);
        channel.read(consumer.buffer(), 0l, channel, consumer);
    }
    consumerThreads.acquire(numberOfThreads);
}


class BufferConsumer implements CompletionHandler<Integer, AsynchronousFileChannel> {

        private ConcurrentLinkedQueue<ByteBuffer> buffers;
        private ByteBuffer bytes;
        private String file;
        private StringBuffer chars;
        private int limit;
        private long position;
        private DateFormat frmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        public BufferConsumer(ConcurrentLinkedQueue<ByteBuffer> byteBuffers, String fileName, int bufferSize) {
            buffers = byteBuffers;
            bytes = buffers.poll();
            if (bytes==null)
                bytes = ByteBuffer.allocate(bufferSize);

            file = fileName;
            chars = new StringBuffer(bufferSize);
            frmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            limit = bufferSize;
            position = 0l;
        }

        public ByteBuffer buffer() {
            return bytes;
        }

        @Override
        public synchronized void completed(Integer result, AsynchronousFileChannel channel) {

            if (result!=-1) {
                bytes.flip();
                final int len = bytes.limit();
                int i = 0;
                try {
                    for (i = 0; i < len; i++) {
                        byte by = bytes.get();
                        if (by=='\n') {
                            // ***
                            // The code used to process the line goes here
                            chars.setLength(0);
                        }
                        else {
                                chars.append((char) by);
                        }
                    }
                }
                catch (Exception x) {
                    System.out.println(
                        "Caught exception " + x.getClass().getName() + " " + x.getMessage() +
                        " i=" + String.valueOf(i) + ", limit=" + String.valueOf(len) +
                        ", position="+String.valueOf(position));
                }

                if (len==limit) {
                    bytes.clear();
                    position += len;
                    channel.read(bytes, position, channel, this);
                }
                else {
                    try {
                        channel.close();
                    }
                    catch (IOException e) {
                    }
                    consumerThreads.release();
                    bytes.clear();
                    buffers.add(bytes);
                }
            }
            else {
                try {
                    channel.close();
                }
                catch (IOException e) {
                }
                consumerThreads.release();
                bytes.clear();
                buffers.add(bytes);
            }
        }

        @Override
        public void failed(Throwable e, AsynchronousFileChannel channel) {
        }
};

すべてのケースの完全に実行可能な実装

https://github.com/sergiomt/javaiobenchmark/blob/master/FileReadBenchmark.java


24

以下は、3つの機能しテスト済みの方法です。

使用する BufferedReader

package io;
import java.io.*;
public class ReadFromFile2 {
    public static void main(String[] args)throws Exception {
        File file = new File("C:\\Users\\pankaj\\Desktop\\test.java");
        BufferedReader br = new BufferedReader(new FileReader(file));
        String st;
        while((st=br.readLine()) != null){
            System.out.println(st);
        }
    }
}

使用する Scanner

package io;

import java.io.File;
import java.util.Scanner;

public class ReadFromFileUsingScanner {
    public static void main(String[] args) throws Exception {
        File file = new File("C:\\Users\\pankaj\\Desktop\\test.java");
        Scanner sc = new Scanner(file);
        while(sc.hasNextLine()){
            System.out.println(sc.nextLine());
        }
    }
}

使用する FileReader

package io;
import java.io.*;
public class ReadingFromFile {

    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("C:\\Users\\pankaj\\Desktop\\test.java");
        int i;
        while ((i=fr.read()) != -1){
            System.out.print((char) i);
        }
    }
}

Scannerクラスを使用してループなしでファイル全体を読み取る

package io;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadingEntireFileWithoutLoop {

    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("C:\\Users\\pankaj\\Desktop\\test.java");
        Scanner sc = new Scanner(file);
        sc.useDelimiter("\\Z");
        System.out.println(sc.next());
    }
}

1
フォルダがプロジェクト内に存在する場合にパスを指定するにはどうすればよいですか?
カビプリヤ2017年

2
どうjava.nio.file.Filesですか?私たちは今、ちょうど使用することができreadAllLinesreadAllByteslines
クロードマーティン

21

内のメソッドorg.apache.commons.io.FileUtilsも非常に便利かもしれません、例えば:

/**
 * Reads the contents of a file line by line to a List
 * of Strings using the default encoding for the VM.
 */
static List readLines(File file)

あるいは、Guava(よりモダンでアクティブに保守されているライブラリ)を好む場合は、Filesクラスに同様のユーティリティがありますこの回答の簡単な例
Jonik 2013

1
または、あなたは、単にすべての行を取得するための方法で構築された使用:docs.oracle.com/javase/7/docs/api/java/nio/file/...
kritzikratzi

Apache Commons上のリンクは死んでいるようです。
2017年

17

テキストをどのように処理しますか?ファイルはメモリに収まるほど小さいですか?私はあなたのニーズに合わせてファイルを処理する最も簡単な方法を見つけようとします。FileUtilsライブラリはこのための非常にハンドルです。

for(String line: FileUtils.readLines("my-text-file"))
    System.out.println(line);

2
:それはまた、java7に組み込まれているdocs.oracle.com/javase/7/docs/api/java/nio/file/...
kritzikratzi

@PeterLawreyはおそらく意味しorg.apache.commons.io.FileUtilsます。Googleリンクは、最も広く使われている意味が変わるため、時間の経過とともにコンテンツを変更する可能性がありますが、これは彼のクエリに一致し、正しく見えます。
Palec、2015

2
残念ながら、現在は存在せずreadLines(String)readLines(File)廃止予定ですreadLines(File, Charset)。エンコーディングは文字列としても提供できます。
Palec、2015


12

Javaファイルを読み取る15の方法を文書化し、さまざまなファイルサイズ(1 KBから1 GB)で速度をテストしました。これを行う3つの方法を次に示します。

  1. java.nio.file.Files.readAllBytes()

    Java 7、8、および9で動作することがテストされています。

    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    
    public class ReadFile_Files_ReadAllBytes {
      public static void main(String [] pArgs) throws IOException {
        String fileName = "c:\\temp\\sample-10KB.txt";
        File file = new File(fileName);
    
        byte [] fileBytes = Files.readAllBytes(file.toPath());
        char singleChar;
        for(byte b : fileBytes) {
          singleChar = (char) b;
          System.out.print(singleChar);
        }
      }
    }
  2. java.io.BufferedReader.readLine()

    Java 7、8、9で動作することがテストされています。

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    
    public class ReadFile_BufferedReader_ReadLine {
      public static void main(String [] args) throws IOException {
        String fileName = "c:\\temp\\sample-10KB.txt";
        FileReader fileReader = new FileReader(fileName);
    
        try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
          String line;
          while((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
          }
        }
      }
    }
  3. java.nio.file.Files.lines()

    これは、Java 8および9で動作するようにテストされていますが、ラムダ式の要件のため、Java 7では動作しません。

    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.util.stream.Stream;
    
    public class ReadFile_Files_Lines {
      public static void main(String[] pArgs) throws IOException {
        String fileName = "c:\\temp\\sample-10KB.txt";
        File file = new File(fileName);
    
        try (Stream linesStream = Files.lines(file.toPath())) {
          linesStream.forEach(line -> {
            System.out.println(line);
          });
        }
      }
    }

9

以下は、Java 8の方法でそれを行うためのワンライナーです。text.txtファイルがEclipseのプロジェクトディレクトリのルートにあると仮定します。

Files.lines(Paths.get("text.txt")).collect(Collectors.toList());

7

BufferedReaderの使用:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

BufferedReader br;
try {
    br = new BufferedReader(new FileReader("/fileToRead.txt"));
    try {
        String x;
        while ( (x = br.readLine()) != null ) {
            // Printing out each line in the file
            System.out.println(x);
        }
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}
catch (FileNotFoundException e) {
    System.out.println(e);
    e.printStackTrace();
}

7

これは基本的に、Jesus Ramosの回答とまったく同じですが、FileReaderの代わりにFileを使用し、ファイルのコンテンツをステップ実行するための反復を使用します。

Scanner in = new Scanner(new File("filename.txt"));

while (in.hasNext()) { // Iterates each line in the file
    String line = in.nextLine();
    // Do something with line
}

in.close(); // Don't forget to close resource leaks

...投げる FileNotFoundException


3
File vs FileReader:FileReaderでは、ファイルが存在し、オペレーティングシステムの権限でアクセスが許可されている必要があります。ファイルを使用すると、これらの権限をテストしたり、ファイルがディレクトリかどうかを確認したりできます。ファイルには便利な関数があります:isFile()、isDirectory()、listFiles()、canExecute()、canRead()、canWrite()、exists()、mkdir()、delete()。File.createTempFile()は、システムのデフォルトの一時ディレクトリに書き込みます。この方法は、オープンのFileOutputStreamオブジェクトに使用することができますファイルオブジェクトを返す、などでしょうソース
ThisClark

7

バッファーストリームクラスは実際にははるかにパフォーマンスが高いため、NIO.2 APIには、これらのストリームクラスを具体的に返すメソッドが含まれているため、アプリケーションで常にバッファーストリームを使用することを推奨しています。

次に例を示します。

Path path = Paths.get("/myfolder/myfile.ext");
try (BufferedReader reader = Files.newBufferedReader(path)) {
    // Read from the stream
    String currentLine = null;
    while ((currentLine = reader.readLine()) != null)
        //do your code here
} catch (IOException e) {
    // Handle file I/O exception...
}

このコードを置き換えることができます

BufferedReader reader = Files.newBufferedReader(path);

BufferedReader br = new BufferedReader(new FileReader("/myfolder/myfile.ext"));

私はお勧めします。この JavaのNIOとIOの主な用途を学ぶために記事を。


6

おそらくバッファI / Oほど高速ではありませんが、かなり簡潔です:

    String content;
    try (Scanner scanner = new Scanner(textFile).useDelimiter("\\Z")) {
        content = scanner.next();
    }

\Zパターンは伝えScanner区切り文字がEOFであること。


1
非常に関連している既存の答えは、Jesus Ramosによるものです。
Palec、2015年

1
確かに、次のようになります。 if(scanner.hasNext()) content = scanner.next();
デビッドSoroko

1
これはAndroid 4.4では失敗します。1024バイトのみが読み取られます。YMMV。
Roger Keays、2016年

3

今のところ、他の回答ではまだ言及されていません。しかし、「最高」が速度を意味する場合、新しいJava I / O(NIO)が最も高速なパフォーマンスを提供する可能性がありますが、学習している人にとって常に理解しやすいとは限りません。

http://download.oracle.com/javase/tutorial/essential/io/file.html


あなたはそれがどのように行われ、フォローするリンクを与えないように述べるべきでした
Orar

3

Javaでファイルからデータを読み取る最も簡単な方法は、Fileクラスを使用してファイルを読み取り、Scannerクラスを使用してファイルのコンテンツを読み取ることです。

public static void main(String args[])throws Exception
{
   File f = new File("input.txt");
   takeInputIn2DArray(f);
}

public static void takeInputIn2DArray(File f) throws Exception
{
    Scanner s = new Scanner(f);
    int a[][] = new int[20][20];
    for(int i=0; i<20; i++)
    {
        for(int j=0; j<20; j++)
        {
            a[i][j] = s.nextInt();
        }
    }
}

PS:java.util。*をインポートすることを忘れないでください。スキャナーが動作するようにします。


2

グアバはこれのためのワンライナーを提供します:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

String contents = Files.toString(filePath, Charsets.UTF_8);

2

これは質問に対する正確な答えではない可能性があります。これは、Javaコードでファイルへのパスを明示的に指定せずに、コマンドライン引数として読み取る、ファイルを読み取るもう1つの方法です。

次のコードで、

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class InputReader{

    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s="";
        while((s=br.readLine())!=null){
            System.out.println(s);
        }
    }
}

先に進んでそれを実行してください:

java InputReader < input.txt

これはの内容を読み取り、input.txtコンソールに出力します。

System.out.println()次のように、コマンドラインから特定のファイルに書き込むようにすることもできます。

java InputReader < input.txt > output.txt

これはinput.txt、に読み書きしoutput.txtます。


2

readAllLinesとjoinメソッドを使用して、ファイルの内容全体を1行で取得できます。

String str = String.join("\n",Files.readAllLines(Paths.get("e:\\text.txt")));

デフォルトではUTF-8エンコーディングを使用し、ASCIIデータを正しく読み取ります。

また、readAllBytesを使用できます。

String str = new String(Files.readAllBytes(Paths.get("e:\\text.txt")), StandardCharsets.UTF_8);

readAllBytesの方が高速で正確であると思います。これは、新しい行がに置き換えられず、新しい行が置き換え\nられる可能性があるため\r\nです。どちらが適しているかは、ニーズによって異なります。


1

JSFベースのMaven Webアプリケーションの場合、ClassLoaderとResourcesフォルダーを使用して、必要なファイルを読み取ります。

  1. 読み取りたいファイルをすべてResourcesフォルダーに入れます。
  2. Apache Commons IO依存関係をPOMに追加します。

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
  3. 以下のコードを使用してそれを読み取ります(たとえば、以下は.jsonファイルを読み取っています)。

    String metadata = null;
    FileInputStream inputStream;
    try {
    
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        inputStream = (FileInputStream) loader
                .getResourceAsStream("/metadata.json");
        metadata = IOUtils.toString(inputStream);
        inputStream.close();
    }
    catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return metadata;

テキストファイル、.propertiesファイル、XSDスキーマなどについても同じことができます。


これは、「任意のファイル」では使用できません。JARまたはWARファイルにパッケージ化されたリソースにのみ使用できます。
ローンの侯爵

1

Cactoosは宣言型のワンライナーを提供します:

new TextOf(new File("a.txt")).asString();

0

これが構造の単純さに関するものである場合は、Java kissを使用します

import static kiss.API.*;

class App {
  void run() {
    String line;
    try (Close in = inOpen("file.dat")) {
      while ((line = readLine()) != null) {
        println(line);
      }
    }
  }
}

0
import java.util.stream.Stream;
import java.nio.file.*;
import java.io.*;

class ReadFile {

 public static void main(String[] args) {

    String filename = "Test.txt";

    try(Stream<String> stream = Files.lines(Paths.get(filename))) {

          stream.forEach(System.out:: println);

    } catch (IOException e) {

        e.printStackTrace();
    }

 }

 }

Java 8 Streamを使用するだけです。


0
try {
  File f = new File("filename.txt");
  Scanner r = new Scanner(f);  
  while (r.hasNextLine()) {
    String data = r.nextLine();
    JOptionPane.showMessageDialog(data);
  }
  r.close();
} catch (FileNotFoundException ex) {
  JOptionPane.showMessageDialog("Error occurred");
  ex.printStackTrace();
}

0

最も直感的な方法はJava 11で導入されました Files.readString

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String args[]) throws IOException {
        String content = Files.readString(Paths.get("D:\\sandbox\\mvn\\my-app\\my-app.iml"));
        System.out.print(content);
    }
}

PHPには何十年も前からこの贅沢があります!☺


-3

私がプログラムしたこのコードは、非常に大きなファイルに対してはるかに高速です。

public String readDoc(File f) {
    String text = "";
    int read, N = 1024 * 1024;
    char[] buffer = new char[N];

    try {
        FileReader fr = new FileReader(f);
        BufferedReader br = new BufferedReader(fr);

        while(true) {
            read = br.read(buffer, 0, N);
            text += new String(buffer, 0, read);

            if(read < N) {
                break;
            }
        }
    } catch(Exception ex) {
        ex.printStackTrace();
    }

    return text;
}

10
StringBuilderの代わりに単純な文字列連結を使用すると、はるかに速くなると思います...
PhiLho

6
主な速度向上は、1MB(1024 * 1024)ブロックでの読み取りによるものだと思います。ただし、1024 * 1024を2番目の引数としてBufferedReaderコンストラクターに渡すだけで同じことができます。
gb96 2013

3
これはまったくテストされていないと思います。+=この方法で使用すると、線形複雑であるはずのタスクの2次(!)複雑さが得られます。これにより、数MBを超えるファイルのクロールが開始されます。これを回避するには、テキストブロックをlist <string>に保持するか、前述の文字列ビルダーを使用する必要があります。
kritzikratzi 14年

5
何よりもずっと速い?それは間違いなく、StringBufferに追加するよりも速くありません。-1
ローン侯爵2014

1
@ gb96私はバッファサイズについて同じことを考えましたが、この質問の詳細な実験では、同様のコンテキストで驚くべき結果が得られました。16KBバッファは一貫して著しく高速でした。
chiastic-security 2014

-3
String fileName = 'yourFileFullNameWithPath';
File file = new File(fileName); // Creates a new file object for your file
FileReader fr = new FileReader(file);// Creates a Reader that you can use to read the contents of a file read your file
BufferedReader br = new BufferedReader(fr); //Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

上記の一連の行は、次のように1つの行に書き込むことができます。

BufferedReader br = new BufferedReader(new FileReader("file.txt")); // Optional

文字列ビルダーに追加する(ファイルが大きい場合は、文字列ビルダーを使用するか、通常の文字列オブジェクトを使用することをお勧めします)

try {
        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
        sb.append(line);
        sb.append(System.lineSeparator());
        line = br.readLine();
        }
        String everything = sb.toString();
        } finally {
        br.close();
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.