Как создать строку Java из содержимого файла?

avatar
OscarRyz
28 ноября 2008 в 18:32
1503674
33
1633

Я уже некоторое время использую приведенную ниже идиому. И он кажется самым распространенным, по крайней мере, на сайтах, которые я посещал.

Есть ли лучший / другой способ чтения файла в строку в Java?

private String readFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    String         line = null;
    StringBuilder  stringBuilder = new StringBuilder();
    String         ls = System.getProperty("line.separator");

    try {
        while((line = reader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append(ls);
        }

        return stringBuilder.toString();
    } finally {
        reader.close();
    }
}
Источник
OscarRyz
28 ноября 2008 в 18:33
7

Может ли кто-нибудь очень просто объяснить мне, что с NIO? Каждый раз, когда читаю об этом, я теряюсь в n-м упоминании канала :(

Henrik Paul
28 ноября 2008 в 18:35
7

помните, что не гарантируется, что разделитель строк в файле не является таким же, как системный разделитель строк.

Deep
12 августа 2011 в 10:29
6

В приведенном выше коде есть ошибка добавления дополнительного символа новой строки в последнюю строку. Это должно быть что-то вроде следующего if (line = reader.readLine ())! = Null) {stringBuilder.append (line); } пока (строка = reader.readLine ())! = ноль) {stringBuilder.append (ls); stringBuilder.append (строка); }

Val
17 января 2012 в 15:20
29

Java 7 представляет byte[] Files.readAllBytes(file); Тем, кто предлагает решение «однострочного» сканера: разве вам не нужно его закрывать?

Bill K
17 марта 2015 в 16:40
0

@OscarRyz Самым большим изменением для меня является то, что NIO позволяет вам прослушивать множество портов, не выделяя каждому потоку. Не проблема, если вы не хотите отправить пакет на каждую машину в сетевом адресном пространстве класса B (65 тыс. Адресов), чтобы увидеть, что существует, в Windows заканчиваются потоки примерно на 20 тыс. сеть класса A / B, до NIO было тяжело).

Rajesh Goel
5 июня 2017 в 23:41
0

Если вы видите реализацию Files.readAllBytes (), вы заметите, что она использует закрываемый канал. Так что не нужно закрывать его явно.

Piko
2 августа 2017 в 19:12
0

С появлением Groovy вы можете читать файл таким образом: return new File (file) .text ()

Love Bisaria
14 ноября 2017 в 01:26
0

Связывание другой ссылки StackOverflow, находка которой хорошо объяснена: coderhelper.com/questions/14169661/…

user207421
7 февраля 2019 в 23:37
0

@Deep Последняя строка в текстовом файле обычно заканчивается строкой, поэтому то, что вы описываете как ошибка, не является ошибкой, и в вашем коде есть ошибка удаления всех ограничителей строки.

Alan
19 июля 2021 в 10:10
0

Пожалуйста, примите ответ на свой вопрос и помогите решить эту проблему.

Ответы (33)

avatar
erickson
28 ноября 2008 в 18:56
1689

Прочитать весь текст из файла

В Java 11 добавлен метод readString () для чтения небольших файлов как String с сохранением разделителей строк:

String content = Files.readString(path, StandardCharsets.US_ASCII);

Для версий между Java 7 и 11, вот компактная и надежная идиома, заключенная в служебный метод:

static String readFile(String path, Charset encoding)
  throws IOException
{
  byte[] encoded = Files.readAllBytes(Paths.get(path));
  return new String(encoded, encoding);
}

Прочитать строки текста из файла

В Java 7 добавлен удобный метод для чтения файла в виде строк текста,, представленных как List<String>. Этот подход является «с потерями», потому что разделители строк удаляются с конца каждой строки.

List<String> lines = Files.readAllLines(Paths.get(path), encoding);

В Java 8 добавлен метод Files.lines() для создания Stream<String>. Опять же, этот метод с потерями, потому что разделители строк удаляются. Если при чтении файла встречается IOException, он упаковывается в UncheckedIOException, поскольку Stream не принимает лямбда-выражения, которые генерируют проверенные исключения.

try (Stream<String> lines = Files.lines(path, encoding)) {
  lines.forEach(System.out::println);
}

Для этого Stream требуется вызов close(); это плохо задокументировано в API, и я подозреваю, что многие люди даже не замечают, что Stream имеет метод close(). Обязательно используйте блок ARM, как показано.

Если вы работаете с источником, отличным от файла, вы можете вместо этого использовать метод lines() в BufferedReader.

Использование памяти

Первый метод, который сохраняет разрывы строк, может временно потребовать память, в несколько раз превышающую размер файла, потому что на короткое время необработанное содержимое файла (массив байтов) и декодированные символы (каждый из которых составляет 16 битов) даже если файл закодирован как 8 бит) одновременно хранятся в памяти. Безопаснее всего применять к файлам, размер которых, как вы знаете, меньше доступной памяти.

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

Для чтения больших файлов вам понадобится другой дизайн вашей программы, такой, который считывает фрагмент текста из потока, обрабатывает его, а затем переходит к следующему, повторно используя тот же блок памяти фиксированного размера. Здесь «большой» зависит от технических характеристик компьютера. В настоящее время этот порог может составлять несколько гигабайт оперативной памяти. Третий метод с использованием Stream<String> - это один из способов сделать это, если ваши входные «записи» являются отдельными строками. (Использование метода readLine() из BufferedReader является процедурным эквивалентом этого подхода.)

Кодировка символов

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

Класс StandardCharsets определяет некоторые константы для кодировок, необходимых для всех сред выполнения Java:

String content = readFile("test.txt", StandardCharsets.UTF_8);

Платформа по умолчанию доступна из самого Charset класса:

String content = readFile("test.txt", Charset.defaultCharset());

Примечание. Этот ответ в значительной степени заменяет мою версию Java 6. Утилита Java 7 безопасно упрощает код, а старый ответ, в котором использовался сопоставленный байтовый буфер, предотвращал удаление файла, который был прочитан, до тех пор, пока сопоставленный буфер не будет собран сборщиком мусора. Вы можете просмотреть старую версию по ссылке «отредактировано» в этом ответе.

Sébastien Nussbaumer
19 августа 2010 в 15:47
36

Примечание: немного поработав этот код, я обнаружил, что вы не можете надежно удалить файл сразу после его прочтения с помощью этого метода, что в некоторых случаях может быть не проблемой, но не для меня. Может быть, это связано с этой проблемой: bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154? В конце концов я согласился с предложением Джона Скита, который не страдает этой ошибкой. В любом случае, я просто хотел дать информацию другим людям, на всякий случай ...

avatar
Rajesh Kumar
12 июня 2021 в 15:24
0

Вы можете прочитать содержимое файла несколькими способами. Ниже приведены несколько способов чтения содержимого файла

  • BufferedReader
  • Сканер
  • Files.ReadBytes

Использование BufferedReader

try {
            
            File file = new File("C://temp/sample.txt");
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            
            // Converting input stream to buffer reader
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String temp = "";
            StringBuffer textFileContent = new StringBuffer();
            while ((temp = bufferedReader.readLine()) != null) {
                textFileContent.append(temp);
            }
            
            System.out.println(textFileContent);
            // In below line we are closing the bufferReader
            bufferedReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

С помощью сканера

try {
            File file = new File("C:\\temp\\sample.txt");
            
            Scanner scanner = new Scanner(file);
            StringBuffer textFileContent = new StringBuffer();
            while (scanner.hasNextLine()) {
                textFileContent.append(scanner.nextLine());
            }
            System.out.println(textFileContent);
            scanner.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Использование File.ReadBytes

try {
            byte[] encoded = Files.readAllBytes(Paths.get("D:\\workspace\\sample.txt"));
            String s = new String(encoded, StandardCharsets.US_ASCII);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }

Для получения дополнительной информации см. URL-адрес ниже

https://beginnersbug.com/how-to-read-a-file-from-java-with-example/

avatar
OscarRyz
17 ноября 2019 в 10:07
72

Гуава имеет метод, аналогичный методу из Commons IOUtils, который упомянул Вилли аус Рор:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

РЕДАКТИРОВАТЬ от PiggyPiglet
Files#toString устарел и подлежит удалению в октябре 2019 года. Вместо этого используйте Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();

РЕДАКТИРОВАТЬ Оскаром Рейесом

Это (упрощенный) базовый код указанной библиотеки:

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

Изменить (от Jonik): приведенное выше не соответствует исходному коду последних версий Guava. Текущий источник см. В классах Files, CharStreams, ByteSource и CharSource <68194871517719> на сайте CharSource <68194871519820.google.com. пакет.

Mohamed Taher Alrefaie
22 апреля 2013 в 15:42
0

Этот код имеет преобразование от long к int, что может вызвать сумасшедшее поведение с большими файлами. Есть лишние пробелы и где вы закрываете поток ввода?

Jonik
29 декабря 2013 в 13:19
0

@ M-T-A: поток закрыт , обратите внимание на использование Closer в CharSource. Код в ответе не является фактическим текущим источником Guava.

avatar
Nitin
26 октября 2018 в 06:38
3

Пользователь java.nio.Files для чтения всех строк файла.

public String readFile() throws IOException {
        File fileToRead = new File("file path");
        List<String> fileLines = Files.readAllLines(fileToRead.toPath());
        return StringUtils.join(fileLines, StringUtils.EMPTY);
}
avatar
leventov
26 июня 2018 в 14:26
25

Начиная с JDK 11:

String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8
mryan
24 сентября 2018 в 07:49
0

Зачем, ну зачем вводить новые методы, основанные на кодировке по умолчанию в 2018 году?

leventov
24 сентября 2018 в 11:39
2

@mryan этот метод не полагается на системную кодировку по умолчанию. По умолчанию используется UTF-8, это нормально.

mryan
25 сентября 2018 в 13:34
0

@leventov ты прав! как и Files.readAllLines! что делает API файлов не очень совместимым со старыми методами, но это к лучшему :)

avatar
Saikat
21 июня 2018 в 05:46
11

Использование JDK 8 или более поздней версии:

внешние библиотеки не используются

Вы можете создать новый объект String из содержимого файла (используя классы из пакета java.nio.file):

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}
Jean-Christophe Blanchard
29 ноября 2018 в 10:30
0

Дубликат ответа Морица Петерсена, который написал: String content = new String (Files.readAllBytes (Paths.get (filename)), «UTF-8»);

avatar
Yash
29 мая 2018 в 10:09
30

Собраны все возможные способы чтения файла в виде строки с диска или из сети.


  • APACHE - ОБЩИЙ ввод-вывод с использованием классов IOUtils, FileUtils

    static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
    public static String commons_IOUtils( URL url ) throws IOException {
        java.io.InputStream in = url.openStream();
        try {
            return IOUtils.toString( in, encoding );
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    public static String commons_FileUtils( File file ) throws IOException {
        return FileUtils.readFileToString( file, encoding );
        /*List<String> lines = FileUtils.readLines( fileName, encoding );
        return lines.stream().collect( Collectors.joining("\n") );*/
    }
    

  • Java 8 BufferReader с использованием Stream API

    public static String streamURL_Buffer( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
        //List<String> lines = reader.lines().collect( Collectors.toList() );
        return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
    }
    public static String streamFile_Buffer( File file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader( file ) );
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }
    

  • Класс сканера с регулярным выражением \A. что соответствует началу ввода.

    static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
    public static String streamURL_Scanner( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    public static String streamFile_Scanner( File file ) throws IOException {
        Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    

  • Java 7 (java.nio.file.Files.readAllBytes)

    public static String getDiskFile_Java7( File file ) throws IOException {
        byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
        return new String( readAllBytes );
    }
    

  • BufferedReader с использованием InputStreamReader.

    public static String getDiskFile_Lines( File file ) throws IOException {
        StringBuffer text = new StringBuffer();
        FileInputStream fileStream = new FileInputStream( file );
        BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
        for ( String line; (line = br.readLine()) != null; )
            text.append( line + System.lineSeparator() );
        return text.toString();
    }
    

Пример основного метода доступа к вышеуказанным методам.

public static void main(String[] args) throws IOException {
    String fileName = "E:/parametarisation.csv";
    File file = new File( fileName );

    String fileStream = commons_FileUtils( file );
            // guava_DiskFile( file );
            // streamFile_Buffer( file );
            // getDiskFile_Java7( file );
            // getDiskFile_Lines( file );
    System.out.println( " File Over Disk : \n"+ fileStream );


    try {
        String src = "https://code.jquery.com/jquery-3.2.1.js";
        URL url = new URL( src );

        String urlStream = commons_IOUtils( url );
                // guava_ServerFile( url );
                // streamURL_Scanner( url );
                // streamURL_Buffer( url );
        System.out.println( " File Over Network : \n"+ urlStream );
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

@ см.

  • Способы преобразования InputStream в строку

avatar
Muskovets
1 апреля 2018 в 13:34
3

Основываясь на ответе @ erickson, вы можете использовать:

public String readAll(String fileName) throws IOException {
    List<String> lines = Files.readAllLines(new File(fileName).toPath());
    return String.join("\n", lines.toArray(new String[lines.size()]));
}
avatar
Malcolm Boekhoff
15 марта 2017 в 02:39
2

В одной строке (Java 8), если у вас есть Reader:

String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));
avatar
OscarRyz
15 февраля 2017 в 21:15
2

Также, если ваш файл оказался внутри банки, вы также можете использовать это:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

Путь должен начинаться с /, например, если ваш jar-файл

my.jar/com/some/thing/a.txt

Затем вы хотите вызвать его следующим образом:

String myTxt = fromFileInJar("/com/com/thing/a.txt");
avatar
jamesjara
7 февраля 2017 в 06:10
3

Вы можете попробовать класс Scanner and File, решение из нескольких строк

 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}
avatar
Devram Kandhare
16 января 2017 в 06:53
0

Используйте код:

File file = new File("input.txt");
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(
                file));
byte[] buffer = new byte[(int) file.length()];
bin.read(buffer);
String fileStr = new String(buffer);

fileStr содержит вывод в виде строки.

avatar
satnam
10 декабря 2016 в 15:55
2

Используя эту библиотеку, это одна строка:

String data = IO.from(new File("data.txt")).toString();
Ari
1 августа 2017 в 02:13
1

если не учитываются строки внутри библиотеки.

avatar
user2058603
6 декабря 2016 в 12:00
-2

в java 8 появился новый класс

java.util.stream.Stream

Поток представляет последовательность элементов и поддерживает различные типы операций для выполнения вычислений над этими элементами

Подробнее об этом:

Документация Oracle

Вот пример:

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public Class ReadFile{
  public  static String readFile(String filePath) {
 StringBuilder  stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");
        try {

            try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
                for (String line : (Iterable<String>) lines::iterator) {


                      stringBuilder.append(line);
                      stringBuilder.append(ls);


                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

      return stringBuilder.toString(); 


}

}
avatar
J J
28 октября 2016 в 07:04
144
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);

начиная с java 7 вы можете сделать это таким образом.

avatar
Moritz Petersen
19 апреля 2016 в 16:39
16

В Java 7 я предпочитаю читать файл UTF-8:

String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");

Начиная с Java 7, JDK имеет новый API java.nio.file, который предоставляет множество ярлыков, поэтому сторонние библиотеки не всегда требуются для простых операций с файлами.

avatar
Haakon Løtveit
29 ноября 2015 в 14:09
2

После нажатия Ctrl + F после Scanner, я думаю, что решение Scanner тоже должно быть указано. В наиболее удобном для чтения виде это выглядит так:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z means EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

Если вы используете Java 7 или новее (а вам действительно стоит), подумайте об использовании try-with-resources, чтобы упростить чтение кода. Больше никаких беспорядков, засоряющих все вокруг. Но, я думаю, это в основном стилистический выбор.

Я публикую это в основном для завершения, поскольку, если вам нужно делать это много, в java.nio.file.Files должны быть вещи, которые должны работать лучше.

Я предлагаю использовать Files # readAllBytes (Path), чтобы захватить все байты и передать их в новую String (byte [] Charset) для получения строки. того, чему вы можете доверять. Кодировки будут значить для вас всю жизнь, так что остерегайтесь этих вещей сейчас.

Другие дали код и прочее, и я не хочу украсть их славу. ;)

avatar
Ilya Gazman
6 января 2015 в 18:52
7

Если у вас нет доступа к классу Files, вы можете использовать собственное решение.

static String readFile(File file, String charset)
        throws IOException
{
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[fileInputStream.available()];
    int length = fileInputStream.read(buffer);
    fileInputStream.close();
    return new String(buffer, 0, length, charset);
}
Thufir
30 декабря 2018 в 08:48
0

пример кодировки для вызова?

avatar
Andrei N
29 октября 2014 в 08:51
52

Если вам нужна обработка строк (параллельная обработка), в Java 8 есть отличный Stream API.

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // for parallel processing 
                    .map(String::trim) // to change line   
                    .filter(line -> line.length() > 2) // to filter some lines by a predicate                        
                    .collect(Collectors.joining()); // to join lines

Дополнительные примеры доступны в образцах JDK sample/lambda/BulkDataOperations, которые можно загрузить с страницы загрузки Oracle Java SE 8

Еще один пример вкладыша

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));
avatar
Ajk
13 декабря 2013 в 09:33
2

Я пока не могу комментировать другие записи, поэтому просто оставлю их здесь.

Один из лучших ответов здесь (https://coderhelper.com/a/326448/1521167):

private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}

все еще имеет один недостаток. Он всегда помещает символ новой строки в конец строки, что может вызвать некоторые странные ошибки. Я предлагаю изменить его на:

    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}
Patrick Parker
28 марта 2018 в 13:46
0

В первом случае вы могли бы добавить в конце лишнюю новую строку. во втором случае вы можете пропустить один. Так что оба одинаково неправы. См. эту статью

avatar
Henry
15 марта 2013 в 09:09
3

Имейте в виду, что при использовании fileInputStream.available() возвращаемое целое число не должно представлять фактический размер файла, а скорее предполагаемое количество байтов, которое система должна иметь возможность читать из потока без блокировки ввода-вывода. Безопасный и простой способ может выглядеть так:

public String readStringFromInputStream(FileInputStream fileInputStream) {
    StringBuffer stringBuffer = new StringBuffer();
    try {
        byte[] buffer;
        while (fileInputStream.available() > 0) {
            buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            stringBuffer.append(new String(buffer, "ISO-8859-1"));
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) { }
    return stringBuffer.toString();
}

Следует учитывать, что этот подход не подходит для многобайтовых кодировок символов, таких как UTF-8.

wau
15 марта 2013 в 13:32
1

Этот код может дать непредсказуемые результаты. Согласно документации метода available(), нет гарантии, что конец файла будет достигнут в случае, если метод вернет 0. В этом случае вы можете получить неполный файл. Что еще хуже, количество фактически прочитанных байтов может быть меньше, чем значение, возвращаемое available(), и в этом случае вы получите искаженный вывод.

avatar
user590444
16 апреля 2012 в 14:33
57
import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }
assafmo
6 апреля 2013 в 12:09
13

или new String(Files.readAllBytes(Paths.get(filename))); :-)

avatar
wau
15 февраля 2012 в 10:47
4

Гибкое решение, использующее IOUtils из Apache commons-io в сочетании с StringWriter <830>: <44038>

Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
  IOUtils.copy(input, output);
} finally {
  input.close();
}
String fileContents = output.toString();

Он работает с любым устройством чтения или входным потоком (не только с файлами), например, при чтении с URL-адреса.

avatar
barjak
23 октября 2011 в 07:43
3

В этом используется метод RandomAccessFile.readFully, похоже, он доступен из JDK 1.0!

public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 


private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}
avatar
Home in Time
17 октября 2011 в 15:34
26

Если это текстовый файл, почему бы не использовать apache commons-io?

Он имеет следующий метод

public static String readFileToString(File file) throws IOException

Если вы хотите, чтобы строки были списком, используйте

public static List<String> readLines(File file) throws IOException
avatar
Pablo Grisafi
16 сентября 2011 в 20:02
186

Очень экономичное решение на основе Scanner:

Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

Или, если вы хотите установить кодировку:

Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

Или с блоком try-with-resources, который вызовет для вас scanner.close():

try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}

Помните, что конструктор Scanner может выдавать IOException. И не забудьте импортировать java.io и java.util.

Источник: Блог Пэта Нимейера

Pablo Grisafi
16 сентября 2011 в 20:16
4

\\ A работает, потому что нет "другого начала файла", поэтому вы фактически читаете последний токен ... который также является первым. Никогда не пробовал с \\ Z. Также обратите внимание, что вы можете читать все, что доступно для чтения, например, Files, InputStreams, каналы ... Иногда я использую этот код для чтения из окна отображения eclipse, когда я не уверен, читаю ли я тот или иной файл .. .да, путь к классам меня смущает.

earcam
23 ноября 2012 в 09:43
21

Сканер реализует Closeable (он вызывает close для источника), поэтому, хотя он элегантен, он не должен быть однострочным. Размер буфера по умолчанию - 1024, но Scanner при необходимости увеличит размер (см. Scanner # makeSpace ())

avatar
Peter Lawrey
18 апреля 2010 в 07:34
17

Чтобы прочитать файл как двоичный и преобразовать в конце

public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}
avatar
Scott S. McCoy
8 февраля 2010 в 19:51
3
public static String slurp (final File file)
throws IOException {
    StringBuilder result = new StringBuilder();

    BufferedReader reader = new BufferedReader(new FileReader(file));

    try {
        char[] buf = new char[1024];

        int r = 0;

        while ((r = reader.read(buf)) != -1) {
            result.append(buf, 0, r);
        }
    }
    finally {
        reader.close();
    }

    return result.toString();
}
OscarRyz
9 февраля 2010 в 15:53
0

Я думаю, что это неудобство использования кодировки платформы по умолчанию. +1 все равно :)

ceving
25 июня 2012 в 16:11
7

Мне кажется, что блок finally не знает переменных, определенных в блоке try. javac 1.6.0_21 выдает ошибку cannot find symbol.

mauron85
31 октября 2018 в 09:48
0

Вы хоть раз пробовали свой собственный код? Вы определили читателя в блоке try / catch, поэтому он не будет доступен в блоке finally.

avatar
Dan Dyer
28 ноября 2008 в 20:33
7

Существует вариант той же темы, в которой вместо цикла while используется цикл for, чтобы ограничить область действия строковой переменной. «Лучше» ли это - дело личного вкуса.

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}
Peter Lawrey
18 апреля 2010 в 07:23
3

Это изменит символы новой строки на выбор по умолчанию. Это может быть желательно или непреднамеренно.

Dan Dyer
1 августа 2013 в 20:16
0

Откатил редактирование этого ответа, потому что цель заключалась в том, чтобы сузить область действия переменной line. Редакция объявила это дважды, что было бы ошибкой компиляции.

avatar
Jon Skeet
28 ноября 2008 в 19:56
51

Этот код нормализует разрывы строк, что может быть, а может и не быть тем, что вы действительно хотите сделать.

Вот альтернатива, которая этого не делает и которая (IMO) проще для понимания, чем код NIO (хотя он по-прежнему использует java.nio.charset.Charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}
Bryan Larson
5 июня 2013 в 19:17
1

Простите меня за то, что возродил такой старый комментарий, но вы хотели передать объект String с именем "file" или это должен быть объект File?

Harshal Parekh
10 ноября 2020 в 20:32
1

Отличный ответ. +1. Но этому ответу 12 лет. В Java теперь есть возможность попробовать ресурсы.

avatar
Dónal
28 ноября 2008 в 19:00
80

Если вы ищете альтернативу, не использующую стороннюю библиотеку (например, Commons I / O), вы можете использовать Сканер класс:

private String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());        

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString();
    }
}
avatar
Claudiu
28 ноября 2008 в 18:52
15

Java пытается быть чрезвычайно универсальной и гибкой во всем, что она делает. В результате то, что относительно просто на языке сценариев (ваш код будет заменен на «open(file).read()» в python), намного сложнее. Кажется, нет более короткого способа сделать это, кроме использования внешней библиотеки (например, упомянутого Вилли аус Рора). Ваши варианты:

  • Использовать внешнюю библиотеку.
  • Скопируйте этот код во все свои проекты.
  • Создайте свою собственную мини-библиотеку, содержащую функции, которые вы часто используете.

Ваш лучший выбор, вероятно, второй, так как он имеет наименьшее количество зависимостей.

OscarRyz
28 ноября 2008 в 19:36
4

Ага. Это заставляет язык «высокого» уровня принимать другое значение. Java имеет высокий уровень по сравнению с C, но низкий по сравнению с Python или Ruby.

Dónal
11 мая 2011 в 16:44
3

Согласитесь, что в Java много абстракций высокого уровня, но мало удобных методов.

Thorn
16 апреля 2013 в 20:45
3

Действительно, в Java есть безумное количество способов работы с файлами, и многие из них кажутся сложными. Но это довольно близко к тому, что мы имеем в языках более высокого уровня: byte[] bytes = Files.readAllBytes(someFile.toPath());

avatar
Willi aus Rohr
28 ноября 2008 в 18:44
374

Если вы хотите использовать внешнюю библиотеку, ознакомьтесь с Apache Commons IO (200 КБ JAR). Он содержит метод org.apache.commons.io.FileUtils.readFileToString(), который позволяет вам прочитать весь File в String с помощью одной строки кода.

Пример:

import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;

public String readFile() throws IOException {
    File file = new File("data.txt");
    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}