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



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



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



1 62 4 55 5 6 77


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

869   9  

9 ответов:

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

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

руководство: основной ввод-вывод > файл ввод-вывод > чтение, запись и создание текстовых файлов


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

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

руководство: числа и строки > строки > манипулирование символами в a Строка


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

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

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

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

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

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

     }
  }

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

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());
        }
    }
}

просто для удовольствия, вот что я бы сделал в реальном проекте, где я уже использую все мои любимые библиотеки (в данном случае гуавы, ранее известная как Коллекции 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));
}

преимущество: не так много собственного кода для поддержания (контраст с, например,этой). Edit: хотя стоит отметить, что в данном случае решение сканера tschaible больше нет код!

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

использовать 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(" "));

сделано.

использование 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);

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

читать файл, а затем делать все, что захочешь java8 Файлы.линии (пути.сделать("c://lines.формат txt.))"собирать(коллекционеров.toList ());

Comments

    Ничего не найдено.