废话先不说,请看代码:
package Example_1;import java.io.FileInputStream;
import java.io.IOException;public class StreamOperate {
private static FileInputStream fin; public static void main(String[] args) throws IOException {
int i ;
fin = new FileInputStream("F:\\RP.txt");
if( fin.available() > 0 ){
byte[] b = new byte[fin.available()];
System.out.println("能从fin文件中读取的字符数量:"+fin.available());
System.out.println("数组b[]能接受到的字符数量:"+b.length);
for(i=0; i<fin.available(); i++){//循环赋值并输出
b[i] = (byte)fin.read();
System.out.print(b[i]+" - ");
}
System.out.println(">>>循环结束时,i="+i+",这说明循环了>>>"+i+"次");
for(i=0; i<fin.available(); i++)//再输出一次看看
if( 0 == (i+1)%20 )
System.out.println();
else
System.out.print(b[i]+" - ");
System.out.println("=============="+i);
}
}
}
我刚开始看IO,刚看到FileInputStream。里面有一个available()函数,我的理解是,这个函数获取一定量可读取的字节数
我在使用这个函数的时候,出了问题,代码就是上面的。
代码从语法上讲是完全正确的!但是,结果完全不符合预期。在F:盘中有一个RP.txt文本,如果:
【验证1】、文本中是"ABCDEFGHIJKLMN"
   则结果是:
能从fin文件中读取的字符数量:15
数组b[]能接受到的字符数量:15
65 - 32 - 66 - 67 - 68 - 69 - 70 - 71 - >>>循环结束时,i=8,这说明循环了>>>8次
65 - 32 - 66 - 67 - 68 - 69 - 70 - ==============7
显然,fin.avaliable()读取了全部15个字符,由于txt文本中每个英文字符为1个字节,所以读取后应该是循环15次才对,可是,第一次循环8次,第二次循环7次,明显小于15,而且两次循环数量还不一样!为了验证,我进行第二次【验证2】、文本中是"A BCDEFGHIJKLMN"
  这次文本中多了个空格,结果:
能从fin文件中读取的字符数量:16
数组b[]能接受到的字符数量:16
65 - 32 - 66 - 67 - 68 - 69 - 70 - 71 - >>>循环结束时,i=8,这说明循环了>>>8次
65 - 32 - 66 - 67 - 68 - 69 - 70 - 71 ==============8
 此时依然不对 
 怪了我验证第三次
【验证3】、文本中是"A
                  BCDEFGHIJKLMN"
   这次文本中多了个换行符 ,结果
能从fin文件中读取的字符数量:16
数组b[]能接受到的字符数量:16
65 - 13 - 10 - 66 - 67 - 68 - 69 - 70 - >>>循环结束时,i=8,这说明循环了>>>8次
65 - 13 - 10 - 66 - 67 - 68 - 69 - 70 - ==============8
   这次,两次循环的次数一致了,但是依然小于available()可读取的总次数16次最后一次验证
【验证4】、文本中是"你好A
                  BCDEFGHIJKLMN"
结果:
能从fin文件中读取的字符数量:22
数组b[]能接受到的字符数量:22
-60 - -29 - -70 - -61 - 65 - 13 - 10 - 66 - 67 - 68 - 69 - >>>循环结束时,i=11,这说明循环了>>>11次
-60 - -29 - -70 - -61 - 65 - 13 - 10 - 66 - 67 - 68 - 69 - ==============11
  依然小于available()函数可识别字节的总数!-----------------------------------------------通过多番的验证,我依然不得其要,实在是很无奈,故此求解惑!
希望朋友们能给小弟解答下问题,谢谢!

解决方案 »

  1.   

    你觉得在数据读取的过程中fin.available()是变化的,还是不变的呢?明显是变化的。你把第一次查询fin.available()得到的结果保存为变量,然后再循环的条件判断那里使用这个变量。
      

  2.   

    没错,你可以在for循环中输入System.out.println(i+"------>>"+fin.available());进行代码测试,可以发现fin.available()时变换的,所以刚开始的时候要把fin.available()定义成一个局部常量,然后一直引用这个常量,呵呵,我也是新手,发发牢骚
      

  3.   


    既然是变化的,那要这个available有什么用呢?
      

  4.   

    available表示的是当前剩余的可用的数量,每读完一个字节,available的数量就减1.可以理解为有一个游标来标记当前位置,每读一个字节游标的位置就往后移动一位,而available相当于从游标位置到流的末尾的字节数。
      

  5.   

    我觉得会不会是这样
    for(i=0; i<fin.available(); i++){//循环赋值并输出
                     b[i]    =    (byte)fin.read();                 
                   System.out.print(b[i]+" - ");             
               } 
    在循环里每次调用fin.available()返回的数都是不同的,当i = 0时,fin.available()是15
    第二次迭代,i = 1, fin.available() = 14
    第三次迭代,i = 2, fin.available() = 13
    ...
    最后大概是i = 7, fin.available() = 7,此时 i = fin.available()正好退出循环所以我建议fin.available()最好不要再循环里用,除非你知道你在做什么
    fin.available()返回的是数据流剩下的字节数,我猜的
      

  6.   

    你的问题是好几个问题交织在一起的问题。我直接上一个正确的测试例子。
    import java.io.FileInputStream;
    import java.io.IOException;public class StreamOperate {
    private static FileInputStream fileInputStream; public static void main(String[] args) throws IOException {
    fileInputStream = new FileInputStream("d:\\strTest.txt");
    if (fileInputStream.available() <= 0)
    return; Integer[] data = new Integer[fileInputStream.available()]; for (int i = 0; fileInputStream.available() > 0; i++) {
    data[i] = fileInputStream.read();
    System.out.print(Integer.toHexString(fileInputStream.available()) + ":");
    System.out.print(Integer.toHexString(data[i]) + "\t");
    }
    }
    }打印的结果是
    10:ef f:bb e:bf d:41 c:42 b:43 a:44 9:45 8:46 7:47 6:48 5:49 4:4a 3:4b 2:4c 1:4d 0:4e 我的文件是UTF-8格式的,用UE打开是以下数据前面的3个byte是utf-8的头:EF BB BF
    后面的14个byte是数据