【问题标题】:Whole text file to a String in Java整个文本文件到Java中的字符串
【发布时间】:2011-04-20 11:10:37
【问题描述】:

Java 是否像 C# 一样具有单行指令来读取文本文件?

我的意思是,在 Java 中有与此等价的东西吗?:

String data = System.IO.File.ReadAllText("path to file");

如果不是...什么是“最佳方式”来做到这一点...?

编辑:
我更喜欢 Java 标准库中的一种方式...我不能使用 3rd 方库..

【问题讨论】:

标签: java file file-io


【解决方案1】:

不在主要 Java 库中,但您可以使用 Guava

String data = Files.asCharSource(new File("path.txt"), Charsets.UTF_8).read();

或者读行:

List<String> lines = Files.readLines( new File("path.txt"), Charsets.UTF_8 );

当然,我确信还有其他 3rd 方库可以同样简单 - 我只是最熟悉 Guava。

【讨论】:

    【解决方案2】:

    apache commons-io 有:

    String str = FileUtils.readFileToString(file, "utf-8");
    

    但是在标准的 java 类中没有这样的实用程序。如果您(出于某种原因)不想要外部库,则必须重新实现它。 Here 是一些例子,你也可以看看 commons-io 或 Guava 是如何实现的。

    【讨论】:

    • 我会使用FileUtils.readFileToString(file,encoding) 版本 - 不妨推荐好习惯!
    【解决方案3】:

    Java 11 使用 Files.readString 添加了对此用例的支持,示例代码:

    Files.readString(Path.of("/your/directory/path/file.txt"));
    

    在 Java 11 之前,标准库的典型方法是这样的:

    public static String readStream(InputStream is) {
        StringBuilder sb = new StringBuilder(512);
        try {
            Reader r = new InputStreamReader(is, "UTF-8");
            int c = 0;
            while ((c = r.read()) != -1) {
                sb.append((char) c);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return sb.toString();
    }
    

    注意事项:

    • 为了从文件中读取文本,请使用 FileInputStream
    • 如果性能很重要并且您正在读取大文件,建议将流包装在 BufferedInputStream 中
    • 调用者应关闭流

    【讨论】:

    • 缓冲阅读器有一个读取行,这比一次读取一个字符要好
    • 如果你使用 BufferedInputStream,它不会有任何区别
    • 这样会将最后一个 (-1) 添加到字符串中。
    • 不,它没有。它在 while 条件下检查 (c != -1)
    • 这真的不酷。由于 while 循环周围的编码不小心,返回字符串总是以 -1 结尾。
    【解决方案4】:

    Java 7 通过 Files 类(不要与 Guava 的 class of the same name 混淆)改进了这种令人遗憾的状况,您可以从文件中获取所有行 - 无需外部库 - 使用:

    List<String> fileLines = Files.readAllLines(path, StandardCharsets.UTF_8);
    

    或成一个字符串:

    String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
    // or equivalently:
    StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(path)));
    

    如果您需要开箱即用的干净 JDK,这非常有用。也就是说,你为什么要编写没有 Guava 的 Java?

    【讨论】:

    • 第二个示例中的路径是 Path 类型,可以使用 var path = Paths.get(filePathAsString); 从字符串中检索到
    • 所有Files方法都使用Path;见java.nio.file packagePaths.get() 只是获取Path 实例的一种方式。
    【解决方案5】:

    不需要外部库。文件内容在转成字符串前会被缓存。

    Path path = FileSystems.getDefault().getPath(directory, filename);
    String fileContent = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
    

    【讨论】:

    • 注意String(byte[], String) 抛出一个UnsupportedEncodingException。您应该更喜欢 String(byte[], Charset) 构造函数以及 StandardCharsets 或 Guava 的 Charsets 中的常量。
    • 这是一个仅代码的答案,您的答案没有提到它需要在将其转换为字符串之前缓冲所有字节(即它的内存效率不是很高)。
    【解决方案6】:

    不需要外部库。文件内容在转成字符串前会被缓存。

      String fileContent="";
      try {
              File f = new File("path2file");
              byte[] bf = new byte[(int)f.length()];
              new FileInputStream(f).read(bf);
              fileContent = new String(bf, "UTF-8");
          } catch (FileNotFoundException e) {
              // handle file not found exception
          } catch (IOException e) {
              // handle IO-exception
          }
    

    【讨论】:

    • 但前提是您从未遵循 I/O 流教程并且不了解如何处理错误,并且如果您想在将所有字符转换为字符串之前将它们复制到缓冲区中。请描述您的答案,仅代码的答案通常不会被投票。
    • 它缺少对流的关闭声明,但除此之外,这个建议的一般原则对于较小的文件很有用。
    【解决方案7】:

    Java 8(没有外部库)中,您可以使用流。此代码读取一个文件,并将所有由 ', ' 分隔的行放入一个字符串中。

    try (Stream<String> lines = Files.lines(myPath)) {
        list = lines.collect(Collectors.joining(", "));
    } catch (IOException e) {
        LOGGER.error("Failed to load file.", e);
    }
    

    【讨论】:

      【解决方案8】:

      这里有 3 种方法可以在一行中读取文本文件,而无需循环。我记录了15 ways to read from a file in Java,这些来自那篇文章。

      请注意,您仍然需要遍历返回的列表,即使读取文件内容的实际调用只需要 1 行,而无需循环。

      1) java.nio.file.Files.readAllLines() - 默认编码

      import java.io.File;
      import java.io.IOException;
      import java.nio.file.Files;
      import java.util.List;
      
      public class ReadFile_Files_ReadAllLines {
        public static void main(String [] pArgs) throws IOException {
          String fileName = "c:\\temp\\sample-10KB.txt";
          File file = new File(fileName);
      
          List  fileLinesList = Files.readAllLines(file.toPath());
      
          for(String line : fileLinesList) {
            System.out.println(line);
          }
        }
      }
      

      2) java.nio.file.Files.readAllLines() - 显式编码

      import java.io.File;
      import java.io.IOException;
      import java.nio.charset.StandardCharsets;
      import java.nio.file.Files;
      import java.util.List;
      
      public class ReadFile_Files_ReadAllLines_Encoding {
        public static void main(String [] pArgs) throws IOException {
          String fileName = "c:\\temp\\sample-10KB.txt";
          File file = new File(fileName);
      
          //use UTF-8 encoding
          List  fileLinesList = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
      
          for(String line : fileLinesList) {
            System.out.println(line);
          }
        }
      }
      

      3) java.nio.file.Files.readAllBytes()

      import java.io.File;
      import java.io.IOException;
      import java.nio.file.Files;
      
      public class ReadFile_Files_ReadAllBytes {
        public static void main(String [] pArgs) throws IOException {
          String fileName = "c:\\temp\\sample-10KB.txt";
          File file = new File(fileName);
      
          byte [] fileBytes = Files.readAllBytes(file.toPath());
          char singleChar;
          for(byte b : fileBytes) {
            singleChar = (char) b;
            System.out.print(singleChar);
          }
        }
      }
      

      【讨论】:

        【解决方案9】:

        使用 JDK/11,您可以使用 Files.readString(Path path)Path 处的完整文件作为字符串读取:

        try {
            String fileContent = Files.readString(Path.of("/foo/bar/gus"));
        } catch (IOException e) {
            // handle exception in i/o
        }
        

        JDK 中的方法文档如下:

        /**
         * Reads all content from a file into a string, decoding from bytes to characters
         * using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
         * The method ensures that the file is closed when all content have been read
         * or an I/O error, or other runtime exception, is thrown.
         *
         * <p> This method is equivalent to:
         * {@code readString(path, StandardCharsets.UTF_8) }
         *
         * @param   path the path to the file
         *
         * @return  a String containing the content read from the file
         *
         * @throws  IOException
         *          if an I/O error occurs reading from the file or a malformed or
         *          unmappable byte sequence is read
         * @throws  OutOfMemoryError
         *          if the file is extremely large, for example larger than {@code 2GB}
         * @throws  SecurityException
         *          In the case of the default provider, and a security manager is
         *          installed, the {@link SecurityManager#checkRead(String) checkRead}
         *          method is invoked to check read access to the file.
         *
         * @since 11
         */
        public static String readString(Path path) throws IOException 
        

        【讨论】:

        • 现在是你可以做到这一点的时候了。我看不出读取行和丢弃行尾编码的意义。
        【解决方案10】:

        如果使用 nullpointer 发布的 JDK 11,它可能已经过时了。如果您有非文件输入流仍然有用

        InputStream inStream = context.getAssets().open(filename);
        Scanner s = new Scanner(inStream).useDelimiter("\\A");
        String string = s.hasNext() ? s.next() : "";
        inStream.close();
        return string;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-28
          • 2011-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          相关资源
          最近更新 更多