ASCII - это текстовый файл, который вы бы использовали Readersдля чтения. Java также поддерживает чтение из двоичного файла с использованием InputStreams. Если читаемые файлы огромны, вы можете использовать BufferedReaderверхнюю часть FileReaderдля повышения производительности чтения.
Выбор Reader действительно зависит от того, для чего вам нужно содержимое файла. Если файл небольшой (ish) и вам все это нужно, то быстрее (с точки зрения сравнения: 1.8-2x) просто использовать FileReader и читать все (или, по крайней мере, достаточно большие куски). Если вы обрабатываете его построчно, перейдите к BufferedReader.
Влад
3
Будет ли порядок строк сохраняться при использовании «Files.lines (..). ForEach (...)». Насколько я понимаю, после этой операции порядок будет произвольным.
Даниил Шевелев
39
Files.lines(…).forEach(…)не сохраняет порядок строк, но выполняется параллельно, @Dash. Если порядок важен, вы можете использовать Files.lines(…).forEachOrdered(…), который должен сохранить порядок (не проверял, хотя).
Палек
2
@Palec это интересно, но можете ли вы процитировать документы, где написано, что они Files.lines(...).forEach(...)выполняются параллельно? Я думал, что это был только тот случай, когда вы явно делаете поток параллельным, используя Files.lines(...).parallel().forEach(...).
Klitos Kyriacou
3
Моя оригинальная формулировка не пуленепробиваемая, @KlitosKyriacou. Дело в том, что forEachне гарантирует никакой порядок, а причина в простом распараллеливании. Если порядок должен быть сохранен, используйте forEachOrdered.
Палек
687
Мой любимый способ прочитать небольшой файл - это использовать BufferedReader и StringBuilder. Это очень просто и точно (хотя и не особенно эффективно, но достаточно хорошо для большинства случаев):
BufferedReader br =newBufferedReader(newFileReader("file.txt"));try{StringBuilder sb =newStringBuilder();String line = br.readLine();while(line !=null){
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();}String everything = sb.toString();}finally{
br.close();}
Некоторые отмечают, что после Java 7 вы должны использовать функции try-with-resources (то есть автоматического закрытия):
try(BufferedReader br =newBufferedReader(newFileReader("file.txt"))){StringBuilder sb =newStringBuilder();String line = br.readLine();while(line !=null){
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();}String everything = sb.toString();}
Когда я читаю подобные строки, я обычно все равно хочу выполнить некоторую обработку строк для каждой строки, поэтому я перехожу к этой реализации.
Хотя, если я хочу просто прочитать файл в строку, я всегда использую Apache Commons IO с методом класса IOUtils.toString (). Вы можете взглянуть на источник здесь:
try(FileInputStream inputStream =newFileInputStream("foo.txt")){String everything =IOUtils.toString(inputStream);// do something with everything string}
Я сделал небольшую корректировку, чтобы прекратить добавление новой строки (\ n), если достигнута последняя строка. code while (line! = null) {sb.append (line); line = br.readLine (); // Добавлять новую строку можно только тогда, когда curline НЕ является последней строкой .. if (line! = Null) {sb.append ("\ n"); }}code
Рамон Финкен
2
Аналогично Apache Common IO IOUtils # toString () является sun.misc.IOUtils # readFully (), который включен в JRE Sun / Oracle.
gb96
3
Для производительности всегда вызывайте sb.append ('\ n') вместо sb.append ("\ n"), так как символ добавляется в StringBuilder быстрее, чем String
gb96
2
FileReader может выдавать FileNotFoundException, а BufferedRead может выдавать IOException, поэтому вам нужно их перехватить.
или используйте попытку с использованием ресурсов try (FileReader reader = new FileReader (file))
Эрнан Эче
3
Я заметил file.length (), насколько хорошо это работает с файлами utf-16?
Уэйн
5
Этот метод предполагает, что read () заполняет буфер; что число символов равно количеству байтов; что количество байтов помещается в память; и что количество байтов вписывается в целое число. -1
Маркиз Лорн
1
@HermesTrismegistus Я привел четыре причины, почему это неправильно. StefanReich совершенно правильно согласен со мной.
Маркиз Лорн
35
Я должен был сравнить различные способы. Я прокомментирую мои выводы, но, вкратце, самый быстрый способ - это использовать обычный старый BufferedInputStream поверх FileInputStream. Если нужно прочитать много файлов, то три потока сократят общее время выполнения примерно до половины, но добавление большего количества потоков будет постепенно снижать производительность, пока не потребуется три раза больше времени для завершения с двадцатью потоками, чем с одним потоком.
Предполагается, что вы должны прочитать файл и сделать что-то значимое с его содержимым. В примерах здесь читаются строки из журнала и подсчитываются те, которые содержат значения, превышающие определенный порог. Так что я предполагаю, что однострочная Java 8Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";")) не вариант.
Я тестировал на Java 1.8, Windows 7 и на SSD и HDD дисках.
Я написал шесть разных реализаций:
rawParse : используйте BufferedInputStream поверх FileInputStream, а затем обрезайте строки, читая побайтно. Это превосходит любой другой однопоточный подход, но может быть очень неудобно для файлов, не относящихся к ASCII.
lineReaderParse : используйте BufferedReader поверх FileReader, читайте построчно, разбивайте строки, вызывая String.split (). Это примерно на 20% медленнее, чем rawParse.
lineReaderParseParallel : это то же самое, что lineReaderParse, но использует несколько потоков. Это самый быстрый вариант в целом во всех случаях.
nioAsyncParse : используйте AsynchronousFileChannel с обработчиком завершения и пулом потоков.
nioMemoryMappedParse : использовать отображенный в памяти файл. Это действительно плохая идея, которая дает время выполнения, по крайней мере, в три раза больше, чем любая другая реализация.
Это среднее время чтения 204 файлов по 4 МБ каждый на четырехъядерном диске i7 и SSD. Файлы создаются на лету, чтобы избежать кеширования диска.
Я обнаружил разницу, меньшую, чем я ожидал, между работой на SSD или жестком диске, поскольку SSD работает примерно на 15% быстрее. Это может быть связано с тем, что файлы создаются на нефрагментированном жестком диске и считываются последовательно, поэтому вращающийся диск может работать почти как SSD.
Я был удивлен низкой производительностью реализации nioAsyncParse. Либо я реализовал что-то неправильно, либо многопотоковая реализация с использованием NIO и обработчик завершения выполняет то же самое (или даже хуже), чем однопотоковая реализация с API java.io. Более того, асинхронный анализ с CompletionHandler намного длиннее в строках кода и сложен для правильной реализации, чем прямая реализация в старых потоках.
Теперь за шестью реализациями следует класс, содержащий их все, плюс параметризуемый метод main (), который позволяет играть с количеством файлов, размером файла и степенью параллелизма. Обратите внимание, что размер файлов варьируется плюс минус 20%. Это позволяет избежать какого-либо эффекта, поскольку все файлы имеют одинаковый размер.
rawParse
publicvoid rawParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{
overrunCount =0;finalint dl =(int)';';StringBuffer lineBuffer =newStringBuffer(1024);for(int f=0; f<numberOfFiles; f++){File fl =newFile(targetDir+filenamePreffix+String.valueOf(f)+".txt");FileInputStream fin =newFileInputStream(fl);BufferedInputStream bin =newBufferedInputStream(fin);int character;while((character=bin.read())!=-1){if(character==dl){// Here is where something is done with each line
doSomethingWithRawLine(lineBuffer.toString());
lineBuffer.setLength(0);}else{
lineBuffer.append((char) character);}}
bin.close();
fin.close();}}publicfinalvoid doSomethingWithRawLine(String line)throwsParseException{// What to do for each lineint fieldNumber =0;finalint len = line.length();StringBuffer fieldBuffer =newStringBuffer(256);for(int charPos=0; charPos<len; charPos++){char c = line.charAt(charPos);if(c==DL0){String fieldValue = fieldBuffer.toString();if(fieldValue.length()>0){switch(fieldNumber){case0:Date dt = fmt.parse(fieldValue);
fieldNumber++;break;case1:double d =Double.parseDouble(fieldValue);
fieldNumber++;break;case2:int t =Integer.parseInt(fieldValue);
fieldNumber++;break;case3:if(fieldValue.equals("overrun"))
overrunCount++;break;}}
fieldBuffer.setLength(0);}else{
fieldBuffer.append(c);}}}
lineReaderParse
publicvoid lineReaderParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{String line;for(int f=0; f<numberOfFiles; f++){File fl =newFile(targetDir+filenamePreffix+String.valueOf(f)+".txt");FileReader frd =newFileReader(fl);BufferedReader brd =newBufferedReader(frd);while((line=brd.readLine())!=null)
doSomethingWithLine(line);
brd.close();
frd.close();}}publicfinalvoid doSomethingWithLine(String line)throwsParseException{// Example of what to do for each lineString[] fields = line.split(";");Date dt = fmt.parse(fields[0]);double d =Double.parseDouble(fields[1]);int t =Integer.parseInt(fields[2]);if(fields[3].equals("overrun"))
overrunCount++;}
publicvoid nioFilesParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{for(int f=0; f<numberOfFiles; f++){Path ph =Paths.get(targetDir+filenamePreffix+String.valueOf(f)+".txt");Consumer<String> action =newLineConsumer();Stream<String> lines =Files.lines(ph);
lines.forEach(action);
lines.close();}}classLineConsumerimplementsConsumer<String>{@Overridepublicvoid accept(String line){// What to do for each lineString[] fields = line.split(DL);if(fields.length>1){try{Date dt = fmt.parse(fields[0]);}catch(ParseException e){}double d =Double.parseDouble(fields[1]);int t =Integer.parseInt(fields[2]);if(fields[3].equals("overrun"))
overrunCount++;}}}
nioAsyncParse
publicvoid nioAsyncParse(finalString targetDir,finalint numberOfFiles,finalint numberOfThreads,finalint bufferSize)throwsIOException,ParseException,InterruptedException{ScheduledThreadPoolExecutor pool =newScheduledThreadPoolExecutor(numberOfThreads);ConcurrentLinkedQueue<ByteBuffer> byteBuffers =newConcurrentLinkedQueue<ByteBuffer>();for(int b=0; b<numberOfThreads; b++)
byteBuffers.add(ByteBuffer.allocate(bufferSize));for(int f=0; f<numberOfFiles; f++){
consumerThreads.acquire();String fileName = targetDir+filenamePreffix+String.valueOf(f)+".txt";AsynchronousFileChannel channel =AsynchronousFileChannel.open(Paths.get(fileName),EnumSet.of(StandardOpenOption.READ), pool);BufferConsumer consumer =newBufferConsumer(byteBuffers, fileName, bufferSize);
channel.read(consumer.buffer(),0l, channel, consumer);}
consumerThreads.acquire(numberOfThreads);}classBufferConsumerimplementsCompletionHandler<Integer,AsynchronousFileChannel>{privateConcurrentLinkedQueue<ByteBuffer> buffers;privateByteBuffer bytes;privateString file;privateStringBuffer chars;privateint limit;privatelong position;privateDateFormat frmt =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");publicBufferConsumer(ConcurrentLinkedQueue<ByteBuffer> byteBuffers,String fileName,int bufferSize){
buffers = byteBuffers;
bytes = buffers.poll();if(bytes==null)
bytes =ByteBuffer.allocate(bufferSize);
file = fileName;
chars =newStringBuffer(bufferSize);
frmt =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");
limit = bufferSize;
position =0l;}publicByteBuffer buffer(){return bytes;}@Overridepublicsynchronizedvoid completed(Integer result,AsynchronousFileChannel channel){if(result!=-1){
bytes.flip();finalint len = bytes.limit();int i =0;try{for(i =0; i < len; i++){byte by = bytes.get();if(by=='\n'){// ***// The code used to process the line goes here
chars.setLength(0);}else{
chars.append((char) by);}}}catch(Exception x){System.out.println("Caught exception "+ x.getClass().getName()+" "+ x.getMessage()+" i="+String.valueOf(i)+", limit="+String.valueOf(len)+", position="+String.valueOf(position));}if(len==limit){
bytes.clear();
position += len;
channel.read(bytes, position, channel,this);}else{try{
channel.close();}catch(IOException e){}
consumerThreads.release();
bytes.clear();
buffers.add(bytes);}}else{try{
channel.close();}catch(IOException e){}
consumerThreads.release();
bytes.clear();
buffers.add(bytes);}}@Overridepublicvoid failed(Throwable e,AsynchronousFileChannel channel){}};
Или, если вы предпочитаете Guava (более современную, активно поддерживаемую библиотеку), она имеет аналогичные утилиты в своем классе Files . Простые примеры в этом ответе .
Что вы хотите сделать с текстом? Файл достаточно мал, чтобы поместиться в память? Я постараюсь найти самый простой способ обработки файла для ваших нужд. Библиотека FileUtils очень удобна для этого.
@PeterLawrey, вероятно, означает org.apache.commons.io.FileUtils. Ссылка Google может со временем менять контент, поскольку наиболее распространенное значение меняется, но это соответствует его запросу и выглядит правильно.
Палек
2
К сожалению, в наше время нет readLines(String)и readLines(File)не рекомендуется в пользу readLines(File, Charset). Кодировка может быть предоставлена также в виде строки.
Я задокументировал 15 способов чтения файла на Java, а затем проверил их на скорость при различных размерах файлов - от 1 КБ до 1 ГБ, и вот три основных способа сделать это:
import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;BufferedReader br;try{
br =newBufferedReader(newFileReader("/fileToRead.txt"));try{String x;while((x = br.readLine())!=null){// Printing out each line in the fileSystem.out.println(x);}}catch(IOException e){
e.printStackTrace();}}catch(FileNotFoundException e){System.out.println(e);
e.printStackTrace();}
По сути, это то же самое, что и ответ Иисуса Рамоса, за исключением того, что File вместо FileReader плюс итерация для просмотра содержимого файла.
Scanner in =newScanner(newFile("filename.txt"));while(in.hasNext()){// Iterates each line in the fileString line = in.nextLine();// Do something with line}
in.close();// Don't forget to close resource leaks
File vs FileReader. При использовании FileReader файл должен существовать, а разрешения операционной системы должны разрешать доступ. С файлом можно проверить эти разрешения или проверить, является ли файл каталогом. Файл имеет полезные функции: isFile (), isDirectory (), listFiles (), canExecute (), canRead (), canWrite (), exist (), mkdir (), delete (). File.createTempFile () записывает в системный временный каталог по умолчанию. Этот метод возвращает объект файла, который можно использовать для открытия объектов FileOutputStream и т. Д. Source
ThisClark
7
Классы буферизованных потоков на практике гораздо более производительны, настолько, что API NIO.2 включает методы, которые специально возвращают эти классы потоков, отчасти, чтобы поощрять вас всегда использовать буферизованные потоки в вашем приложении.
Вот пример:
Path path =Paths.get("/myfolder/myfile.ext");try(BufferedReader reader =Files.newBufferedReader(path)){// Read from the streamString currentLine =null;while((currentLine = reader.readLine())!=null)//do your code here}catch(IOException e){// Handle file I/O exception...}
Правда, должно быть: if(scanner.hasNext()) content = scanner.next();
Дэвид Сороко
1
Это терпит неудачу для меня на Android 4.4. Только 1024 байта читаются. YMMV.
Роджер Кис
3
Пока я не вижу упоминания в других ответах. Но если «Наилучший» означает скорость, то новый Java I / O (NIO) может обеспечить самое быстрое предварительное выполнение, но не всегда самое простое, чтобы понять его для кого-то, кто изучает.
Это может быть не точный ответ на вопрос. Это просто еще один способ чтения файла, в котором вы не указываете явно путь к вашему файлу в своем Java-коде, а вместо этого вы читаете его как аргумент командной строки.
Я думаю, что readAllBytes быстрее и точнее, потому что он не заменяет новую строку, \nа также может быть новая строка \r\n. Это зависит от ваших потребностей, какой из них подходит.
Вы не можете использовать это на «любой файл, который вы хотите». Вы можете использовать его только для ресурсов, которые были упакованы в файл JAR или WAR.
try{File f =newFile("filename.txt");Scanner r =newScanner(f);while(r.hasNextLine()){String data = r.nextLine();JOptionPane.showMessageDialog(data);}
r.close();}catch(FileNotFoundException ex){JOptionPane.showMessageDialog("Error occurred");
ex.printStackTrace();}
Гораздо быстрее, я сомневаюсь, если вы используете простую конкатенацию строк вместо StringBuilder ...
PhiLho
6
Я думаю, что основной прирост скорости происходит от чтения в 1 МБ (1024 * 1024) блоков. Однако вы можете сделать то же самое, просто передав 1024 * 1024 в качестве второго аргумента в конструктор BufferedReader.
gb96
3
я не верю, что это проверено на всех. использование +=этого способа дает вам квадратичную (!) сложность для задачи, которая должна быть линейной сложности. начнется сканирование файлов размером более нескольких мегабайт. чтобы обойти это, вы должны либо сохранить текстовые блоки в списке <string>, либо использовать вышеупомянутый построитель строк.
kritzikratzi
5
Гораздо быстрее, чем что? Это, безусловно, не быстрее, чем добавление в StringBuffer. -1
Маркиз Лорн
1
@ gb96 Я тоже думал о размерах буфера, но подробный эксперимент в этом вопросе дал удивительные результаты в аналогичном контексте: буфер 16 КБ был последовательно и заметно быстрее.
chiastic-security
-3
String fileName ='yourFileFullNameWithPath';File file =newFile(fileName);// Creates a new file object for your fileFileReader fr =newFileReader(file);// Creates a Reader that you can use to read the contents of a file read your fileBufferedReader br =newBufferedReader(fr);//Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
Приведенный выше набор строк можно записать в одну строку как:
Ответы:
ASCII - это текстовый файл, который вы бы использовали
Readers
для чтения. Java также поддерживает чтение из двоичного файла с использованиемInputStreams
. Если читаемые файлы огромны, вы можете использоватьBufferedReader
верхнюю частьFileReader
для повышения производительности чтения.Прочтите эту статью о том, как использовать
Reader
Я бы также порекомендовал вам скачать и прочитать эту замечательную (но бесплатную) книгу под названием Thinking In Java
В Java 7 :
(документы) или
(документы)
В Java 8 :
(документы)
источник
Files.lines(…).forEach(…)
не сохраняет порядок строк, но выполняется параллельно, @Dash. Если порядок важен, вы можете использоватьFiles.lines(…).forEachOrdered(…)
, который должен сохранить порядок (не проверял, хотя).Files.lines(...).forEach(...)
выполняются параллельно? Я думал, что это был только тот случай, когда вы явно делаете поток параллельным, используяFiles.lines(...).parallel().forEach(...)
.forEach
не гарантирует никакой порядок, а причина в простом распараллеливании. Если порядок должен быть сохранен, используйтеforEachOrdered
.Мой любимый способ прочитать небольшой файл - это использовать BufferedReader и StringBuilder. Это очень просто и точно (хотя и не особенно эффективно, но достаточно хорошо для большинства случаев):
Некоторые отмечают, что после Java 7 вы должны использовать функции try-with-resources (то есть автоматического закрытия):
Когда я читаю подобные строки, я обычно все равно хочу выполнить некоторую обработку строк для каждой строки, поэтому я перехожу к этой реализации.
Хотя, если я хочу просто прочитать файл в строку, я всегда использую Apache Commons IO с методом класса IOUtils.toString (). Вы можете взглянуть на источник здесь:
http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html
И даже проще с Java 7:
источник
code
while (line! = null) {sb.append (line); line = br.readLine (); // Добавлять новую строку можно только тогда, когда curline НЕ является последней строкой .. if (line! = Null) {sb.append ("\ n"); }}code
Самый простой способ - использовать
Scanner
класс в Java и объект FileReader. Простой пример:Scanner
имеет несколько методов для чтения в строках, числах и т. д. Более подробную информацию вы можете найти на странице документации Java.Например, чтение всего содержимого в
String
:Также, если вам нужна определенная кодировка, вы можете использовать это вместо
FileReader
:источник
BufferedReader
while ((line = br.readLine()) != null) { sb.append(line); }
?Вот простое решение:
источник
Вот еще один способ сделать это без использования внешних библиотек:
источник
Я должен был сравнить различные способы. Я прокомментирую мои выводы, но, вкратце, самый быстрый способ - это использовать обычный старый BufferedInputStream поверх FileInputStream. Если нужно прочитать много файлов, то три потока сократят общее время выполнения примерно до половины, но добавление большего количества потоков будет постепенно снижать производительность, пока не потребуется три раза больше времени для завершения с двадцатью потоками, чем с одним потоком.
Предполагается, что вы должны прочитать файл и сделать что-то значимое с его содержимым. В примерах здесь читаются строки из журнала и подсчитываются те, которые содержат значения, превышающие определенный порог. Так что я предполагаю, что однострочная Java 8
Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";"))
не вариант.Я тестировал на Java 1.8, Windows 7 и на SSD и HDD дисках.
Я написал шесть разных реализаций:
rawParse : используйте BufferedInputStream поверх FileInputStream, а затем обрезайте строки, читая побайтно. Это превосходит любой другой однопоточный подход, но может быть очень неудобно для файлов, не относящихся к ASCII.
lineReaderParse : используйте BufferedReader поверх FileReader, читайте построчно, разбивайте строки, вызывая String.split (). Это примерно на 20% медленнее, чем rawParse.
lineReaderParseParallel : это то же самое, что lineReaderParse, но использует несколько потоков. Это самый быстрый вариант в целом во всех случаях.
nioFilesParse : используйте java.nio.files.Files.lines ()
nioAsyncParse : используйте AsynchronousFileChannel с обработчиком завершения и пулом потоков.
nioMemoryMappedParse : использовать отображенный в памяти файл. Это действительно плохая идея, которая дает время выполнения, по крайней мере, в три раза больше, чем любая другая реализация.
Это среднее время чтения 204 файлов по 4 МБ каждый на четырехъядерном диске i7 и SSD. Файлы создаются на лету, чтобы избежать кеширования диска.
Я обнаружил разницу, меньшую, чем я ожидал, между работой на SSD или жестком диске, поскольку SSD работает примерно на 15% быстрее. Это может быть связано с тем, что файлы создаются на нефрагментированном жестком диске и считываются последовательно, поэтому вращающийся диск может работать почти как SSD.
Я был удивлен низкой производительностью реализации nioAsyncParse. Либо я реализовал что-то неправильно, либо многопотоковая реализация с использованием NIO и обработчик завершения выполняет то же самое (или даже хуже), чем однопотоковая реализация с API java.io. Более того, асинхронный анализ с CompletionHandler намного длиннее в строках кода и сложен для правильной реализации, чем прямая реализация в старых потоках.
Теперь за шестью реализациями следует класс, содержащий их все, плюс параметризуемый метод main (), который позволяет играть с количеством файлов, размером файла и степенью параллелизма. Обратите внимание, что размер файлов варьируется плюс минус 20%. Это позволяет избежать какого-либо эффекта, поскольку все файлы имеют одинаковый размер.
rawParse
lineReaderParse
lineReaderParseParallel
nioFilesParse
nioAsyncParse
ПОЛНАЯ БЕЗОПАСНАЯ РЕАЛИЗАЦИЯ ВСЕХ ДЕЛА
https://github.com/sergiomt/javaiobenchmark/blob/master/FileReadBenchmark.java
источник
Вот три рабочих и проверенных метода:
С помощью
BufferedReader
С помощью
Scanner
С помощью
FileReader
Прочитать весь файл без цикла, используя
Scanner
классисточник
java.nio.file.Files
? Теперь мы можем просто использоватьreadAllLines
,readAllBytes
иlines
.Методы внутри
org.apache.commons.io.FileUtils
могут также быть очень удобными, например:источник
Что вы хотите сделать с текстом? Файл достаточно мал, чтобы поместиться в память? Я постараюсь найти самый простой способ обработки файла для ваших нужд. Библиотека FileUtils очень удобна для этого.
источник
org.apache.commons.io.FileUtils
. Ссылка Google может со временем менять контент, поскольку наиболее распространенное значение меняется, но это соответствует его запросу и выглядит правильно.readLines(String)
иreadLines(File)
не рекомендуется в пользуreadLines(File, Charset)
. Кодировка может быть предоставлена также в виде строки.Я задокументировал 15 способов чтения файла на Java, а затем проверил их на скорость при различных размерах файлов - от 1 КБ до 1 ГБ, и вот три основных способа сделать это:
java.nio.file.Files.readAllBytes()
Проверено на работу в Java 7, 8 и 9.
java.io.BufferedReader.readLine()
Проверено на работу в Java 7, 8, 9.
java.nio.file.Files.lines()
Это было протестировано для работы в Java 8 и 9, но не будет работать в Java 7 из-за требования лямбда-выражения.
источник
Ниже приводится описание того, как сделать это в стиле Java 8. Предполагая, что
text.txt
файл находится в корневом каталоге проекта Eclipse.источник
Использование BufferedReader:
источник
По сути, это то же самое, что и ответ Иисуса Рамоса, за исключением того, что File вместо FileReader плюс итерация для просмотра содержимого файла.
... броски
FileNotFoundException
источник
Классы буферизованных потоков на практике гораздо более производительны, настолько, что API NIO.2 включает методы, которые специально возвращают эти классы потоков, отчасти, чтобы поощрять вас всегда использовать буферизованные потоки в вашем приложении.
Вот пример:
Вы можете заменить этот код
с
Я рекомендую эту статью, чтобы изучить основные способы использования Java NIO и IO.
источник
Вероятно, не так быстро, как с буферизованным вводом / выводом, но довольно кратко:
\Z
Картина рассказывает ,Scanner
что разделитель является EOF.источник
if(scanner.hasNext()) content = scanner.next();
Пока я не вижу упоминания в других ответах. Но если «Наилучший» означает скорость, то новый Java I / O (NIO) может обеспечить самое быстрое предварительное выполнение, но не всегда самое простое, чтобы понять его для кого-то, кто изучает.
http://download.oracle.com/javase/tutorial/essential/io/file.html
источник
Самый простой способ чтения данных из файла в Java - это использование класса File для чтения файла и класса Scanner для чтения содержимого файла.
PS: не забудьте импортировать java.util. *; для работы сканера.
источник
Гуава предоставляет для этого одну строку:
источник
Это может быть не точный ответ на вопрос. Это просто еще один способ чтения файла, в котором вы не указываете явно путь к вашему файлу в своем Java-коде, а вместо этого вы читаете его как аргумент командной строки.
Со следующим кодом,
просто продолжайте и запустите его с:
Это прочитает содержимое
input.txt
и выведет его на вашу консоль.Вы также можете настроить
System.out.println()
запись в определенный файл через командную строку следующим образом:Это будет читать
input.txt
и писатьoutput.txt
.источник
Вы можете использовать readAllLines и
join
метод для получения всего содержимого файла в одну строку:По умолчанию используется кодировка UTF-8, которая правильно читает данные ASCII.
Также вы можете использовать readAllBytes:
Я думаю, что readAllBytes быстрее и точнее, потому что он не заменяет новую строку,
\n
а также может быть новая строка\r\n
. Это зависит от ваших потребностей, какой из них подходит.источник
Для веб-приложений Maven на основе JSF просто используйте ClassLoader и
Resources
папку для чтения в любом файле:Поместите зависимость Apache Commons IO в ваш POM:
Используйте код ниже, чтобы прочитать его (например, ниже читается в файле .json):
Вы можете сделать то же самое для текстовых файлов, файлов .properties, схем XSD и т. Д.
источник
Cactoos дает вам декларативный однострочный:
источник
Используйте Java поцелуй, если речь идет о простоте структуры:
источник
Просто используйте Java 8 Stream.
источник
источник
Наиболее интуитивный метод введен в Java 11
Files.readString
PHP обладает такой роскошью десятилетия назад! ☺
источник
Этот код, который я запрограммировал, намного быстрее для очень больших файлов:
источник
+=
этого способа дает вам квадратичную (!) сложность для задачи, которая должна быть линейной сложности. начнется сканирование файлов размером более нескольких мегабайт. чтобы обойти это, вы должны либо сохранить текстовые блоки в списке <string>, либо использовать вышеупомянутый построитель строк.Приведенный выше набор строк можно записать в одну строку как:
Добавление к строителю строк (если ваш файл огромен, рекомендуется использовать построитель строк, иначе используйте обычный объект String)
источник