Java: Как читать текстовый файл - PullRequest
81 голосов
/ 07 мая 2010

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

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

1 62 4 55 5 6 77

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

Ответы [ 9 ]

170 голосов
/ 07 мая 2010

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

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

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


Вы можете использовать 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 для этого, стarting с 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

34 голосов
/ 07 мая 2010

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, хотя. Есть еще много вариантов работы с различными типами источников ввода, различными разделителями и различными типами данных.

18 голосов
/ 01 марта 2013

В этом примере кода показано, как читать файл в 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());                      
       }

     }
  }
10 голосов
/ 07 мая 2010

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

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 голосов
/ 07 мая 2010

Просто для удовольствия, вот что я, вероятно, сделаю в реальном проекте, где я уже использую все свои любимые библиотеки (в данном случае Гуава , ранее известный как 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 ). Редактировать : Хотя стоит отметить, что в этом случае Решение Scanner * tschaible не имеет больше кода!

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

4 голосов
/ 04 августа 2014

Используйте 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(" "));

Готово.

2 голосов
/ 03 февраля 2014

Использование 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);
1 голос
/ 15 сентября 2014

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

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

  1. Каждый символ обрабатывается дважды, один раз при построении String и один раз при его обработке.
  2. Сборщик мусора не будет вашим другом, если в файле много строк. Вы создаете новый 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 подходов, также приведенных в качестве ответов на этот вопрос. В этом вопросе подробно рассматривается очень похожая проблема . Там вы увидите, что есть возможность улучшить его еще больше, если вы захотите пойти по многопоточной линии.

0 голосов
/ 04 июля 2016

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

.
...