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

1376

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

Есть ли лучший/другой способ чтения файла в строку на 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();
    }
}
  • 6
    Может кто-нибудь объяснить мне очень просто, что с NIO? Каждый раз, когда я читаю об этом, я теряюсь в упоминании о канале :(
  • 7
    помните, что не гарантируется, что разделитель строк в файле не обязательно такой же, как системный разделитель строк.
Показать ещё 8 комментариев
Теги:
string
file
io
file-io

35 ответов

1273

Читать весь текст из файла

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

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 BufferedReader добавлен новый метод lines() для создания Stream<String>. Если при чтении файла встречается IOException, оно завернуто в UncheckedIOException, так как Stream не принимает lambdas, что исключить проверенные исключения.

try (BufferedReader r = Files.newBufferedReader(path, encoding)) {
  r.lines().forEach(System.out::println);
}

Существует также метод Files.lines(), который делает что-то очень похожее, возвращая Stream<String> напрямую. Но мне это не нравится. Для Stream требуется вызов close(); это плохо документировано в API, и я подозреваю, что многие люди даже не замечают, что Stream имеет метод close(). Таким образом, ваш код будет выглядеть очень похоже, например:

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

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

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

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

  • 0
    Довольно интересно. Что значит канал? Я знаю, что это, чтобы избежать блокировки "поток"? Они могут быть двунаправленными (или я так понял) Но, проще говоря, что они? Можете ли вы уточнить дальше?
  • 0
    Во многих отношениях ReadableByteChannel похож на InputStream, а WritableByteChannel похож на OutputStream. Многие конкретные каналы реализуют оба этих интерфейса, поэтому один объект является двунаправленным. Некоторые каналы (SocketChannel) поддерживают неблокирующий ввод-вывод, но это относится не ко всем каналам.
Показать ещё 24 комментария
293

Commons FileUtils.readFileToString:

public static String readFileToString(File file)
                       throws IOException

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

Параметры:

  • file - файл для чтения, не должен быть null

Возвращает: содержимое файла, никогда не null

Броски:  - IOException - в случае ошибки ввода/вывода

С: Commons IO 1.3.1

Код, используемый (косвенно) этим классом:

IOUtils.java под Apache License 2.0.

public static long copyLarge(InputStream input, OutputStream output)
       throws IOException {
   byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
   long count = 0;
   int n = 0;
   while (-1 != (n = input.read(buffer))) {
       output.write(buffer, 0, n);
       count += n;
   }
   return count;
}

Он очень похож на тот, который используется Ritche_W.

  • 0
    Я не нахожу этот метод в URL, который вы предоставляете.
  • 2
    Это в классе org.apache.commons.io.FileUtils
Показать ещё 4 комментария
160

Из эта страница очень худощавое решение:

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

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

  • 2
    \\ A работает, потому что нет «другого начала файла», так что вы фактически прочитали последний токен ... который также является первым. Никогда не пробовал с \\ Z. Также обратите внимание, что вы можете читать все, что доступно для чтения, например Файлы, InputStreams, каналы ... Я иногда использую этот код для чтения из окна отображения затмения, когда я не уверен, что читаю тот или иной файл ... .yes, classpath смущает меня.
  • 1
    Как автор, я могу сказать, что действительно не знаю, правильно ли и когда файл закрыт ... Я никогда не пишу этот файл в рабочем коде, я использую его только для тестирования или отладки.
Показать ещё 5 комментариев
70
import java.nio.file.Files;
import java.nio.file.Paths;

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

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

  • 0
    Это должно быть принято как ответ - одна строка, никаких внешних библиотек.
  • 2
    Следует упомянуть необходимые импортные данные: import java.nio.file.Files; импорт java.nio.file.Paths;
Показать ещё 1 комментарий
70

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

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();
    }
}
  • 2
    Я думаю, что это лучший способ. Проверьте java.sun.com/docs/books/tutorial/essential/io/scanning.html
  • 3
    Конструктор Scanner, принимающий строку, обрабатывает строку не как имя файла для чтения, а как текст для сканирования. Я делаю эту ошибку все время. : - /
Показать ещё 5 комментариев
69

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

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

// ...

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

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

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

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 в com.google.common.io.

  • 0
    Этот код имеет приведение типа long к int, что может привести к сумасшедшему поведению с большими файлами. Есть ли дополнительные пробелы и где вы закрываете входной поток?
  • 0
    @MTA: поток закрыт, обратите внимание на использование Closer в CharSource . Код в ответе не является действительным, текущим источником Guava.
53
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 "";
    }
  • 6
    Или еще проще: new String(Files.readAllBytes(FileSystems.getDefault().getPath( filename)));
  • 10
    или new String(Files.readAllBytes(Paths.get(filename))); :-)
Показать ещё 3 комментария
46

Если вам нужна обработка строк (параллельная обработка), у 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, которые можно загрузить с страницы загрузки Java Java SE 8,

Еще один пример liner

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));
  • 0
    Происходит ли .parallel () после того, как вы прочитали строки или до этого?
  • 0
    Реальная работа начинается с момента вызова операции терминала (...). Поток лениво заселяется построчно. Нет необходимости читать весь файл в памяти перед обработкой (например, фильтрация и отображение).
Показать ещё 1 комментарий
45

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

Здесь альтернатива, которая этого не делает, и которая (ИМО) проще понять, чем код 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();
    }        
}
  • 5
    Какой это "тот" код?
  • 7
    Код в вопросе.
Показать ещё 1 комментарий
22

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

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

public static String readFileToString(File file) throws IOException

Если вы хотите, чтобы строки в виде списка использовали

public static List<String> readLines(File file) throws IOException
20

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

  • Гуава: Google использует классы Resources, Files

    static Charset charset = com.google.common.base.Charsets.UTF_8;
    public static String guava_ServerFile( URL url ) throws IOException {
        return Resources.toString( url, charset );
    }
    public static String guava_DiskFile( File file ) throws IOException {
        return Files.toString( file, charset );
    }
    

  • APACHE - ОБЩИЙ IO с использованием классов 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();
    }
}

@увидеть

19

Поскольку 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
  • 5
    После 23 лет ...
  • 0
    Зачем, ну почему, вводить новые методы, основанные на кодировке по умолчанию в 2018 году?
Показать ещё 2 комментария
15

В Java 7 это мой предпочтительный вариант для чтения файла UTF-8:

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

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

15

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

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();
    }
}
  • 1
    Простой и понятный ответ.
14

Java пытается быть чрезвычайно общим и гибким во всем, что он делает. В результате что-то, что относительно просто на языке сценариев (ваш код будет заменен на "open(file).read()" в python) намного сложнее. Кажется, что нет более короткого способа сделать это, за исключением использования внешней библиотеки (например, Willi aus Rohr). Ваши варианты:

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

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

  • 3
    Yeap. Это заставляет язык «высокого уровня» принимать другое значение. Java - высокий уровень по сравнению с C, но низкий по сравнению с Python или Ruby
  • 3
    Согласитесь, что в Java много абстракций высокого уровня, но мало удобных методов
Показать ещё 1 комментарий
7

Использование JDK 8 или выше:

не использовались внешние библиотеки

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

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}
  • 0
    Дубликат ответа Морица Петерсена, который написал: String content = new String (Files.readAllBytes (Paths.get (filename)), "UTF-8");
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);
}
  • 0
    пример кодировки для вызова?
7

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

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}
  • 2
    Это изменит символы новой строки на выбор новой строки по умолчанию. Это может быть желательным или непреднамеренным.
  • 0
    Откатил редактирование этого ответа, потому что целью было сузить область действия переменной line . Редактирование объявило это дважды, что было бы ошибкой компиляции.
5

Однострочное решение

String content = new String(Files.readAllBytes(Paths.get("d://test.txt")));
4

Гибкое решение с использованием IOUtils от Apache commons- io в сочетании с StringWriter:

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

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

3

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

 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}
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.

  • 1
    Этот код может дать непредсказуемые результаты. В соответствии с документацией метода available() нет гарантии, что конец файла достигнут в случае, если метод возвращает 0. В этом случае вы можете получить неполный файл. Что еще хуже, количество фактически прочитанных байтов может быть меньше значения, возвращаемого функцией available() , и в этом случае вы получаете искаженный вывод.
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
        }
    }
}
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();
}
  • 0
    Я думаю, что это создает неудобства при использовании кодировки платформы по умолчанию. +1 все равно :)
  • 7
    Мне кажется, что блок finally не знает переменных, определенных в блоке try. javac 1.6.0_21 выбрасывает ошибку cannot find symbol .
Показать ещё 1 комментарий
2

Пользователь 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);
}
2

Основываясь на ответе @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()]));
}
2

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

String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));
2

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

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

Путь должен начинаться с /, например, если ваша банка

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

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

String myTxt = fromFileInJar("/com/com/thing/a.txt");
2

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

String data = IO.from(new File("data.txt")).toString();
  • 0
    если строки внутри библиотеки не учитываются
2

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

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

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

1

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

Один из лучших ответов здесь (https://stackoverflow.com/questions/326390/how-do-i-create-a-java-string-from-the-contents-of-a-file):

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

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

    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();
    }
}
  • 0
    В первом случае вы можете добавить дополнительную новую строку в конце. во втором случае вы можете пропустить один. Так что оба одинаково неправы. Смотрите эту статью
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 содержит выходные данные в String.

-1
String data=new File("C:/data/datafile.xml").text

Ой, я слишком долго пользуюсь Groovy - но, честно говоря, я так и сделал. Добавление groovy в большинство проектов тривиально, и поскольку код groovy является просто "улучшенной" Java, довольно просто переименовать файл.java в.groovy, а затем добавить строку кода, подобную этой.

Также они добавили байт-код в JVM, чтобы Groovy (и другие динамические языки) могли работать так же быстро, как и Java. Нет большого недостатка в том, чтобы он был доступен.

С другой стороны, вся эта сложность в Java-решении, которое вы разместили, является намеренной. Это заставляет вас задуматься о кодировке символов, окончании строк, переполнении памяти и т.д. На реальном производственном сервере не обрезайте углы, просто сделайте это многословным способом Java - оберните его как служебный метод, и это должно быть так просто, как:

String s=readFile("C:/data/datafile.xml");

и поскольку вы сами написали readFile, вы можете обрабатывать такие вещи, как разные языки и огромные файлы, не изменяя КАЖДОЕ место, где вы неправильно использовали какую-либо внешнюю утилиту.

В основном я использую Groovy для инструментов разработчика и простых одноразовых скриптов, которые я просто хочу быстро создать, потому что определенные структуры (например, чтение файла) НЕМНОГО ЛЕГКО и очевидны.

пс. Просто для удовольствия, в Groovy это также работает:

new File("C:/data/datafile.xml").text = "Hello, File"
-1
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
/**
 * A simple example program that reads a text file into a String using Files.lines and stream.
 */
public class ReadTextFileExample {
    public static void main(String[] args) throws IOException {
        String contents = Files.lines(Paths.get("c:\\temp\\testfile.txt")).collect(Collectors.joining("\n"));
        System.out.println(contents);
    }
}
-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(); 


}

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню