当我有要打印的字符数量时,如何计算文本文件的估计大小?

How do I calculate the estimated size of a text file when I have the amount of chars to be printed?

实际上我写了一个 Java 程序,它在 .txt 文件中打印一个大字符串!现在我想知道文件在生成之前有多大。其实我有字符的数量,但我不知道如何计算这个文件的大小。

当你说 "how big the file will be" 时,我假设你指的是文件中存储的字节数。

假设您使用 UTF-8 编码,悲观估计是字符串中字符数的 3 倍,因为它使用 3 字节代码字对一些 Unicode 代码点进行编码。它还使用 4 字节代码字,但这些代码字与 UTF-16 代理项对完全匹配。代理项对由两个 Java 个字符组成,因此它们的字节字符比仅为 2。

如果您的文件仅保留 Unicode 的 ASCII 子集,则估计值等于字符串中的字符数。

要获得 UTF-8 编码的确切字节数,您实际上必须逐个字符地扫描字符串并添加每个特定代码字的大小。您可以参考 Wikipedia page on UTF-8 了解这些尺寸。

据我所知,

Java 并没有让这变得非常容易。我相信你确实必须对所有内容进行编码,但你不需要创建一个大字节数组......你可以使用 CharsetEncoder 将编码保持为 ByteBuffer 以获得长度它编码的每个部分。这是一些示例代码,我相信是正确的...

import java.nio.*;
import java.nio.charset.*;
import java.util.*;

public class Test {
    public static void main(String[] args) {
        String ascii = createString('A', 2500);
        String u00e9 = createString('\u00e9', 2500); // e-acute
        String euro = createString('\u20ac', 2500); // Euro sign
        // 4 UTF-16 code units, 3 Unicode code points
        String surrogatePair = "X\ud800\udc00Y"; 

        System.out.println(getEncodedLength(ascii, StandardCharsets.UTF_8));
        System.out.println(getEncodedLength(ascii, StandardCharsets.UTF_16BE));

        System.out.println(getEncodedLength(u00e9, StandardCharsets.UTF_8));
        System.out.println(getEncodedLength(u00e9, StandardCharsets.UTF_16BE));

        System.out.println(getEncodedLength(euro, StandardCharsets.UTF_8));
        System.out.println(getEncodedLength(euro, StandardCharsets.UTF_16BE));

        System.out.println(getEncodedLength(surrogatePair, StandardCharsets.UTF_8));
        System.out.println(getEncodedLength(surrogatePair, StandardCharsets.UTF_16BE));
    }


    private static String createString(char c, int length) {
        char[] chars = new char[length];
        Arrays.fill(chars, c);
        return new String(chars);
    }

    public static int getEncodedLength(String text, Charset charset) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);        
        CharBuffer charBuffer = CharBuffer.wrap(text);
        CharsetEncoder encoder = charset.newEncoder();

        int length = 0;
        while (encoder.encode(charBuffer, byteBuffer, false) == CoderResult.OVERFLOW) {
            length += byteBuffer.position();
            byteBuffer.clear();
        }

        encoder.encode(charBuffer, byteBuffer, true);
        length += byteBuffer.position();
        return length;
    }
}

输出:

2500
5000
5000
5000
7500
5000
6
8