1. Обзор
В этом руководстве мы обсудим различные способы чтения файла в ArrayList
.
Есть много способов прочитать файл в Java . Когда мы читаем файл, мы можем выполнять множество операций над содержимым этого файла.
Некоторые из этих операций, например сортировка, могут потребовать обработки всего содержимого файла в памяти. Для выполнения таких операций нам может потребоваться прочитать файл как массив
или список
строк или слов.
2. Использование FileReader
Самый простой способ чтения файла в Java — использование FileReader
. По определению FileReader
— это удобный класс для чтения потока символов из файла.
Для инициализации FileReader
доступно несколько конструкторов : ``
FileReader f = new FileReader(String filepath);
FileReader f = new FileReader(File f);
FileReader f = new FileReader(FileDescriptor fd);
Все эти конструкторы предполагают, что кодировка символов по умолчанию и размер байтового буфера по умолчанию являются подходящими.
Однако, если мы хотим предоставить пользовательскую кодировку символов и размер байтового буфера, мы можем использовать InputStreamReader
или FileInputStream
.
В следующем коде мы покажем, как читать строки из файла в ArrayList
с помощью FileReader:
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. Использование BufferedReader
Хотя FileReader
довольно прост в использовании, рекомендуется всегда обертывать его BuffereReader
при чтении файла.
Это связано с тем, что BufferedReader
использует буфер символов для одновременного чтения нескольких значений из потока ввода символов и, следовательно, уменьшает количество вызовов read()
, выполняемых базовым FileStream
.
Конструкторы для BufferedReader
принимают Reader
в качестве входных данных. Кроме того, мы также можем указать размер буфера в конструкторах, но для большинства случаев использования размер по умолчанию достаточно велик:
BufferedReader br = new BufferedReader(new FileReader(filename));
BufferedReader br = new BufferedReader(new FileReader(filename), size);
В дополнение к методам, унаследованным от класса Reader ,
BufferedReader также
предоставляет метод readLine()
для чтения всей строки в виде строки:
ArrayList<String> result = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
while (br.ready()) {
result.add(br.readLine());
}
}
4. Использование сканера
Другой распространенный способ чтения файлов — через Scanner
.
Scanner
— это простой текстовый сканер, используемый для анализа примитивных типов и строк с использованием регулярных выражений.
При чтении файлов Scanner
инициализируется с помощью объектов File
или FileReader :
Scanner s = new Scanner(new File(filename));
Scanner s = new Scanner(new FileReader(filename));
Подобно 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;
}
Сканер
разбивает входные данные на токены с помощью разделителя, разделителем по умолчанию является пробел. Эти токены могут быть преобразованы в значения разных типов с помощью различных доступных методов 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. Использование Files.readAllLines
Вероятно, самый простой способ прочитать файл и проанализировать все его строки в ArrayList
— это использовать метод readAllLines()
, доступный в классе Files :
List<String> result = Files.readAllLines(Paths.get(filename));
Этот метод также может принимать параметр charset для чтения в соответствии с определенной кодировкой символов:
Charset charset = Charset.forName("ISO-8859-1");
List<String> result = Files.readAllLines(Paths.get(filename), charset);
6. Заключение
Подводя итог, мы обсудили некоторые распространенные способы чтения содержимого File
в ArrayList
. Кроме того, мы рассмотрели некоторые преимущества и недостатки различных методов.
Например, мы можем использовать BufferedReader
для буферизации символов для повышения эффективности. В качестве альтернативы мы могли бы использовать Scanner
для чтения примитива с использованием разделителей. Или, возможно, мы могли бы просто использовать Files.readAllLines(),
не беспокоясь о базовой реализации.
Как обычно, код доступен в нашем репозитории GitHub .