Read a File into an ArrayList – 将文件读入数组列表

最后修改: 2018年 8月 13日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss different ways of reading a file into an ArrayList.

在本教程中,我们将讨论ArrayList读取文件的不同方法。

There are many ways to read a file in Java. Once we read a file, we can perform a lot of operations on the content of that file.

有许多方法可以在Java中读取一个文件。一旦我们读取了一个文件,我们就可以对该文件的内容进行很多操作。

Some of these operations, like sorting, may require processing the entire content of the file into memory. In order to perform such operations, we may need to read the file as an Array or a List of lines or words.

其中一些操作,如排序,可能需要将文件的整个内容处理到内存中。为了执行此类操作,我们可能需要将文件作为行或字的ArrayList读取。

2. Using FileReader

2.使用FileReader

The most basic way of reading a file in Java is using FileReader. By definition, FileReader is a convenience class for reading stream of characters from a File.

在Java中读取文件的最基本方法是使用FileReader。根据定义,FileReader是一个方便的类,用于从File.读取字符流。

There are multiple constructors available to initialize a FileReader:

有多个构造函数可用于初始化FileReader:

FileReader f = new FileReader(String filepath);
FileReader f = new FileReader(File f);
FileReader f = new FileReader(FileDescriptor fd);

All of these constructors assume that the default character encoding and the default byte-buffer size are appropriate.

所有这些构造函数都假定默认的字符编码和默认的字节缓冲区大小是合适的。

However, if we want to provide custom character encoding and byte buffer size, we can use InputStreamReader or FileInputStream.

然而,如果我们想提供自定义的字符编码和字节缓冲区大小,我们可以使用InputStreamReaderFileInputStream

In the following code, we’ll demonstrate how to read lines from a file into an ArrayList, using FileReader:

在下面的代码中,我们将演示如何使用FileReader:从文件中读取行到ArrayList。

ArrayList<String> result = new ArrayList<>();

try (FileReader f = new FileReader(filename)) {
    StringBuffer sb = new StringBuffer();
    while (f.ready()) {
        char c = (char) f.read();
        if (c == '\n') {
            result.add(sb.toString());
            sb = new StringBuffer();
        } else {
            sb.append(c);
        }
    }
    if (sb.length() > 0) {
        result.add(sb.toString());
    }
}       
return result;

3. Using BufferedReader

3.使用BufferedReader

Although FileReader is pretty easy to use, it’s advisable to always wrap it with BuffereReader, when reading a file.

尽管FileReader相当容易使用,但建议在读取文件时,总是用BuffereReader来包裹它。

This is because BufferedReader uses a char buffer to simultaneously read multiple values from a character-input stream and hence reduces the number of read() calls made by the underlying FileStream.

这是因为BufferedReader使用一个char缓冲区来同时从一个字符输入流中读取多个值,因此减少了底层FileStreamread()调用的数量。

Constructors for BufferedReader take Reader as input. Additionally, we can also provide buffer size in the constructors, but, for most use cases, the default size is large enough:

BufferedReader的构造函数将Reader作为输入。此外,我们也可以在构造函数中提供缓冲区的大小,但是,对于大多数使用情况,默认的大小已经足够大了。

BufferedReader br = new BufferedReader(new FileReader(filename));
BufferedReader br = new BufferedReader(new FileReader(filename), size);

In addition to the inherited methods from the Reader class, BufferedReader also provides readLine() method, to read an entire line as a String:

除了从Reader类继承的方法外,BufferedReader还提供了readLine()方法,以读取整个行作为String:

ArrayList<String> result = new ArrayList<>();

try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
    while (br.ready()) {
        result.add(br.readLine());
    }
}

4. Using Scanner

4.使用扫描器

Another common way of reading files is through Scanner.

另一种常见的读取文件的方式是通过Scanner

Scanner is a simple text scanner, used for parsing primitive types and strings, using regular expressions.

Scanner是一个简单的文本扫描仪,用于解析原始类型和字符串,使用正则表达式。

When reading files, Scanner is initialized using File or FileReader objects:

读取文件时,Scanner使用FileFileReader对象进行初始化。

Scanner s = new Scanner(new File(filename));
Scanner s = new Scanner(new FileReader(filename));

Similar to BufferedReader, Scanner provides readLine() method to read an entire line. Additionallyit also provides a hasNext() method to indicate whether more values are available for reading or not:

BufferedReader类似,Scanner提供了readLine()方法来读取整个行此外它还提供了一个hasNext()方法来指示是否有更多的值可供读取。

ArrayList<String> result = new ArrayList<>();

try (Scanner s = new Scanner(new FileReader(filename))) {
    while (s.hasNext()) {
        result.add(s.nextLine());
    }
    return result;
}

Scanner breaks its input into tokens using a delimiter, default delimiter being whitespace. These tokens can be converted into values of different types, by using various next (nextInt, nextLong, etc) methods available:

Scanner使用一个分隔符将其输入分解成标记,默认分隔符为空白。通过使用各种可用的next nextInt, nextLong等)方法,这些标记可以被转换为不同类型的值。

ArrayList<Integer> result = new ArrayList<>();

try (Scanner s = new Scanner(new FileReader(filename))) {
    while (s.hasNext()) {
        result.add(s.nextInt());
    }
    return result;
}

5. Using Files.readAllLines

5.使用Files.readAllLines

Probably the easiest way to read a file, and parse all its lines into an ArrayList, is to use the readAllLines() method available in Files class:

读取一个文件并将其所有行解析为ArrayList的最简单方法是使用Files类中的readAllLines() 方法:

List<String> result = Files.readAllLines(Paths.get(filename));

This method can also take a charset parameter, to read as per a specific character encoding:

这个方法也可以接受一个charset参数,以便按照特定的字符编码进行读取。

Charset charset = Charset.forName("ISO-8859-1");
List<String> result = Files.readAllLines(Paths.get(filename), charset);

6. Conclusion

6.结语

To summarize, we discussed some common ways of reading the contents of a File into an ArrayList. Also, we covered some advantages and disadvantages of the various methods.

总结一下,我们讨论了将文件的内容读入ArrayList的一些常见方法。此外,我们还介绍了各种方法的一些优点和缺点。

For example, we can use BufferedReader to buffer characters for efficiency. Alternatively, we could use Scanner to read primitive using delimiters. Or perhaps, we could simply use Files.readAllLines(), without worrying about underlying implementation.

例如,我们可以使用BufferedReader来缓冲字符以提高效率。或者,我们可以使用Scanner来使用分隔符读取原始数据。或者,我们可以简单地使用Files.readAllLines(),而不必担心底层实现。

As usual, the code is available in our GitHub repository.

像往常一样,代码可以在我们的GitHub仓库中找到。