java 从同一个 FileInputStream 读取字符串和二进制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/568616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading Strings and Binary from the same FileInputStream
提问by
I have a file that contains some amount of plain text at the start followed by binary content at the end. The size of the binary content is determined by some one of the plain text lines I read.
我有一个文件,开头包含一定数量的纯文本,结尾是二进制内容。二进制内容的大小由我阅读的一些纯文本行决定。
I was using a BufferedReaderto read the individual lines, however it exposes no methods to refer to read a byte array. The readUTFfor a DataInputStreamdoesnt read all the way to the end of the line, and the readLinemethod is deprecated.
我使用 aBufferedReader来读取各个行,但是它没有公开任何方法来引用读取字节数组。所述readUTF用于DataInputStream犯规读一路到行的结束,并且readLine方法被弃用。
Using the underlying FileInputStreamto read returns empty byte arrays. Any suggestions on how to go about this?
使用底层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;
}
采纳答案by Jon Skeet
If you genuinely have a file (rather than something harder to seek in, e.g. a network stream) then I suggest something like this:
如果您真的有一个文件(而不是更难查找的文件,例如网络流),那么我建议如下:
- Open the file as a FileInputStream
- Wrap it in InputStreamReader and a BufferedReader
- Read the text, so you can find out how much content there is
- Close the BufferedReader (which will close the InputStreamReader which will close the FileInputStream)
- Reopen the file
- Skip to (total file length - binary content length)
- Read the rest of the data as normal
- 将文件作为 FileInputStream 打开
- 将其包装在 InputStreamReader 和 BufferedReader 中
- 阅读文本,以便您了解有多少内容
- 关闭 BufferedReader(这将关闭将关闭 FileInputStream 的 InputStreamReader)
- 重新打开文件
- 跳至(总文件长度 - 二进制内容长度)
- 正常读取其余数据
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.)
你可以只调用mark()在FileInputStream中开始,然后reset()和skip()如果你想避免重新打开文件才能到正确的地方。(我正在寻找一个,InputStream.seek()但我看不到一个 - 我不记得以前在 Java 中想要它,但它真的没有吗?哎呀。)
回答by Zach Scrivena
You could use RandomAccessFile. Use readLine()to read the plain text at the start (note the limitations of this, as described in the API), and then readByte()or readFully()to read the subsequent binary data.
你可以使用RandomAccessFile. 用于readLine()在开始时读取纯文本(注意这里的限制,如 API 中所述),然后readByte()或readFully()读取后续的二进制数据。
Using the underlying
FileInputStreamto read returns empty byte arrays.
使用底层
FileInputStream读取返回空字节数组。
That's because you have wrapped the stream in a BufferedReader, which has probably consumed all the bytes from the stream when filling up its buffer.
那是因为您已将流包装在 a 中BufferedReader,这可能在填充其缓冲区时消耗了流中的所有字节。
回答by Lawrence Dol
You need to use an InputStream. Readers are for character data. Look into wrapping your input stream with a DataInputStream, like:
您需要使用 InputStream。读取器用于字符数据。考虑使用 DataInputStream 包装您的输入流,例如:
stream=new DataInputStream(new BufferedInputStream(new FileInputStream(...)));
The data input stream will give you many useful methods to read various types of data, and of course, the base InputStream methods for reading bytes.
数据输入流将为您提供许多有用的方法来读取各种类型的数据,当然还有用于读取字节的基本 InputStream 方法。
(This is actually exactly what a HTTP server must do to read a request with content.)
(这实际上正是 HTTP 服务器读取带有内容的请求所必须执行的操作。)
The readUTF doesn't read a line, it reads a string that was written in (modified) UTF8 format - refer to the JavaDoc.
readUTF 不读取一行,它读取以(修改后的)UTF8 格式编写的字符串 - 请参阅 JavaDoc。
回答by akuhn
Alas, DataInputStreamis deprecated and does not handle UTF. But this should help (it reads a line from a binary stream, without any lookahead).
唉,DataInputStream已被弃用且不处理 UTF。但这应该有帮助(它从二进制流中读取一行,没有任何前瞻)。
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");
}
回答by kgiannakakis
I recommend using DataInputStream. You have the following options:
我建议使用DataInputStream。您有以下选择:
- Read both text and binary content with DataInputStream
- Open a BufferedReader, read text and close the stream. Then open a DataInputStream, skip bytes equal to the size of the text and read binary data.
- 使用 DataInputStream 读取文本和二进制内容
- 打开 BufferedReader,读取文本并关闭流。然后打开一个DataInputStream,跳过等于文本大小的字节并读取二进制数据。
回答by Peter Lawrey
You can read the text with BufferedReader. When you know where the binary starts you can close the file and open it with RandomAccessFile and read binary from any point in the file. Or you can read the file as binary and convert to text the sections you identify as text. {Using new String(bytes, encoding)}
您可以使用 BufferedReader 阅读文本。当您知道二进制文件的开始位置时,您可以关闭文件并使用 RandomAccessFile 打开它并从文件中的任何位置读取二进制文件。或者,您可以将文件作为二进制文件读取,并将您标识为文本的部分转换为文本。{使用新的字符串(字节,编码)}
回答by Nick Fortescue
The correct way is to use an InputStream of some form, probably a FileInputStream unless this becomes a performance barrier.
正确的方法是使用某种形式的 InputStream,可能是 FileInputStream,除非这成为性能障碍。
What do you mean "Using the underlying FileInputStream to read returns empty byte arrays."? This seems very unlikely and is probably where your mistake is. Can you show us the example code you've tried?
“使用底层 FileInputStream 读取返回空字节数组”是什么意思?这似乎不太可能,并且可能是您的错误所在。你能告诉我们你试过的示例代码吗?

