下面的代码只解析数据文件一次。我试图让它解析整个文件。每次找到标记时,都会解析数据并将其附加到输出文件中。目前它成功解析数据然后停止。无法弄清楚如何让它循环直到eof。数据是4字节对齐的,并且是在输入二进制文件中。
private static void startParse(File inFile) throws IOException {
boolean markerFound = false;
for (int offset = 0; !markerFound && offset < 4; offset++){
DataInputStream dis = new DataInputStream(new FileInputStream(inFile));
for (int i = 0; i < offset; i++){
dis.read();
}
try {
int integer;
long l;
while((l = (integer = dis.readInt())) != MARKER) {
//Don't do anything
}
markerFound = true;
for (int i = 0; i < 11; i++){
dis.read();
}
// ********************** data **********************
byte[] data = new byte[1016];
for(int i = 0; i < 1016; i++){
data[i] = (byte) dis.read();
}
for (int i = 0; i < 4; i++){
dis.read();
}
// ***************** output data ********************
if (checksumCheck(checksum) && fecfCheck(fecf)){
FileOutputStream output = new FileOutputStream("ParsedData", true);
try{
output.write(data);
}
finally{
output.close();
}
}
}
catch (EOFException eof) {
}
dis.close();
}
}
答案 0 :(得分:6)
markerFound = true;
此行不在条件内,并且将在任何循环中执行 当然会关闭你的循环,因为:
for (int offset = 0; !markerFound && offset < 4; offset++)
答案 1 :(得分:1)
第一件事
您正在for
内打开文件,因此,读数始终会从文件的开头开始。在第一个for
之前打开它。
<强>第二强>
由于测试!markerFound && offset < 4
,您的循环最多会出现4次。
<强>第三强>
这段代码对我来说没有意义:
for (int i = 0; i < offset; i++){
dis.read();
}
因为offset
在第一次迭代中为0,所以在下一次迭代中将为1,依此类推。并且该循环不是必需的,您使用另一个循环来读取字节,直到到达MARKER。
<强>四强>
如果您的文件具有固定长度的“记录”并且标记出现在可预测的位置上,请使用DataInputStream skipBytes
method前进到下一个标记。
答案 2 :(得分:0)
正如我在早期answer中发布的问题Java, need a while loop to reach eof. i.e.while !eof, keep parsing我想再次声明DataInputStream.read()
(与其他readXxX()方法不同) 不抛出 EOFExcepion
。
来自JavaDocs:(DataInputStream
从read()
继承FilterInputStream
)
如果由于已到达流末尾而没有可用字节,则返回值 -1 。
因此,要正确检查EOF
,read(byte[])
循环中通常使用while
,如下所示:
int read = 0;
byte[] b = new byte[1024];
while ((read = dis.read(b)) != -1) { // returns numOfBytesRead or -1 at EOF
// fos = FileOutputStream
fos.write(b, 0, read); // (byte[], offset, numOfBytesToWrite)
}
现在,让回到你当前的问题;因为,您还没有共享二进制文件格式,因此很难建议更好的解析方法。因此,对嵌套循环当前解析文件的方式的理解有限;您需要另一个while
循环(如上所述)读取/解析并复制您的“数据”,直到找到标记<到达EOF
为止/ em>的
markerFound = true;
for (int i = 0; i < 11; i++){ // move this loop inside while IF
dis.read(); // these 11 bytes need to be skipped every time
}
// Open the file just ONCE (outside the loop)
FileOutputStream output = new FileOutputStream("ParsedData", true);
// ********************** data **********************
int read = 0;
byte[] data = new byte[1016]; // set byte buffer size
while ((read = dis.read(data)) != -1) { // read and check for EOF
// ***************** output data ********************
if (checksumCheck(checksum) && fecfCheck(fecf)) { // if checksum is valid
output.write(data, 0, read); // write the number of bytes read before
}
// SKIP four bytes
for (int i = 0; i < 4; i++) { // or, dis.skipBytes(4); instead of the loop
dis.read();
}
}
// Close the file AFTER input stream reaches EOF
output.close(); // i.e. all the data has been written