从 RandomAccessFile 读取数据产生不正确的结果 - Java

Reading data from RandomAccessFile producing incorrect results - Java

我有一个 42 行的文本文件。每行有超过 22,000 个以逗号分隔的数字。

我想从每一行中提取某些数字,我有一个长度为 1000 的 int 数组,其中包含我需要从这 42 行中的每一行中提取的 1,000 个数字。

例如,如果数组包含 43、1、3244,这意味着我想要每行的第 43 个数字、第 1 个数字和第 3244 个数字,从第一行开始到第 42 行结束。

我的for循环好像不行,它只从文本文件的第一行读取了42行220000个数字,我不知道哪里错了。

for(int i=0;i<42;i++){ //irretates through the 42 lines of 
    counter=1; // to keep track about on which line the code is working
    System.out.println("Starting line"+i);

    st2=new StringTokenizer(raf1.readLine(),",");
    //raf3 is a RandomAccessFile object containing the 42 lines

    a:while(st2.hasMoreTokens()){
        b=is_there(array2,counter);
        // is_there is a method that compares the rank of the taken being read with 
       //the whole array that has the 1000 numbers that i want. 
        if(b==false){ 
            // if the rank or order of token [e.g. 1st, 432th] we are stopping at 
           //is not among the 1000 numbers in the array 
            counter++;                  
            continue a;
        }
        else{ //if true
            s2=st2.nextToken();
            raf2.writeBytes(s2); //write that token on a new empty text file 
            raf2.writeBytes(","); // follow the number with a comma
            counter++;
        }
    } // end of for loop



public static boolean is_there(int[] x,int y){
    boolean b=false;
    for(int i=0;i<x.length;i++){
        if(x[i]==y) {b=true; break;}
    }
    return b;

您遇到的一个问题是,当您找到一个不在您的数组中的索引时,您实际上并没有跳过该标记:

if ( b == false ) {
    // don't actually skip the token !!
    counter++;                  
    continue a;
} else {
    s2 = st2.nextToken();
    raf2.writeBytes(s2);
    raf2.writeBytes(",");
    counter++;
}

这意味着每次您尝试跳过时,您的 StringTokenizer 都会落后 1 个标记。

例如,这可能会导致无限循环。

if ( b == false ) {
    // so skip the token !!
    st2.nextToken();

    counter++;                  
    continue a;
} else {
    s2 = st2.nextToken();
    raf2.writeBytes(s2);
    raf2.writeBytes(",");
    counter++;
}

作为旁注,循环可以更优雅地重写如下:

while (st2.hasMoreTokens()) {
    s2 = st2.nextToken();

    if (is_there(array2, counter)) {
        raf2.writeBytes(s2);
        raf2.writeBytes(",");
    }

    ++counter;
}

您还应该:

  • 对事物使用更具描述性的名称。
  • declare variables in the scope they are used.

Radiodef 的答案是正确的,但我认为还缺少一个部分。该代码找到了正确的数字,但将它们打印在一行中,因为循环后没有 'next Line' 语句通过特定行(至少在上面的代码中没有),例如:

        for(int i=0;i<42;i++){
        counter=1; // to keep track about on which TOKEN the code is working
        System.out.println("Starting line"+i);
        st2=new StringTokenizer(raf1.readLine(),",");
            while(st2.hasMoreTokens()){
                boolean b = is_there(array2,counter);
                if(!b){
                    st2.nextToken();
                }else{
                    String s2=st2.nextToken();
                    raf2.writeBytes(s2 + ",");
                }
                counter++;
            }
            raf2.writeBytes("\r\n");         //next line!
        }

这样,它应该可以正确读取、搜索和打印数字。

此外,评论中有错误:counter=1; // to keep track about on which line the code is workingcounter 跟踪循环正在处理的标记,而不是行。

顺便说一句。 is_there 方法也可以采用更短的形式:

public static boolean is_there(int[] x,int y){
    for(int i : x){
        if (i == y) return true;
    }
    return false;
}

但是,我不确定,它是否更具可读性。