Кажется, я вижу постоянный неожиданный конец моего файла. Мой файл содержит сначала пару строк, затем байтовые данные.
Файл содержит несколько разделенных строк, которые мой код читает правильно.
Однако, когда я начинаю читать байты, он ничего не возвращает. Я почти уверен, что это связано со мной с помощью Читателей. Прочитал ли 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
Я видел код другого, который решил именно это.
Он использовал DataInputStream, который может выполнять readLine (хотя и устаревший) и readByte.
Поскольку 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
}
Для чтения всей String
вы должны это сделать:
ArrayList<String> lines = new ArrayList<String>();
while ((line = br.readLine();) != null) {
lines.add(line);
}
а затем вы можете сделать цикл, чтобы разделить каждую строку, или просто сделать то, что вам нужно сделать в течение цикла.
Я рекомендую создать 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
, поэтому мы сможем скопировать его позже.
Вы не можете обернуть InputStream
в BufferedReader
и использовать оба.
В качестве подсказок названия BufferedReader
может читать вперед и буферизовать данные из базового InputStream
который тогда не будет доступен при прямом чтении из базового InputStream
.
Предлагаемое решение - не смешивать текстовые и двоичные данные в одном файле. Они должны храниться в двух отдельных файлах, а затем их можно читать отдельно. Если оставшиеся данные не являются бинарными, вы не должны читать их через InputStream
но через свою обертку BufferedReader
же, как вы читаете первые строки.
#binvox
?