【问题标题】:Reading/writing a BINARY File with Strings?用字符串读/写二进制文件?
【发布时间】:2012-07-20 17:54:06
【问题描述】:

如何从二进制文件中写入/读取字符串?

我尝试过使用 writeUTF / readUTF (DataOutputStream/DataInputStream),但太麻烦了。

谢谢。

【问题讨论】:

  • 如果您使用的是 Java 7,请查看新的 Files 类。
  • 让我羡慕,但是 Java 7 让我与许多旧程序不兼容,我宁愿换一种方式。
  • 向我们展示您迄今为止所做的尝试以及您遇到的错误/问题。
  • java.io.UTFDataFormatException: 使用 readUTF 时字节 17 左右的输入格式错误

标签: java string binary datainputstream dataoutputstream


【解决方案1】:

暂时忘记 FileWriter、DataOutputStream。

  • 对于二进制数据,使用OutputStreamInputStream 类。他们处理byte[]
  • 对于文本数据,使用ReaderWriter 类。他们处理 String 可以存储所有类型的文本,因为它在内部使用 Unicode。

文本到二进制数据的交叉可以通过指定编码来完成,默认为OS编码。

  • new OutputStreamWriter(outputStream, encoding)
  • string.getBytes(encoding)

因此,如果您想避免使用byte[] 并使用字符串,则必须滥用以任何顺序覆盖所有 256 字节值的编码。所以没有“UTF-8”,但可能是“windows-1252”(也称为“Cp1252”)。

但内部存在转换,在极少数情况下可能会出现问题。例如 é 在 Unicode 中可以是一个或两个代码,e + 组合变音符号右重音 '。有一个转换函数(java.text.Normalizer)。

这已经导致问题的一种情况是不同操作系统中的文件名; MacOS 比 Windows 有另一个 Unicode 规范化,因此在版本控制系统中需要特别注意。

所以原则上最好使用更繁琐的字节数组,或者 ByteArrayInputStream,或者 java.nio 缓冲区。还要注意 String chars 是 16 位的。

【讨论】:

    【解决方案2】:

    如果你想写文本,你可以使用 Writers 和 Readers。

    您可以使用 Data*Stream writeUTF/readUTF,但字符串长度必须少于 64K 个字符。


    public static void main(String... args) throws IOException {
        // generate a million random words.
        List<String> words = new ArrayList<String>();
        for (int i = 0; i < 1000000; i++)
            words.add(Long.toHexString(System.nanoTime()));
    
        writeStrings("words", words);
        List<String> words2 = readWords("words");
        System.out.println("Words are the same is " + words.equals(words2));
    }
    
    public static List<String> readWords(String filename) throws IOException {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
        int count = dis.readInt();
        List<String> words = new ArrayList<String>(count);
        while (words.size() < count)
            words.add(dis.readUTF());
        return words;
    }
    
    public static void writeStrings(String filename, List<String> words) throws IOException {
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
        dos.writeInt(words.size());
        for (String word : words)
            dos.writeUTF(word);
        dos.close();
    }
    

    打印

    Words are the same is true
    

    【讨论】:

    • 我已经在使用 writeUTF/readUTF - 这太麻烦了。我有没有提到我想从二进制文件而不是纯文本中读取/写入?抱歉...编辑了主帖
    • 我无法想象比使用 writeUTF/readUTF 更简单的事情了。没有看到你的代码,我无法想象是什么导致你的麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    相关资源
    最近更新 更多