Java - 想通过eof解析。代码只解析一次

时间:2013-06-06 17:25:29

标签: java parsing eof datainputstream

下面的代码只解析数据文件一次。我试图让它解析整个文件。每次找到标记时,都会解析数据并将其附加到输出文件中。目前它成功解析数据然后停止。无法弄清楚如何让它循环直到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();
 }
 }

3 个答案:

答案 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

来自JavaDocsDataInputStreamread()继承FilterInputStream

  

如果由于已到达流末尾而没有可用字节,则返回值 -1

因此,要正确检查EOFread(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