Я использую идиому ниже в течение некоторого времени. И это, кажется, самый распространенный, по крайней мере, на сайтах, которые я посетил.
Есть ли лучший / другой способ прочитать файл в строку в 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();
}
}
byte[] Files.readAllBytes(file);
теми, кто предлагает «однострочное» решение для сканера: не нужно ли его закрывать?Ответы:
Читать весь текст из файла
Java 11 добавила метод readString () для чтения небольших файлов как
String
сохраняющих ограничители строки:Для версий между Java 7 и 11 вот компактная и надежная идиома, заключенная в служебный метод:
Читать строки текста из файла
В Java 7 добавлен удобный метод для чтения файла в виде строк текста, представленных как
List<String>
. Этот подход «с потерями», потому что разделители строк удаляются с конца каждой строки.Java 8 добавил
Files.lines()
метод для созданияStream<String>
. Опять же, этот метод с потерями, потому что разделители строк удалены. ЕслиIOException
при чтении файла встречается an, он оборачивается вUncheckedIOException
, такStream
как не принимает лямбда-выражения, которые выдают проверенные исключения.Это
Stream
действительно нужноclose()
позвонить; это плохо документировано в API, и я подозреваю, что многие люди даже не замечают, что уStream
него естьclose()
метод. Обязательно используйте ARM-блок, как показано на рисунке.Если вы работаете с источником, отличным от файла, вы можете использовать
lines()
методBufferedReader
вместо.Использование памяти
Первый метод, который сохраняет разрывы строк, может временно требовать памяти в несколько раз больше размера файла, потому что в течение короткого времени сырое содержимое файла (байтовый массив) и декодированные символы (каждый из которых составляет 16 бит, даже если они закодированы) как 8 бит в файле) находятся в памяти одновременно. Безопаснее всего применять файлы, которые, как вы знаете, имеют небольшой размер относительно доступной памяти.
Второй метод, чтение строк, обычно более эффективен для использования памяти, поскольку входной буфер байтов для декодирования не должен содержать весь файл. Тем не менее, он все еще не подходит для файлов, которые очень велики по отношению к доступной памяти.
Для чтения больших файлов вам понадобится другой дизайн вашей программы, который читает фрагмент текста из потока, обрабатывает его, а затем переходит к следующему, повторно используя тот же блок памяти фиксированного размера. Здесь «большой» зависит от технических характеристик компьютера. В настоящее время этот порог может составлять много гигабайт оперативной памяти. Третий метод, использующий a,
Stream<String>
является одним из способов сделать это, если ваши входные «записи» оказываются отдельными строками. (ИспользованиеreadLine()
методаBufferedReader
является процедурным эквивалентом этого подхода.)Кодировка символов
Одна вещь, которая отсутствует в образце в оригинальном посте, это кодировка символов. В некоторых особых случаях платформа по умолчанию - это то, что вам нужно, но они редки, и вы должны быть в состоянии оправдать свой выбор.
StandardCharsets
Класс определить некоторые константы для кодирования требуемого всех сред выполнения Java:Платформа по умолчанию доступна из самого
Charset
класса :Примечание. Этот ответ во многом заменяет мою версию Java 6. Утилита Java 7 безопасно упрощает код, а старый ответ, в котором используется сопоставленный байтовый буфер, предотвращает удаление прочитанного файла до тех пор, пока сопоставленный буфер не будет очищен от мусора. Вы можете просмотреть старую версию по "отредактированной" ссылке на этот ответ.
источник
FileChannel#map
, в общем, это непригодно для использования.Если вы хотите использовать внешнюю библиотеку, обратитесь к Apache Commons IO (JAR на 200 КБ). Он содержит
org.apache.commons.io.FileUtils.readFileToString()
метод, который позволяет вам читать всеFile
вString
одну строку кода.Пример:
источник
Очень бережливое решение, основанное на
Scanner
:Или, если вы хотите установить кодировку:
Или с помощью блока try-with-resources , который будет вызывать
scanner.close()
вас:Помните, что
Scanner
конструктор может броситьIOException
. И не забудьте импортироватьjava.io
иjava.util
.Источник: блог Пэт Нимейер
источник
java.util.NoSuchElementException
.начиная с Java 7 вы можете сделать это таким образом.
источник
Если вы ищете альтернативу, не включающую стороннюю библиотеку (например, ввод / вывод Commons ), вы можете использовать класс Scanner :
источник
Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(file)));
. В противном случае вы можете захватить только часть файла.У Guava есть метод, похожий на метод из Commons IOUtils, о котором упоминал Вилли аус Рор:
EDIT от PiggyPiglet
Files#toString
устарел и подлежит удалению Octobor 2019. Вместо этого используйтеFiles.asCharSource(new File(path), StandardCharsets.UTF_8).read();
РЕДАКТИРОВАТЬ Оскар Рейес
Это (упрощенный) базовый код в цитируемой библиотеке:
Редактировать (от Jonik): Выше не соответствует исходному коду последних версий Guava. Текущий источник см. В классах Files , CharStreams , ByteSource и CharSource в пакете com.google.common.io .
источник
Closer
в CharSource . Код в ответе не является действительным, текущим источником Guava........
источник
new String(Files.readAllBytes(FileSystems.getDefault().getPath( filename)));
new String(Files.readAllBytes(Paths.get(filename)));
:-)Paths
Гуглинг , по-видимому, 1,7+ как естьFileSystems
. (ЧертЕсли вам нужна обработка строк (параллельная обработка), в Java 8 есть отличный API-интерфейс Stream.
Дополнительные примеры доступны в примерах JDK,
sample/lambda/BulkDataOperations
которые можно загрузить со страницы загрузки Oracle Java SE 8.Еще один пример лайнера
источник
Этот код нормализует разрывы строк, что может или не может быть тем, что вы действительно хотите сделать.
Вот альтернатива, которая этого не делает и которая (IMO) проще для понимания, чем код NIO (хотя она все еще использует
java.nio.charset.Charset
):источник
Собраны все возможные способы чтения файла как строки с диска или сети.
Гуава: Google использует классы
Resources
,Files
APACHE - ОБЩИЙ IO с использованием классов IOUtils, FileUtils
Java 8 BufferReader с использованием Stream API
Класс сканера с регулярным выражением
\A
. который соответствует началу ввода.Java 7 (
java.nio.file.Files.readAllBytes
)BufferedReader
используяInputStreamReader
.Пример с основным методом для доступа к вышеуказанным методам.
@видеть
источник
Если это текстовый файл, почему бы не использовать apache commons-io ?
Имеет следующий метод
Если вы хотите, чтобы строки были списком, используйте
источник
С JDK 11:
источник
Чтобы прочитать файл в двоичном виде и конвертировать в конце
источник
В Java 7 это мой предпочтительный вариант для чтения файла UTF-8:
Начиная с Java 7, JDK имеет новый
java.nio.file
API, который предоставляет множество ярлыков, поэтому сторонние библиотеки не всегда требуются для простых файловых операций.источник
Java пытается быть чрезвычайно универсальным и гибким во всем, что делает. В результате, что-то относительно простое в языке сценариев (ваш код будет заменен на "
open(file).read()
" в Python) намного сложнее. Кажется, нет более короткого способа сделать это, кроме использования внешней библиотеки (как упомянуто Вилли аус Рор ). Ваши варианты:Ваша лучшая ставка, вероятно, вторая, поскольку она имеет наименьшее количество зависимостей.
источник
byte[] bytes = Files.readAllBytes(someFile.toPath());
Используя JDK 8 или выше:
внешние библиотеки не используются
Вы можете создать новый объект String из содержимого файла (используя классы из
java.nio.file
пакета):источник
Существует вариация на ту же тему, которая использует цикл for вместо цикла while, чтобы ограничить область действия строковой переменной. Является ли это «лучше», это вопрос личного вкуса.
источник
line
переменной. Редактирование объявляло это дважды, что было бы ошибкой компиляции.Если у вас нет доступа к
Files
классу, вы можете использовать нативное решение.источник
Гибкое решение, использующее IOUtils из Apache commons-io в сочетании с StringWriter :
Он работает с любым читателем или входным потоком (не только с файлами), например, при чтении с URL.
источник
Имейте в
fileInputStream.available()
виду, что при использовании возвращенного целого числа не обязательно должен отображаться фактический размер файла, а скорее предполагаемое количество байтов, которое система должна быть в состоянии прочитать из потока без блокировки ввода-вывода. Безопасный и простой способ может выглядеть следующим образомСледует учитывать, что этот подход не подходит для многобайтовых кодировок символов, таких как UTF-8.
источник
available()
методу, нет никакой гарантии , что конец файла достигается в том случае, если метод возвращает 0. В этом случае вы могли бы в конечном итоге с неполным файлом. Что еще хуже, число фактически прочитанных байтов может быть меньше, чем возвращаемое значениеavailable()
, и в этом случае вы получаете искаженный вывод.Этот использует метод
RandomAccessFile.readFully
, кажется, доступен из JDK 1.0!источник
Вы можете попробовать сканер и файл класса, несколько строк решения
источник
Пользователь,
java.nio.Files
чтобы прочитать все строки файла.источник
источник
cannot find symbol
.Я не могу пока комментировать другие записи, поэтому я просто оставлю это здесь.
Один из лучших ответов здесь ( https://stackoverflow.com/a/326448/1521167 ):
все еще имеет один недостаток. Он всегда помещает символ новой строки в конец строки, что может вызвать некоторые странные ошибки. Я предлагаю изменить его на:
источник
После Ctrl + F после «Сканера» я думаю, что решение «Сканер» тоже должно быть в списке. Проще всего читать моды это выглядит так:
Если вы используете Java 7 или новее (и вам действительно следует), рассмотрите возможность использования try-with-resources для облегчения чтения кода. Нет больше мелочей, засоряющих все. Но это в основном стилистический выбор.
Я публикую это в основном для завершения, так как если вам нужно много делать, в java.nio.file.Files должны быть вещи, которые должны работать лучше.
Я бы предложил использовать Files # readAllBytes (Path), чтобы захватить все байты, и передать его в новую String (byte [] Charset), чтобы получить из него строку, которой вы можете доверять. Charsets будет иметь для вас значение во время вашей жизни, так что остерегайтесь этого материала сейчас.
Другие дали код и прочее, и я не хочу красть их славу. ;)
источник
Используя эту библиотеку , это одна строка:
источник
Также, если ваш файл находится внутри фляги, вы также можете использовать это:
Путь должен начинаться,
/
например, если ваша банкаЗатем вы хотите вызвать это так:
источник
В одной строке (Java 8), если у вас есть Reader:
источник
Основываясь на ответе @ erickson`s, вы можете использовать:
источник