无法从二进制文件中读取 - 读取一些 UTF-8 行,一些二进制文件

时间:2021-02-26 14:39:12

标签: java

我有这个代码:

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main  {
    public static void main(String[] args) {
        zero("zero.out");
        System.out.println(zeroRead("zero.out"));
    }

    public static String zeroRead(String name)  {

        try (FileInputStream fos = new FileInputStream(name);
             BufferedInputStream bos = new BufferedInputStream(fos);
             DataInputStream dos = new DataInputStream(bos)) {

            StringBuffer inputLine = new StringBuffer();
            String tmp;
            String s = "";
            while ((tmp = dos.readLine()) != null) {
                inputLine.append(tmp);
                System.out.println(tmp);
            }
            dos.close();
            return s;
        }
        catch (IOException e)  {
            e.printStackTrace();
        }

        return null;
    }


    public static void zero(String name)  {
        File file = new File(name);
        String text = "König" + "\t";

        try (FileOutputStream fos = new FileOutputStream(file);
             BufferedOutputStream bos = new BufferedOutputStream(fos);
             DataOutputStream dos = new DataOutputStream(bos)) {

             dos.write(text.getBytes(StandardCharsets.UTF_8));
             dos.writeInt(50);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

zero() 方法将数据写入文件:字符串以 UTF-8 格式写入,而数字以二进制格式写入。 zeroRead() 从文件中读取数据。

执行 zero() 后的文件如下所示:

enter image description here

这就是 zeroRead() 返回的内容:

enter image description here

如何从文件中读取真实数据 König\t50

1 个答案:

答案 0 :(得分:3)

DataInputStream 的 readLine 方法的 javadoc 几乎是在大喊它不想被使用。你应该注意这个 javadoc:那个方法不好,你不应该使用它。它不进行字符集编码。

如上所述,您的文件格式不可能:您不知道何时停止读取字符串并开始读取二进制数。但是,根据您描述的方式,听起来字符串以换行符结尾,因此,\n 字符。

没有简单的“只是让这个过滤器读取器可用并调用它的 .nextLine,因为它们往往会缓冲。你可以试试这个:

InputStreamReader isr = new InputStreamReader(bos, StandardCharsets.UTF_8);

然而,基本的 readers 没有 readLine 方法,如果你把它包装在一个 BufferedReader 中,它可能会读到最后(那个名字中的“缓冲区”不仅仅用于踢)。您必须手动处理一次获取一个字符的方法,将它们附加到 stringbuilder,以换行符结尾:

StringBuilder out = new StringBuilder();

for (int c = isr.read(); c != -1 && c != '\n'; c = isr.read())
  out.append((char) c);

String line = out.toString();

将完成工作并且不会读取“越过”换行符并吞噬您的二进制数。

相关问题