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

时间:2015-04-23 01:56:04

标签: java for-loop stringtokenizer randomaccessfile

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

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

例如,如果数组包含43,1,3244,则表示我想要从第一行到第42行开始的第43个数字,第1个数字和第3244个数字。

我的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;

2 个答案:

答案 0 :(得分:7)

您遇到的一个问题是,当您发现某个索引不在您的数组中时,您实际上并未跳过该令牌:

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;
}

您还应该:

答案 1 :(得分:5)

Radiodef答案是正确的,但我认为仍有一件丢失。代码找到了正确的数字,但是将它们打印在一行中,因为没有下一行&#39;循环之后的语句经过特定行(至少不在上面的代码中),例如:

        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;
}

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