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

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

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

1 62 4 55 5 6 77

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


person aks    schedule 07.05.2010    source источник


Ответы (9)


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

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

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


Вы можете использовать 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

person BalusC    schedule 07.05.2010
comment
Обратите внимание, что в Java 7 и 8 есть лучшие способы сделать это: stackoverflow.com/questions/4716503/ - person Alex Beardsley; 12.08.2014

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

person tschaible    schedule 07.05.2010
comment
это гораздо легче запомнить, чем комбинацию буферизованного, ввода-вывода, чтения - person avanderw; 30.01.2014

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

     }
  }
person Sajjad Khan    schedule 01.03.2013

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

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());
        }
    }
}
person Eddinho    schedule 07.05.2010

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

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 в своих проектах. ;-)

person Jonik    schedule 07.05.2010
comment
Конечно, вместо цикла можно было бы также использовать transform() и функцию из коллекций Google, но ИМХО это было бы менее читабельно и даже не короче. - person Jonik; 07.05.2010

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

Сделанный.

person Chris    schedule 04.08.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);
person user2601995    schedule 03.02.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, также приведенных в качестве ответов на этот вопрос. Существует подробное исследование очень похожей проблемы в этом вопросе. Там вы увидите, что есть возможность улучшить его еще больше, если вы хотите пойти по многопоточной линии.

person chiastic-security    schedule 15.09.2014

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

person Ran Adler    schedule 04.07.2016