Java-希望通过eof进行解析。代码只解析一次

Java-希望通过eof进行解析。代码只解析一次,java,parsing,eof,datainputstream,Java,Parsing,Eof,Datainputstream,下面的代码只对数据文件进行一次解析。我试图让它解析整个文件。每次它找到一个标记时,解析数据并将其附加到输出文件中。目前,它成功地解析了数据一次,然后停止。在eof之前,我不知道如何保持循环。数据是4字节对齐的,并且位于输入二进制文件中 private static void startParse(File inFile) throws IOException { boolean markerFound = false; for (int offset = 0; !mar

下面的代码只对数据文件进行一次解析。我试图让它解析整个文件。每次它找到一个标记时,解析数据并将其附加到输出文件中。目前,它成功地解析了数据一次,然后停止。在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();
 }
 }
private static void startParse(文件填充)引发IOException{
布尔markerFound=false;
对于(int offset=0;!markerFound&&offset<4;offset++){
DataInputStream dis=新DataInputStream(新文件InputStream(infle));
对于(int i=0;i
该行不在条件内,将在循环的任何事件中执行。
这当然会关闭您的循环,因为:

for (int offset = 0; !markerFound && offset < 4; offset++)
for(int offset=0;!markerFound&&offset<4;offset++)

第一件事

您正在为
打开
中的文件,因此读取总是从文件的开头开始。在
的第一个
之前打开它

因为测试
!markerFound&&offset<4
,循环最多出现4次

第三

这个代码对我来说没有意义:

for (int i = 0; i < offset; i++){
    dis.read();
}
for(int i=0;i
因为在第一次迭代中,偏移量是0,在下一次迭代中,偏移量是1,依此类推。这个循环是不必要的,您正在使用另一个循环读取字节,直到到达标记

第四


如果您的文件具有固定长度的“记录”,并且标记发生在可预测的位置,请使用DataInputStream前进到下一个标记。

正如我在前面的问题中所述,我想再次声明
DataInputStream.read()
(与其他readXxX()方法不同)不会抛出
EOFExcepion

从:(
DataInputStream
FilterInputStream
继承
read()

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

因此,为了正确检查
EOF
,通常在
循环中使用
read(byte[])
,而
循环如下:

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

markerFound=true;
对于(int i=0;i<11;i++){//在
dis.read();//每次都需要跳过这11个字节
}
//只打开文件一次(循环外部)
FileOutputStream输出=新的FileOutputStream(“ParsedData”,true);
//*************************数据**********************
int read=0;
字节[]数据=新字节[1016];//设置字节缓冲区大小
while((read=dis.read(data))!=-1){//read并检查EOF
//****************输出数据********************
if(checksumCheck(checksum)和&fecfCheck(fecf)){//if校验和有效
output.write(data,0,read);//写入之前读取的字节数
}
//跳过四个字节
对于(inti=0;i<4;i++){//or,dis.skipBytes(4);而不是循环
dis.read();
}
}
//输入流达到EOF后关闭文件
output.close();//i、 e.所有数据均已写入

您的意思是直到数据结束时才解析?顺便说一句,我建议您使用这种作业是的,文件中有一段数据,它只解析第一段标记数据,文件中大约有50段。我说“数据”,因为其余的都是垃圾,我不在乎,我正在解析出我想要的实际“数据”。你确定标记存在,4字节对齐,字节顺序正确(小/大端)<代码>标记查找=整数==标记请包括文件格式的说明。没有它,你的问题就没有多大意义。但只有找到标记,它才能退出上面的while循环。否则它将得到一个eof异常。如果不是这样的话,我可能需要进一步的解释,因为我会感到困惑。
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)
}
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