Java: как читать текстовый файл

Я хочу прочитать текстовый файл, содержащий значения, разделенные пробелами. Значения являются целыми числами. Как я могу его прочитать и поместить в список массивов?

Вот пример содержимого текстового файла:

1 62 4 55 5 6 77

Я хочу иметь его в arraylist как [1, 62, 4, 55, 5, 6, 77]. Как я могу сделать это на Java?

Ответ 1

Вы можете использовать Files#readAllLines(), чтобы получить все строки текстового файла в List<String>.

for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    // ...
}

Учебник: Основные операции ввода-выводa > Файл ввода-выводa > Чтение, запись и создание текстовых файлов


Вы можете использовать String#split() для разделения String по частям на основе регулярного выражения.

for (String part : line.split("\\s+")) {
    // ...
}

Учебное пособие: Числа и строки > Строки > Манипуляция символами в строке


Вы можете использовать Integer#valueOf(), чтобы преобразовать String в Integer.

Integer i = Integer.valueOf(part);

Учебное пособие: Числа и строки > Строки > Преобразование между номерами и строками


Вы можете использовать List#add(), чтобы добавить элемент в List.

numbers.add(i);

Учебное пособие: Интерфейсы > Интерфейс списка


Итак, в двух словах (предполагая, что в файле нет пустых строк и пробелов/ведущих пробелов).

List<Integer> numbers = new ArrayList<>();
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    for (String part : line.split("\\s+")) {
        Integer i = Integer.valueOf(part);
        numbers.add(i);
    }
}

Если вы уже на Java 8, вы можете использовать Stream API для этого, начиная с Files#lines().

List<Integer> numbers = Files.lines(Paths.get("/path/to/test.txt"))
    .map(line -> line.split("\\s+")).flatMap(Arrays::stream)
    .map(Integer::valueOf)
    .collect(Collectors.toList());

Учебное пособие: Обработка данных с помощью потоков Java 8

Ответ 2

Java 1.5 представила класс Scanner для обработки ввода из файла и потоков.

Он используется для получения целых чисел из файла и будет выглядеть примерно так:

List<Integer> integers = new ArrayList<Integer>();
Scanner fileScanner = new Scanner(new File("c:\\file.txt"));
while (fileScanner.hasNextInt()){
   integers.add(fileScanner.nextInt());
}

Проверьте API. Существует гораздо больше возможностей для работы с различными типами источников ввода, разными разделителями и разными типами данных.

Ответ 3

В этом примере кода показано, как читать файл на Java.

import java.io.*;

/**
 * This example code shows you how to read file in Java
 *
 * IN MY CASE RAILWAY IS MY TEXT FILE WHICH I WANT TO DISPLAY YOU CHANGE WITH YOUR   OWN      
 */

 public class ReadFileExample 
 {
    public static void main(String[] args) 
    {
       System.out.println("Reading File from Java code");
       //Name of the file
       String fileName="RAILWAY.txt";
       try{

          //Create object of FileReader
          FileReader inputFile = new FileReader(fileName);

          //Instantiate the BufferedReader Class
          BufferedReader bufferReader = new BufferedReader(inputFile);

          //Variable to hold the one line data
          String line;

          // Read file line by line and print on the console
          while ((line = bufferReader.readLine()) != null)   {
            System.out.println(line);
          }
          //Close the buffer reader
          bufferReader.close();
       }catch(Exception e){
          System.out.println("Error while reading file line by line:" + e.getMessage());                      
       }

     }
  }

Ответ 4

Посмотрите на этот пример и попытайтесь сделать свой собственный:

import java.io.*;

public class ReadFile {

    public static void main(String[] args){
        String string = "";
        String file = "textFile.txt";

        // Reading
        try{
            InputStream ips = new FileInputStream(file);
            InputStreamReader ipsr = new InputStreamReader(ips);
            BufferedReader br = new BufferedReader(ipsr);
            String line;
            while ((line = br.readLine()) != null){
                System.out.println(line);
                string += line + "\n";
            }
            br.close();
        }
        catch (Exception e){
            System.out.println(e.toString());
        }

        // Writing
        try {
            FileWriter fw = new FileWriter (file);
            BufferedWriter bw = new BufferedWriter (fw);
            PrintWriter fileOut = new PrintWriter (bw);
                fileOut.println (string+"\n test of read and write !!");
            fileOut.close();
            System.out.println("the file " + file + " is created!");
        }
        catch (Exception e){
            System.out.println(e.toString());
        }
    }
}

Ответ 5

Просто для удовольствия, вот что я мог бы сделать в реальном проекте, где я уже использую все мои любимые библиотеки (в этом случае Guava, ранее известный как Google Collections).

String text = Files.toString(new File("textfile.txt"), Charsets.UTF_8);
List<Integer> list = Lists.newArrayList();
for (String s : text.split("\\s")) {
    list.add(Integer.valueOf(s));
}

Преимущество: не поддерживается собственный код (контрастируйте, например, this). Изменить: Хотя стоит отметить, что в этом случае решение tschaible Scanner не имеет никакого кода!

Недостаток: вы, очевидно, не захотите добавлять новые зависимости библиотеки только для этого. (И снова вам было бы глупо не использовать Guava в ваших проектах. -)

Ответ 6

Используйте Apache Commons (IO и Lang) для простых/общих вещей, подобных этому.

Импорт

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;

код:

String contents = FileUtils.readFileToString(new File("path/to/your/file.txt"));
String[] array = ArrayUtils.toArray(contents.split(" "));

Готово.

Ответ 7

Использование Java 7 для чтения файлов с NIO.2

Импортируйте эти пакеты:

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Это процесс чтения файла:

Path file = Paths.get("C:\\Java\\file.txt");

if(Files.exists(file) && Files.isReadable(file)) {

    try {
        // File reader
        BufferedReader reader = Files.newBufferedReader(file, Charset.defaultCharset());

        String line;
        // read each line
        while((line = reader.readLine()) != null) {
            System.out.println(line);
            // tokenize each number
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            while (tokenizer.hasMoreElements()) {
                // parse each integer in file
                int element = Integer.parseInt(tokenizer.nextToken());
            }
        }
        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Чтобы сразу прочитать все строки файла:

Path file = Paths.get("C:\\Java\\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);

Ответ 8

Все приведенные до сих пор ответы включают чтение файла по строкам, ввод строки в виде String, а затем обработку String.

Нет сомнений в том, что это самый простой подход к пониманию, и если файл довольно короткий (скажем, десятки тысяч строк), он также будет приемлемым с точки зрения эффективности. Но если файл длинный, это очень неэффективный способ сделать это по двум причинам:

  • Каждый символ обрабатывается дважды, один раз при построении String и один раз при его обработке.
  • Сборщик мусора не будет вашим другом, если в файле много строк. Вы создаете новый String для каждой строки, а затем бросаете его, когда переходите к следующей строке. Сборщик мусора в конечном итоге должен будет избавиться от всех этих String объектов, которые вам больше не нужны. Кто-то должен убираться после вас.

Если вам нужна скорость, вам гораздо лучше читать блок данных, а затем обрабатывать его байтом байтом, а не строковым. Каждый раз, когда вы приходите к концу числа, вы добавляете его в List, который вы строите.

Появится что-то вроде этого:

private List<Integer> readIntegers(File file) throws IOException {
    List<Integer> result = new ArrayList<>();
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    byte buf[] = new byte[16 * 1024];
    final FileChannel ch = raf.getChannel();
    int fileLength = (int) ch.size();
    final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
            fileLength);
    int acc = 0;
    while (mb.hasRemaining()) {
        int len = Math.min(mb.remaining(), buf.length);
        mb.get(buf, 0, len);
        for (int i = 0; i < len; i++)
            if ((buf[i] >= 48) && (buf[i] <= 57))
                acc = acc * 10 + buf[i] - 48;
            else {
                result.add(acc);
                acc = 0;
            }
    }
    ch.close();
    raf.close();
    return result;
}

В приведенном выше коде предполагается, что это ASCII (хотя он может быть легко изменен для других кодировок), и что все, что не является цифрой (в частности, пробелом или новой линией), представляет собой границу между цифрами. Он также предполагает, что файл заканчивается не цифрой (на практике, что последняя строка заканчивается новой строкой), хотя, опять же, она может быть изменена, чтобы иметь дело с тем случаем, когда это не так.

Он намного быстрее, чем, чем любой из подходов, основанных на String, также даваемых в качестве ответов на этот вопрос. В этом вопросе подробно рассматривается очень похожий вопрос . Вы увидите, что есть возможность улучшить его еще дальше, если вы хотите спуститься по многопоточной линии.

Ответ 9

прочитайте файл, а затем сделайте все, что хотите. java8 Files.lines(Paths.get( "C://lines.txt" )). Сбор (Collectors.toList());