如何在java中将文件读入字符串?

Yat*_*oel 27 java

我已经将文件读入String.该文件包含各种名称,每行一个名称.现在的问题是我想在String数组中使用这些名称.

为此我写了以下代码:

String [] names = fileString.split("\n"); // fileString is the string representation of the file
Run Code Online (Sandbox Code Playgroud)

但是我没有得到所需的结果,并且在分割字符串后获得的数组长度为1.这意味着"fileString"没有"\n"字符,但文件中有"\n"字符.

那么如何解决这个问题呢?

Rom*_*las 45

那么使用Apache Commons(Commons IOCommons Lang)呢?

String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '\n');
Run Code Online (Sandbox Code Playgroud)

  • +1 - 用一行代码换取对 Apache Commons IO 和 Lang 的依赖。 (2认同)
  • 请注意,现在这是FileUtils.readFileToString (2认同)

b.r*_*oth 28

问题不在于你如何拆分字符串; 那个位是正确的.

您必须查看如何将文件读取到字符串.你需要这样的东西:

private String readFileAsString(String filePath) throws IOException {
        StringBuffer fileData = new StringBuffer();
        BufferedReader reader = new BufferedReader(
                new FileReader(filePath));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
        }
        reader.close();
        return fileData.toString();
    }
Run Code Online (Sandbox Code Playgroud)

  • 虽然正确我对任何看到这个的人都有一个警告:我不会使用这个确切的代码片段,因为如果抛出IOException,读者永远不会关闭并且可能导致挂起的文件读取器永远不会被垃圾收集在*nix中world意味着你最终会耗尽文件句柄,你的JVM就会崩溃. (8认同)
  • 另一个问题是`FileReader`隐含地接收了默认情况下的任何字符集.中间的"字符串"也是不必要的. (5认同)

Mar*_*cio 17

根据Garrett Rowe和Stan James的建议,您可以使用java.util.Scanner:

try (Scanner s = new Scanner(file).useDelimiter("\\Z")) {
  String contents = s.next();
}
Run Code Online (Sandbox Code Playgroud)

要么

try (Scanner s = new Scanner(file).useDelimiter("\\n")) {
  while(s.hasNext()) {
    String line = s.next();
  }
}
Run Code Online (Sandbox Code Playgroud)

此代码没有外部依赖项.

警告:您应该将charset编码指定为Scanner构造函数的第二个参数.在这个例子中,我使用的是平台的默认值,但这肯定是错误的.

以下是如何使用java.util.Scanner正确的资源和错误处理的示例:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Iterator;

class TestScanner {
  public static void main(String[] args)
    throws FileNotFoundException {
    File file = new File(args[0]);

    System.out.println(getFileContents(file));

    processFileLines(file, new LineProcessor() {
      @Override
      public void process(int lineNumber, String lineContents) {
        System.out.println(lineNumber + ": " + lineContents);
      }
    });
  }

  static String getFileContents(File file)
    throws FileNotFoundException {
    try (Scanner s = new Scanner(file).useDelimiter("\\Z")) {
      return s.next();
    }
  }

  static void processFileLines(File file, LineProcessor lineProcessor)
    throws FileNotFoundException {
    try (Scanner s = new Scanner(file).useDelimiter("\\n")) {
      for (int lineNumber = 1; s.hasNext(); ++lineNumber) {
        lineProcessor.process(lineNumber, s.next());
      }
    }
  }

  static interface LineProcessor {
    void process(int lineNumber, String lineContents);
  }
}
Run Code Online (Sandbox Code Playgroud)


Olu*_*ith 9

特别是我喜欢这个使用此处描述的java.nio.file包.

 String content = new String(Files.readAllBytes(Paths.get("/path/to/file")));
Run Code Online (Sandbox Code Playgroud)

很酷啊!


leo*_*onm 8

您可以将文件读入a List而不是a String,然后转换为数组:

//Setup a BufferedReader here    
List<String> list = new ArrayList<String>();
String line = reader.readLine();
while (line != null) {
  list.add(line);
  line = reader.readLine();
}
String[] arr = list.toArray(new String[0]);
Run Code Online (Sandbox Code Playgroud)

  • 或者甚至把它留作阵列. (2认同)
  • 或者可以完全保留文件 (2认同)

pts*_*pts 5

Java中没有可以读取整个文件的内置方法.所以你有以下选择:

  • 使用非标准的库方法,例如Apache Commons,请参阅romaintaz的答案中的代码示例.
  • 循环一些read方法(例如FileInputStream.read,读取字节,或FileReader.read读取字符;读取预分配的数组).这两个类使用的系统调用,所以你必须要加快他们与bufering(BufferedInputStreamBufferedReader)如果你每次只读取数据量小(比如,小于4096个字节).
  • 绕圈BufferedReader.readLine.存在一个基本问题,即丢弃信息是否存在'\n'文件的末尾 - 例如,它无法将空文件与仅包含换行符的文件区分开来.

我用这个代码:

// charsetName can be null to use the default charset.
public static String readFileAsString(String fileName, String charsetName)
    throws java.io.IOException {
  java.io.InputStream is = new java.io.FileInputStream(fileName);
  try {
    final int bufsize = 4096;
    int available = is.available();
    byte[] data = new byte[available < bufsize ? bufsize : available];
    int used = 0;
    while (true) {
      if (data.length - used < bufsize) {
        byte[] newData = new byte[data.length << 1];
        System.arraycopy(data, 0, newData, 0, used);
        data = newData;
      }
      int got = is.read(data, used, data.length - used);
      if (got <= 0) break;
      used += got;
    }
    return charsetName != null ? new String(data, 0, used, charsetName)
                               : new String(data, 0, used);
  } finally {
    is.close();
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码具有以下优点:

  • 这是正确的:它读取整个文件,而不是丢弃任何字节.
  • 它允许您指定文件使用的字符集(编码).
  • 它很快(无论文件包含多少个换行符).
  • 它不会浪费内存(无论文件包含多少个换行符).