6

我想知道如果我们假设文件大小大于内存,你如何在 Java 中操作大文本文件。我用谷歌搜索了那个主题,它表明大多数人都推荐java.nio这样的任务。

不幸的是,我还没有找到任何关于如何操作文件的文档。例如读取每一行,修改它,写它。我尝试过这样的事情,但这不起作用:

    FileChannel fileChannel = null;
    try {
        fileChannel = new RandomAccessFile(file, "rw").getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(256);

        while (fileChannel.read(buffer) != -1) {
            buffer.rewind();
            buffer.flip();
            String nextLine = buffer.asCharBuffer().toString();
            if (replaceBackSlashes) {
                nextLine = nextLine.replace("\\\\", "/");
            }
            if (!(removeEmptyLines && StringUtils.isEmpty(nextLine))) {
                buffer.flip();
                buffer.asCharBuffer().put(nextLine);
            }

            buffer.clear();
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (fileChannel != null) {
            try {
                fileChannel.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

那么你的建议是什么?此外, Stringnextline与我的文件中的任何内容都不匹配。也许我需要设置编码?

4

2 回答 2

8

逐行。像这样的东西...

public static void main(String[] args) throws Exception {

    File someFile = new File("someFile.txt");
    File temp = File.createTempFile(someFile.getName(), null);
    BufferedReader reader = null;
    PrintStream writer = null;

    try {
        reader = new BufferedReader(new FileReader(someFile));
        writer = new PrintStream(temp);

        String line;
        while ((line = reader.readLine())!=null) {
            // manipulate line
            writer.println(line);
        }
    }
    finally {
        if (writer!=null) writer.close();
        if (reader!=null) reader.close();
    }
    if (!someFile.delete()) throw new Exception("Failed to remove " + someFile.getName());
    if (!temp.renameTo(someFile)) throw new Exception("Failed to replace " + someFile.getName());
}
于 2013-01-08T13:19:34.877 回答
2

感谢 xagyg 提供了一个漂亮、干净的答案!以下内容不适合评论:

If you're running Java 7 already, you can save a lot of boilerplate code by using try-with-resources for the processing loop:

File source = ...
File target = ...
try (BufferedReader in = new BufferedReader(new FileReader(source));
     PrintStream out = new PrintStream(target)) {
  String line;
  while ((line = in.readLine()) != null) {
    // manipulate line
    out.println(line);
  }
}
// no catch or finally clause!

No more of that initalize-to-null-try-catch-finally-close-if-not-null mess, Java will take care of that for you now. Less code, less potential to forget or screw up that crucial call to close().

于 2013-01-08T13:35:15.093 回答