从 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 working
。 counter
跟踪循环正在处理的标记,而不是行。
顺便说一句。 is_there
方法也可以采用更短的形式:
public static boolean is_there(int[] x,int y){
for(int i : x){
if (i == y) return true;
}
return false;
}
但是,我不确定,它是否更具可读性。
我有一个 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 working
。 counter
跟踪循环正在处理的标记,而不是行。
顺便说一句。 is_there
方法也可以采用更短的形式:
public static boolean is_there(int[] x,int y){
for(int i : x){
if (i == y) return true;
}
return false;
}
但是,我不确定,它是否更具可读性。