在Java中读取纯文本文件

时间:2021-05-18 21:21:11

It seems there are different ways to read and write data of files in Java.

在Java中读写文件数据似乎有不同的方法。

I want to read ASCII data from a file. What are the possible ways and their differences?

我想从文件中读取ASCII数据。有哪些可能的方法和它们的不同之处?

23 个解决方案

#1


458  

ASCII is a TEXT file so you would use Readers for reading. Java also supports reading from a binary file using InputStreams. If the files being read are huge then you would want to use a BufferedReader on top of a FileReader to improve read performance.

ASCII是一个文本文件,因此您可以使用阅读器来阅读。Java还支持使用inputstream读取二进制文件。如果正在读取的文件很大,那么您应该在文件阅读器的顶部使用BufferedReader来提高读取性能。

Go through this article on how to use a Reader

请阅读这篇关于如何使用读者的文章

I'd also recommend you download and read this wonderful (yet free) book called Thinking In Java

我还建议您下载并阅读这本名为《用Java思考》(Thinking In Java)的优秀(但免费)的书。

In Java 7:

在Java 7:

new String(Files.readAllBytes(...)) or Files.readAllLines(...)

新的字符串(Files.readAllBytes(…))或Files.readAllLines(…)

In Java 8:

在Java 8:

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

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

#2


629  

My favorite way to read a small file is to use a BufferedReader and a StringBuilder. It is very simple and to the point (though not particularly effective, but good enough for most cases):

我最喜欢的读取小文件的方式是使用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();
}

Some has pointed out that after Java 7 you should use try-with-resources (i.e. auto close) features:

有人指出,在Java 7之后,您应该使用带有资源(即自动关闭)的try- 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();
}

When I read strings like this, I usually want to do some string handling per line anyways, so then I go for this implementation.

当我像这样读取字符串时,我通常希望对每行进行一些字符串处理,因此我使用这个实现。

Though if I want to actually just read a file into a String, I always use Apache Commons IO with the class IOUtils.toString() method. You can have a look at the source here:

尽管如果我只是想把文件读入一个字符串,我总是使用Apache Commons IO和class ioutil . tostring()方法。你可以在这里看一下来源:

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

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

And even simpler with Java 7:

更简单的Java 7:

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

#3


123  

The easiest way is to use the Scanner class in Java and the FileReader object. Simple example:

最简单的方法是在Java和FileReader对象中使用扫描器类。简单的例子:

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

Scanner has several methods for reading in strings, numbers, etc... You can look for more information on this on the Java documentation page.

扫描器有几种方法来读取字符串、数字等。您可以在Java文档页面上查找有关此的更多信息。

For example reading the whole content into a String:

例如,将整个内容读入一个字符串:

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

Also if you need a specific encoding you can use this instead of FileReader:

如果你需要一个特定的编码,你可以用它来代替FileReader:

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

#4


57  

Here is a simple solution:

这里有一个简单的解决方案:

String content;

content = new String(Files.readAllBytes(Paths.get("sample.txt")));

#5


53  

Here's another way to do it without using external libraries:

这里有另一种不用外部库的方法:

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;
}

#6


21  

The methods within org.apache.commons.io.FileUtils may also be very handy, e.g.:

org.apache.common . 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)

#7


21  

I had to benchmark the different ways. I shall comment on my findings but, in short, the fastest way is to use a plain old BufferedInputStream over a FileInputStream. If many files must be read then three threads will reduce the total execution time to roughly half, but adding more threads will progressively degrade performance until making it take three times longer to complete with twenty threads than with just one thread.

我必须衡量不同的方法。我将对我的发现进行评论,但是,简而言之,最快的方法是在FileInputStream上使用一个普通的旧BufferedInputStream。如果必须读取许多文件,那么三个线程将把总执行时间减少到大约一半,但是添加更多的线程将逐渐降低性能,直到使20个线程完成的时间比只用一个线程完成的时间长三倍。

The assumption is that you must read a file and do something meaningful with its contents. In the examples here is reading lines from a log and count the ones which contain values that exceed a certain threshold. So I am assuming that the one-liner Java 8 Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";")) is not an option.

假设您必须读取一个文件并对其内容做一些有意义的事情。在这里的示例中,从日志中读取行并计算包含超过某个阈值的值的行数。所以我假设一行的Java 8文件。lines(path. get(“/path/to/file.txt”)。map(line -> line.split(";"))不是选项。

I tested on Java 1.8, Windows 7 and both SSD and HDD drives.

我在Java 1.8、Windows 7以及SSD和HDD驱动器上进行了测试。

I wrote six different implementations:

我写了六种不同的实现:

rawParse: Use BufferedInputStream over a FileInputStream and then cut lines reading byte by byte. This outperformed any other single-thread approach, but it may be very inconvenient for non-ASCII files.

rawParse:在FileInputStream上使用buffer埃迪森putstream,然后逐字节地删除行。这种方法优于任何其他的单线程方法,但是对于非ascii文件来说可能非常不方便。

lineReaderParse: Use a BufferedReader over a FileReader, read line by line, split lines by calling String.split(). This is approximatedly 20% slower that rawParse.

lineReaderParse:在文件阅读器上使用BufferedReader,逐行读取,通过调用String.split()分割行。这比rawParse快了大约20%。

lineReaderParseParallel: This is the same as lineReaderParse, but it uses several threads. This is the fastest option overall in all cases.

linereaderparseparation:这与lineReaderParse相同,但是它使用了几个线程。这是所有情况下最快的选择。

nioFilesParse: Use java.nio.files.Files.lines()

nioFilesParse:使用java.nio.files.Files.lines()

nioAsyncParse: Use an AsynchronousFileChannel with a completion handler and a thread pool.

nioAsyncParse:使用带有完成处理程序和线程池的AsynchronousFileChannel。

nioMemoryMappedParse: Use a memory-mapped file. This is really a bad idea yielding execution times at least three times longer than any other implementation.

nioMemoryMappedParse:使用内存映射文件。这确实是一个糟糕的想法,它会使执行时间比任何其他实现都长至少三倍。

These are the average times for reading 204 files of 4 MB each on an quad-core i7 and SSD drive. The files are generated on the fly to avoid disk caching.

这是在四核i7和SSD驱动器上读取204个4 MB文件的平均时间。为了避免磁盘缓存,文件会自动生成。

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

I found a difference smaller than I expected between running on an SSD or an HDD drive being the SSD approximately 15% faster. This may be because the files are generated on an unfragmented HDD and they are read sequentially, therefore the spinning drive can perform nearly as an SSD.

我发现在SSD上运行和在硬盘驱动器上运行的差别比我预期的要小,大约快15%。这可能是因为这些文件是在未分段的HDD上生成的,并且它们是按顺序读取的,因此旋转驱动器几乎可以作为SSD执行。

I was surprised by the low performance of the nioAsyncParse implementation. Either I have implemented something in the wrong way or the multi-thread implementation using NIO and a completion handler performs the same (or even worse) than a single-thread implementation with the java.io API. Moreover the asynchronous parse with a CompletionHandler is much longer in lines of code and tricky to implement correctly than a straight implementation on old streams.

我对nioAsyncParse实现的低性能感到惊讶。要么我用错误的方式实现了某些东西,要么使用NIO实现了多线程实现,一个完成处理程序的执行效果与使用java的单线程实现相同(甚至更糟)。io API。此外,带有CompletionHandler的异步解析在代码行中要比在旧流上的直接实现长得多,并且很难正确实现。

Now the six implementations followed by a class containing them all plus a parametrizable main() method that allows to play with the number of files, file size and concurrency degree. Note that the size of the files varies plus minus 20%. This is to avoid any effect due to all the files being of exactly the same size.

现在,六个实现后面跟着一个包含它们的类,加上一个参数化的main()方法,该方法允许处理文件的数量、文件大小和并发程度。请注意,文件的大小不同,正负20%。这是为了避免由于所有文件大小完全相同而产生的任何影响。

rawParse

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

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

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

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

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) {
        }
};

FULL RUNNABLE IMPLEMENTATION OF ALL CASES

所有情况的完全可运行实现

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

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

#8


19  

Here are the three working and tested methods:

以下是三种有效和经过测试的方法:

Using 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);
        }
    }
}

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

Using 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);
        }
    }
}

Read the entire file without a loop using the Scanner class

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

#9


17  

What do you want to do with the text? Is the file small enough to fit into memory? I would try to find the simplest way to handle the file for your needs. The FileUtils library is very handle for this.

你想用这篇课文做什么?这个文件是否足够小到可以装入内存?我将设法找到最简单的方法来处理文件,以满足您的需要。FileUtils库对此非常负责。

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

#10


9  

Below is a one-liner of doing it in the Java 8 way. Assuming text.txt file is in the root of the project directory of the Eclipse.

下面是用Java 8方法完成的一行代码。假设文本。txt文件位于Eclipse项目目录的根目录中。

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

#11


7  

Using BufferedReader:

使用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();
}

#12


7  

This is basically the exact same as Jesus Ramos' answer, except with File instead of FileReader plus iteration to step through the contents of the file.

这基本上与耶稣•拉莫斯的答案完全相同,除了使用File而不是FileReader + iteration来遍历文件内容。

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

... throws FileNotFoundException

…抛出FileNotFoundException

#13


6  

Probably not as fast as with buffered I/O, but quite terse:

可能没有缓冲I/O那么快,但很简洁:

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

The \Z pattern tells the Scanner that the delimiter is EOF.

\Z模式告诉扫描器,分隔符是EOF。

#14


4  

I don't see it mentioned yet in the other answers so far. But if "Best" means speed, then the new Java I/O (NIO) might provide the fastest preformance, but not always the easiest to figure out for someone learning.

到目前为止,我还没有看到其他答案中提到它。但是,如果“最佳”意味着速度,那么新的Java I/O (NIO)可能提供最快的性能,但并不总是最容易理解的。

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

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

#15


3  

The most simple way to read data from a file in Java is making use of the File class to read the file and the Scanner class to read the content of the file.

从Java文件中读取数据的最简单方法是利用文件类来读取文件和扫描仪类来读取文件的内容。

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: Don't forget to import java.util.*; for Scanner to work.

别忘了导入java.util.*;扫描仪工作。

#16


3  

I documented 15 ways to read a file in Java and then tested them for speed with various file sizes - from 1 KB to 1 GB and here are the top three ways to do this:

我记录了15种读取Java文件的方法,然后用不同的文件大小对它们进行测试——从1 KB到1 GB,下面是3种方法:

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

    java.nio.file.Files.readAllBytes()

    Tested to work in Java 7, 8, and 9.

    测试在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.io.BufferedReader.readLine()

    Tested to work in Java 7, 8, 9.

    测试在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.nio.file.Files.lines()

    This was tested to work in Java 8 and 9 but won't work in Java 7 because of the lambda expression requirement.

    这在Java 8和Java 9中进行了测试,但由于lambda表达式要求,在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);
          });
        }
      }
    }
    

#17


2  

This might not be the exact answer to the question. It's just another way of reading a file where you do not explicitly specify the path to your file in your Java code and instead, you read it as a command-line argument.

这可能不是这个问题的确切答案。这只是读取文件的另一种方式,在这种情况下,您不需要在Java代码中显式地指定文件的路径,而是将其作为命令行参数读取。

With the following code,

用下面的代码,

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);
        }
    }
}

just go ahead and run it with:

直接运行它:

java InputReader < input.txt

This would read the contents of the input.txt and print it to the your console.

这将读取输入的内容。txt并将其打印到您的控制台。

You can also make your System.out.println() to write to a specific file through the command line as follows:

您还可以通过命令行将System.out.println()写入特定的文件,如下所示:

java InputReader < input.txt > output.txt

This would read from input.txt and write to output.txt.

这将从输入中读取。并写入output.txt。

#18


1  

For JSF-based Maven web applications, just use ClassLoader and the Resources folder to read in any file you want:

对于基于jsf的Maven web应用程序,只需使用ClassLoader和Resources文件夹在任何您想要的文件中读取:

  1. Put any file you want to read in the Resources folder.
  2. 将您想要读取的任何文件放入“资源”文件夹。
  3. Put the Apache Commons IO dependency into your POM:

    将Apache Commons IO依赖项放入POM中:

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
    
  4. Use the code below to read it (e.g. below is reading in a .json file):

    使用下面的代码来读取它(例如,下面正在读取.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;
    

You can do the same for text files, .properties files, XSD schemas, etc.

您可以对文本文件、.properties文件、XSD模式等执行相同的操作。

#19


1  

Guava provides a one-liner for this:

番石榴为这一点提供了一句俏皮话:

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

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

#20


1  

Cactoos give you a declarative one-liner:

Cactoos给你一个声明式的一行:

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

#21


0  

Use Java kiss if this is about simplicity of structure:

如果这是关于结构的简单性,请使用Java kiss:

import static kiss.API.*;

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

#22


0  

You can use readAllLines and the join method to get whole file content in one line:

您可以使用readAllLines和join方法在一行中获取整个文件内容:

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

It uses UTF-8 encoding by default, which reads ASCII data correctly.

它默认使用UTF-8编码,正确读取ASCII数据。

Also you can use readAllBytes:

也可以使用readAllBytes:

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

I think readAllBytes is faster and more precise, because it does not replace new line with \n and also new line may be \r\n. It is depending on your needs which one is suitable.

我认为readAllBytes更快更准确,因为它不会用\n替换新的行,而且新的行可能是\r\n。这取决于你的需要哪一个是合适的。

#23


-3  

This code I programmed is much faster for very large files:

我编写的代码对于非常大的文件要快得多:

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;
}

#1


458  

ASCII is a TEXT file so you would use Readers for reading. Java also supports reading from a binary file using InputStreams. If the files being read are huge then you would want to use a BufferedReader on top of a FileReader to improve read performance.

ASCII是一个文本文件,因此您可以使用阅读器来阅读。Java还支持使用inputstream读取二进制文件。如果正在读取的文件很大,那么您应该在文件阅读器的顶部使用BufferedReader来提高读取性能。

Go through this article on how to use a Reader

请阅读这篇关于如何使用读者的文章

I'd also recommend you download and read this wonderful (yet free) book called Thinking In Java

我还建议您下载并阅读这本名为《用Java思考》(Thinking In Java)的优秀(但免费)的书。

In Java 7:

在Java 7:

new String(Files.readAllBytes(...)) or Files.readAllLines(...)

新的字符串(Files.readAllBytes(…))或Files.readAllLines(…)

In Java 8:

在Java 8:

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

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

#2


629  

My favorite way to read a small file is to use a BufferedReader and a StringBuilder. It is very simple and to the point (though not particularly effective, but good enough for most cases):

我最喜欢的读取小文件的方式是使用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();
}

Some has pointed out that after Java 7 you should use try-with-resources (i.e. auto close) features:

有人指出,在Java 7之后,您应该使用带有资源(即自动关闭)的try- 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();
}

When I read strings like this, I usually want to do some string handling per line anyways, so then I go for this implementation.

当我像这样读取字符串时,我通常希望对每行进行一些字符串处理,因此我使用这个实现。

Though if I want to actually just read a file into a String, I always use Apache Commons IO with the class IOUtils.toString() method. You can have a look at the source here:

尽管如果我只是想把文件读入一个字符串,我总是使用Apache Commons IO和class ioutil . tostring()方法。你可以在这里看一下来源:

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

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

And even simpler with Java 7:

更简单的Java 7:

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

#3


123  

The easiest way is to use the Scanner class in Java and the FileReader object. Simple example:

最简单的方法是在Java和FileReader对象中使用扫描器类。简单的例子:

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

Scanner has several methods for reading in strings, numbers, etc... You can look for more information on this on the Java documentation page.

扫描器有几种方法来读取字符串、数字等。您可以在Java文档页面上查找有关此的更多信息。

For example reading the whole content into a String:

例如,将整个内容读入一个字符串:

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

Also if you need a specific encoding you can use this instead of FileReader:

如果你需要一个特定的编码,你可以用它来代替FileReader:

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

#4


57  

Here is a simple solution:

这里有一个简单的解决方案:

String content;

content = new String(Files.readAllBytes(Paths.get("sample.txt")));

#5


53  

Here's another way to do it without using external libraries:

这里有另一种不用外部库的方法:

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;
}

#6


21  

The methods within org.apache.commons.io.FileUtils may also be very handy, e.g.:

org.apache.common . 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)

#7


21  

I had to benchmark the different ways. I shall comment on my findings but, in short, the fastest way is to use a plain old BufferedInputStream over a FileInputStream. If many files must be read then three threads will reduce the total execution time to roughly half, but adding more threads will progressively degrade performance until making it take three times longer to complete with twenty threads than with just one thread.

我必须衡量不同的方法。我将对我的发现进行评论,但是,简而言之,最快的方法是在FileInputStream上使用一个普通的旧BufferedInputStream。如果必须读取许多文件,那么三个线程将把总执行时间减少到大约一半,但是添加更多的线程将逐渐降低性能,直到使20个线程完成的时间比只用一个线程完成的时间长三倍。

The assumption is that you must read a file and do something meaningful with its contents. In the examples here is reading lines from a log and count the ones which contain values that exceed a certain threshold. So I am assuming that the one-liner Java 8 Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";")) is not an option.

假设您必须读取一个文件并对其内容做一些有意义的事情。在这里的示例中,从日志中读取行并计算包含超过某个阈值的值的行数。所以我假设一行的Java 8文件。lines(path. get(“/path/to/file.txt”)。map(line -> line.split(";"))不是选项。

I tested on Java 1.8, Windows 7 and both SSD and HDD drives.

我在Java 1.8、Windows 7以及SSD和HDD驱动器上进行了测试。

I wrote six different implementations:

我写了六种不同的实现:

rawParse: Use BufferedInputStream over a FileInputStream and then cut lines reading byte by byte. This outperformed any other single-thread approach, but it may be very inconvenient for non-ASCII files.

rawParse:在FileInputStream上使用buffer埃迪森putstream,然后逐字节地删除行。这种方法优于任何其他的单线程方法,但是对于非ascii文件来说可能非常不方便。

lineReaderParse: Use a BufferedReader over a FileReader, read line by line, split lines by calling String.split(). This is approximatedly 20% slower that rawParse.

lineReaderParse:在文件阅读器上使用BufferedReader,逐行读取,通过调用String.split()分割行。这比rawParse快了大约20%。

lineReaderParseParallel: This is the same as lineReaderParse, but it uses several threads. This is the fastest option overall in all cases.

linereaderparseparation:这与lineReaderParse相同,但是它使用了几个线程。这是所有情况下最快的选择。

nioFilesParse: Use java.nio.files.Files.lines()

nioFilesParse:使用java.nio.files.Files.lines()

nioAsyncParse: Use an AsynchronousFileChannel with a completion handler and a thread pool.

nioAsyncParse:使用带有完成处理程序和线程池的AsynchronousFileChannel。

nioMemoryMappedParse: Use a memory-mapped file. This is really a bad idea yielding execution times at least three times longer than any other implementation.

nioMemoryMappedParse:使用内存映射文件。这确实是一个糟糕的想法,它会使执行时间比任何其他实现都长至少三倍。

These are the average times for reading 204 files of 4 MB each on an quad-core i7 and SSD drive. The files are generated on the fly to avoid disk caching.

这是在四核i7和SSD驱动器上读取204个4 MB文件的平均时间。为了避免磁盘缓存,文件会自动生成。

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

I found a difference smaller than I expected between running on an SSD or an HDD drive being the SSD approximately 15% faster. This may be because the files are generated on an unfragmented HDD and they are read sequentially, therefore the spinning drive can perform nearly as an SSD.

我发现在SSD上运行和在硬盘驱动器上运行的差别比我预期的要小,大约快15%。这可能是因为这些文件是在未分段的HDD上生成的,并且它们是按顺序读取的,因此旋转驱动器几乎可以作为SSD执行。

I was surprised by the low performance of the nioAsyncParse implementation. Either I have implemented something in the wrong way or the multi-thread implementation using NIO and a completion handler performs the same (or even worse) than a single-thread implementation with the java.io API. Moreover the asynchronous parse with a CompletionHandler is much longer in lines of code and tricky to implement correctly than a straight implementation on old streams.

我对nioAsyncParse实现的低性能感到惊讶。要么我用错误的方式实现了某些东西,要么使用NIO实现了多线程实现,一个完成处理程序的执行效果与使用java的单线程实现相同(甚至更糟)。io API。此外,带有CompletionHandler的异步解析在代码行中要比在旧流上的直接实现长得多,并且很难正确实现。

Now the six implementations followed by a class containing them all plus a parametrizable main() method that allows to play with the number of files, file size and concurrency degree. Note that the size of the files varies plus minus 20%. This is to avoid any effect due to all the files being of exactly the same size.

现在,六个实现后面跟着一个包含它们的类,加上一个参数化的main()方法,该方法允许处理文件的数量、文件大小和并发程度。请注意,文件的大小不同,正负20%。这是为了避免由于所有文件大小完全相同而产生的任何影响。

rawParse

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

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

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

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

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) {
        }
};

FULL RUNNABLE IMPLEMENTATION OF ALL CASES

所有情况的完全可运行实现

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

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

#8


19  

Here are the three working and tested methods:

以下是三种有效和经过测试的方法:

Using 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);
        }
    }
}

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

Using 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);
        }
    }
}

Read the entire file without a loop using the Scanner class

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

#9


17  

What do you want to do with the text? Is the file small enough to fit into memory? I would try to find the simplest way to handle the file for your needs. The FileUtils library is very handle for this.

你想用这篇课文做什么?这个文件是否足够小到可以装入内存?我将设法找到最简单的方法来处理文件,以满足您的需要。FileUtils库对此非常负责。

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

#10


9  

Below is a one-liner of doing it in the Java 8 way. Assuming text.txt file is in the root of the project directory of the Eclipse.

下面是用Java 8方法完成的一行代码。假设文本。txt文件位于Eclipse项目目录的根目录中。

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

#11


7  

Using BufferedReader:

使用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();
}

#12


7  

This is basically the exact same as Jesus Ramos' answer, except with File instead of FileReader plus iteration to step through the contents of the file.

这基本上与耶稣•拉莫斯的答案完全相同,除了使用File而不是FileReader + iteration来遍历文件内容。

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

... throws FileNotFoundException

…抛出FileNotFoundException

#13


6  

Probably not as fast as with buffered I/O, but quite terse:

可能没有缓冲I/O那么快,但很简洁:

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

The \Z pattern tells the Scanner that the delimiter is EOF.

\Z模式告诉扫描器,分隔符是EOF。

#14


4  

I don't see it mentioned yet in the other answers so far. But if "Best" means speed, then the new Java I/O (NIO) might provide the fastest preformance, but not always the easiest to figure out for someone learning.

到目前为止,我还没有看到其他答案中提到它。但是,如果“最佳”意味着速度,那么新的Java I/O (NIO)可能提供最快的性能,但并不总是最容易理解的。

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

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

#15


3  

The most simple way to read data from a file in Java is making use of the File class to read the file and the Scanner class to read the content of the file.

从Java文件中读取数据的最简单方法是利用文件类来读取文件和扫描仪类来读取文件的内容。

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: Don't forget to import java.util.*; for Scanner to work.

别忘了导入java.util.*;扫描仪工作。

#16


3  

I documented 15 ways to read a file in Java and then tested them for speed with various file sizes - from 1 KB to 1 GB and here are the top three ways to do this:

我记录了15种读取Java文件的方法,然后用不同的文件大小对它们进行测试——从1 KB到1 GB,下面是3种方法:

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

    java.nio.file.Files.readAllBytes()

    Tested to work in Java 7, 8, and 9.

    测试在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.io.BufferedReader.readLine()

    Tested to work in Java 7, 8, 9.

    测试在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.nio.file.Files.lines()

    This was tested to work in Java 8 and 9 but won't work in Java 7 because of the lambda expression requirement.

    这在Java 8和Java 9中进行了测试,但由于lambda表达式要求,在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);
          });
        }
      }
    }
    

#17


2  

This might not be the exact answer to the question. It's just another way of reading a file where you do not explicitly specify the path to your file in your Java code and instead, you read it as a command-line argument.

这可能不是这个问题的确切答案。这只是读取文件的另一种方式,在这种情况下,您不需要在Java代码中显式地指定文件的路径,而是将其作为命令行参数读取。

With the following code,

用下面的代码,

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);
        }
    }
}

just go ahead and run it with:

直接运行它:

java InputReader < input.txt

This would read the contents of the input.txt and print it to the your console.

这将读取输入的内容。txt并将其打印到您的控制台。

You can also make your System.out.println() to write to a specific file through the command line as follows:

您还可以通过命令行将System.out.println()写入特定的文件,如下所示:

java InputReader < input.txt > output.txt

This would read from input.txt and write to output.txt.

这将从输入中读取。并写入output.txt。

#18


1  

For JSF-based Maven web applications, just use ClassLoader and the Resources folder to read in any file you want:

对于基于jsf的Maven web应用程序,只需使用ClassLoader和Resources文件夹在任何您想要的文件中读取:

  1. Put any file you want to read in the Resources folder.
  2. 将您想要读取的任何文件放入“资源”文件夹。
  3. Put the Apache Commons IO dependency into your POM:

    将Apache Commons IO依赖项放入POM中:

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
    
  4. Use the code below to read it (e.g. below is reading in a .json file):

    使用下面的代码来读取它(例如,下面正在读取.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;
    

You can do the same for text files, .properties files, XSD schemas, etc.

您可以对文本文件、.properties文件、XSD模式等执行相同的操作。

#19


1  

Guava provides a one-liner for this:

番石榴为这一点提供了一句俏皮话:

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

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

#20


1  

Cactoos give you a declarative one-liner:

Cactoos给你一个声明式的一行:

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

#21


0  

Use Java kiss if this is about simplicity of structure:

如果这是关于结构的简单性,请使用Java kiss:

import static kiss.API.*;

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

#22


0  

You can use readAllLines and the join method to get whole file content in one line:

您可以使用readAllLines和join方法在一行中获取整个文件内容:

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

It uses UTF-8 encoding by default, which reads ASCII data correctly.

它默认使用UTF-8编码,正确读取ASCII数据。

Also you can use readAllBytes:

也可以使用readAllBytes:

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

I think readAllBytes is faster and more precise, because it does not replace new line with \n and also new line may be \r\n. It is depending on your needs which one is suitable.

我认为readAllBytes更快更准确,因为它不会用\n替换新的行,而且新的行可能是\r\n。这取决于你的需要哪一个是合适的。

#23


-3  

This code I programmed is much faster for very large files:

我编写的代码对于非常大的文件要快得多:

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;
}