8

我有一个文件,该文件在开头包含一定数量的纯文本,最后是二进制内容。二进制内容的大小由我阅读的一些纯文本行决定。

我使用 aBufferedReader来读取各个行,但是它没有公开任何方法来引用读取字节数组。readUTFfor aDataInputStream不会一直读到行尾,并且该方法readLine已被弃用。

使用底层FileInputStream读取返回空字节数组。关于如何解决这个问题的任何建议?


private DOTDataInfo parseFile(InputStream stream) throws IOException{
DOTDataInfo info = new DOTDataInfo();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
int binSize = 0;
String line;
while((line = reader.readLine()) != null){
    if(line.length() == 0)
        break;
    DOTProperty prop = parseProperty(line);
    info.getProperties().add(prop);
    if(prop.getName().equals("ContentSize"))
        binSize = Integer.parseInt(prop.getValue());
}
byte[] content = new byte[binSize];
stream.read(content); //Its all empty now. If I use a DataInputStream instead, its got the values from the file
return info;
}
4

7 回答 7

5

你可以使用RandomAccessFile. 用于readLine()在开始时读取纯文本(注意此限制,如 API 中所述),然后readByte()readFully()读取后续二进制数据。

使用底层FileInputStream 读取返回空字节数组。

那是因为您已将流包装在 aBufferedReader中,它可能在填充其缓冲区时消耗了流中的所有字节。

于 2009-02-20T07:53:06.283 回答
4

如果您真的有一个文件(而不是更难查找的文件,例如网络流),那么我建议您这样做:

  • 将文件作为 FileInputStream 打开
  • 将其包装在 InputStreamReader 和 BufferedReader 中
  • 阅读文本,这样你就可以知道有多少内容
  • 关闭 BufferedReader(这将关闭 InputStreamReader,这将关闭 FileInputStream)
  • 重新打开文件
  • 跳到(总文件长度 - 二进制内容长度)
  • 正常读取其余数据

You could just call mark() at the start of the FileInputStream and then reset() and skip() to get to the right place if you want to avoid reopening the file. (I was looking for an InputStream.seek() but I can't see one - I can't remember wanting it before in Java, but does it really not have one? Ick.)

于 2009-02-20T08:01:36.527 回答
2

您需要使用 InputStream。阅读器用于字符数据。研究用 DataInputStream 包装您的输入流,例如:

stream=new DataInputStream(new BufferedInputStream(new FileInputStream(...)));

数据输入流将为您提供许多有用的方法来读取各种类型的数据,当然还有用于读取字节的基本 InputStream 方法。

(这实际上正是 HTTP 服务器在读取带有内容的请求时必须做的事情。)


readUTF 不读取一行,它读取以(修改的)UTF8 格式编写的字符串 - 请参阅 JavaDoc。

于 2009-02-20T07:49:10.457 回答
1

Alas, DataInputStream is deprecated and does not handle UTF. But this should help (it reads a line from a binary stream, without any lookahead).

public static String lineFrom(InputStream in) throws IOException {
    byte[] buf = new byte[128];
    int pos = 0;
    for (;;) {
        int ch = in.read();
        if (ch == '\n' || ch < 0) break;
        buf[pos++] = (byte) ch;
        if (pos == buf.length) buf = Arrays.copyOf(buf, pos + 128);
    }
    return new String(Arrays.copyOf(buf, pos), "UTF-8");
}
于 2009-07-31T12:48:31.857 回答
0

正确的方法是使用某种形式的 InputStream,可能是 FileInputStream,除非这会成为性能障碍。

您是什么意思“使用底层 FileInputStream 读取返回空字节数组。”?这似乎不太可能,并且可能是您的错误所在。您能向我们展示您尝试过的示例代码吗?

于 2009-02-20T07:48:45.967 回答
0

您可以使用 BufferedReader 阅读文本。当您知道二进制文件从哪里开始时,您可以关闭文件并使用 RandomAccessFile 打开它并从文件中的任何位置读取二进制文件。或者您可以将文件读取为二进制文件并将您标识为文本的部分转换为文本。{使用新字符串(字节,编码)}

于 2009-02-20T07:49:33.453 回答
0

我建议使用DataInputStream。您有以下选择:

  • 使用 DataInputStream 读取文本和二进制内容
  • 打开 BufferedReader,读取文本并关闭流。然后打开一个DataInputStream,跳过等于文本大小的字节,读取二进制数据。
于 2009-02-20T07:56:39.037 回答