我似乎正在意外结束我的档案。我的文件首先包含几个字符串,然后是字节数据。
该文件包含一些单独的字符串,我的代码可以正确读取。
然而,当我开始读取字节时,它什么都不返回。我很确定它与我使用读者有关。 BufferedReader是否读取整个流?如果是这样,我该如何解决?
我已检查过该文件,并且在字符串后确实包含大量数据。
InputStreamReader is = new InputStreamReader(in);
BufferedReader br = new BufferedReader(is);
String line;
{
line = br.readLine();
String split[] = line.split(" ");
if (!split[0].equals("#binvox")) {
ErrorHandler.log("Not a binvox file");
return false;
}
ErrorHandler.log("Binvox version: " + split[1]);
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead, cnt = 0;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
cnt += nRead;
}
buffer.flush();
// cnt is always 0
binvox格式如下:
#binvox 1
dim 64 40 32
translate -3 0 -2
scale 6.434
data
[byte data]
我基本上尝试将以下C代码转换为Java: http://www.cs.princeton.edu/~min/binvox/read_binvox.html
答案 0 :(得分:1)
要阅读整个String
,您应该这样做:
ArrayList<String> lines = new ArrayList<String>();
while ((line = br.readLine();) != null) {
lines.add(line);
}
然后你可以做一个循环来分割每一行,或者只是做你在循环中你必须做的事情。
答案 1 :(得分:1)
正如 icza 已经写了alraedy,你不能创建InputStream
和BufferedReader
以及用户。 BufferedReader
会尽可能多地从InputStream
读取,然后您无法从InputStream
访问您的数据。
你有几种方法可以解决它:
Reader
。自己从InputStream
读取字节并在其上调用new String(bytes)
。
Reader
读取编码数据。我会推荐这个解决方案。这看起来像那样:public byte[] readBytes (Reader in) throws IOException
{
String base64 = in.readLine(); // Note that a Base64-representation never contains \n
byte[] data = Base64.getDecoder().decode(base64);
return data
}
答案 2 :(得分:0)
您无法将InputStream
包裹在BufferedReader
中并使用它们。
正如其名称提示的那样,BufferedReader
可能会提前读取并缓冲来自基础InputStream
的数据,这些数据在直接从基础InputStream
读取时将无法使用。
建议的解决方案不是在一个文件中混合文本和二进制数据。它们应存储在2个单独的文件中,然后可以单独阅读。如果剩余数据不是二进制数据,则不应通过InputStream
读取它们,而应通过包装器BufferedReader
读取它们,就像读取第一行一样。
答案 3 :(得分:0)
我建议创建预先读取一些字节的BinvoxDetectorStream
public class BinvoxDetectorStream extends InputStream {
private InputStream orig;
private byte[] buffer = new byte[4096];
private int buflen;
private int bufpos = 0;
public BinvoxDetectorStream(InputStream in) {
this.orig = new BufferedInputStream(in);
this.buflen = orig.read(this.buffer, 0, this.buffer.length);
}
public BinvoxInfo getBinvoxVersion() {
// creating a reader for the buffered bytes, to read a line, and compare the header
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
BufferedReader rdr = new BufferedReader(new InputStreamReader(bais)));
String line = rdr.readLine();
String split[] = line.split(" ");
if (split[0].equals("#binvox")) {
BinvoxInfo info = new BinvoxInfo();
info.version = split[1];
split = rdr.readLine().split(" ");
[... parse all properties ...]
// seek for "data\r\n" in the buffered data
while(!(bufpos>=6 &&
buffer[bufpos-6] == 'd' &&
buffer[bufpos-5] == 'a' &&
buffer[bufpos-4] == 't' &&
buffer[bufpos-3] == 'a' &&
buffer[bufpos-2] == '\r' &&
buffer[bufpos-1] == '\n') ) {
bufpos++;
}
return info;
}
return null;
}
@Override
public int read() throws IOException {
if(bufpos < buflen) {
return buffer[bufpos++];
}
return orig.read();
}
}
然后,您可以在不触及原始流的情况下检测Binvox版本:
BinvoxDetectorStream bds = new BinvoxDetectorStream(in);
BinvoxInfo info = bds.getBinvoxInfo();
if (info == null) {
return false;
}
...
[moving bytes in the usual way, but using bds!!! ]
这样我们就可以保留bds
中的原始字节,以便我们以后能够复制它。
答案 4 :(得分:0)
我看到别人的代码解决了这个问题。
他/她使用 DataInputStream ,它可以执行 readLine (虽然已弃用)和 readByte 。