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


81

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

Ось приклад вмісту текстового файлу:

1 62 4 55 5 6 77

Я хочу мати це в списку записів як [1, 62, 4, 55, 5, 6, 77]. Як я можу це зробити на Java?

Відповіді:


170

Ви можете використовувати, 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+")) {
    // ...
}

Підручник: Цифри та рядки> Рядки> Маніпулювання символами в рядку


Ви можете використовувати Integer#valueOf()для перетворення a 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


1
Зверніть увагу, що в Java 7 та 8 є кращі способи зробити це: stackoverflow.com/questions/4716503/…
Алекс Бердслі

34

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. Існує набагато більше варіантів роботи з різними типами джерел вхідних даних, різними роздільниками та різними типами даних.


2
це набагато легше запам’ятати, ніж буферизована комбінація читачів
avanderw

18

Цей приклад коду показує, як читати файли на 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

Подивіться на цей приклад і спробуйте зробити своє:

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

Для розваги ось ось що я, мабуть, зробив би у реальному проекті, де я вже використовую всі свої улюблені бібліотеки (в даному випадку Гуава , раніше відома як 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));
}

Перевага: Не так багато власного коду для підтримки (на відміну від, наприклад, цього ). Редагувати : Хоча варто зазначити, що в цьому випадку сканер tschaible більше не має коду!

Недолік: ви, очевидно, не хочете додавати нові бібліотечні залежності лише для цього. (Знову ж таки, ви б нерозумно не використовувати Гуаву у своїх проектах. ;-)


Звичайно, замість циклу можна також використовувати transform () & функцію від Google Collections, але IMHO, яка буде менш читабельною і навіть не коротшою.
Джонік

4

Використовуйте 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

Використання 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

Всі наведені досі відповіді включають читання файлу рядок за рядком, прийняття рядка як a 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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.