2

我正在将一个可能很长的项目列表写入文件。我正在写的项目是可变长度的。如果生成的文件大小大于 10M,则应将其拆分为多个文件。为了提高性能,我目前正在使用 BufferedWriter,如下所示:

final FileOutputStream fos = new FileOutputStream(file);
final OutputStreamWriter osr = new OutputStreamWriter(fos, "UTF-8");
final BufferedWriter bw = new BufferedWriter(osr);

通过这样做,虽然我无法准确监控我正在编写的文件的大小。我可以经常刷新或删除它,但这当然会对性能产生影响。最好的选择是什么?理想情况下,我希望生成的文件大小尽可能接近 10M 标记。

4

2 回答 2

0

在这种情况下,不要使用 aBufferedWriter而是简单的FileOutputStream(您已经使用过)。写(并检查大小)你的字符串的.getBytes("UTF-8"). 如果需要,您可能必须编写额外的换行符,但这很简单。

这样你就可以提前知道你必须写的大小。

于 2013-06-09T18:54:54.293 回答
0

以下示例使用 Java 7 的try-with-resources 语句;如果您针对的是较早的平台,则必须手动关闭流。

final int MAX_BYTES = 1024 * 1024 * 10;
final int NEWLINE_BYTES = System.getProperty("line.separator")
                                .getBytes("UTF-8").length;
int bytesWritten = 0;
int fileIndex = 0;
while (existsMoreData()) {
    try (
         FileOutputStream fos = new FileOutputStream(
            getFileNameForIndex(fileIndex));
         OutputStreamWriter osr = new OutputStreamWriter(fos, "UTF-8");
         BufferedWriter bw = new BufferedWriter(osr)) {

        String toWrite = getCurrentStringToWrite();
        int bytesOfString = toWrite.getBytes("UTF-8").length;
        if (bytesWritten + bytesOfString + NEWLINE_BYTES > MAX_BYTES
         || bytesWritten == 0 /* if this part > MAX_BYTES */ ) {

            // need to start a new file
            fileIndex++;
            bytesWritten = 0;
            continue; // auto-closed because of try-with-resources
        } else {
            bw.write(toWrite, 0, toWrite.length());
            bw.newLine();
            bytesWritten += bytesOfString + NEWLINE_BYTES;
            incrementDataToWrite();
        }

    } catch (IOException ie) {
        ie.printStackTrace();
    }
}

可能的实现:

String[] data = someLongString.split("\n");
int currentPart = 0;

private boolean existsMoreData() {
    return currentPart + 1 < data.length;
}

private String getCurrentStringToWrite() {
    return data[currentPart];
}

private void incrementDataToWrite() {
    currentPart++;
}

private String getFileNameForIndex(int index) {
    final String BASE_NAME = "/home/codebuddy/somefile";
    return String.format("%s_%s.txt", BASE_NAME, index);
    // equivalent to:
 // return BASE_NAME + "_" + index + ".txt";
}
于 2013-06-09T18:58:41.620 回答