iteye_19215
iteye_19215
2012-08-21 14:55

Java IO 字节流计数问题

已采纳

[code="java"]
long count = 0;
String line = br.readLine();
while (line != null) {
if (count > length) {
break;
}

                count += line.getBytes("UTF-8").length;
                count += 1; // Add \r's length
                System.out.println(Thread.currentThread() + "  " + line);
                System.out.println(" count:" + count);
                line = br.readLine();
            }

[/code]

用这样的方法来统计已读的字节数为什么输出的结果不对呢?具体的说count统计的数目比实际的要少,这是什么原因造成的?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

7条回答

  • jinnianshilongnian jinnianshilongnian 9年前

    [code="java"]File file = new File("D:\todo.txt");
    BufferedReader br = new BufferedReader(new FileReader(file));
    long length = 1261192704;
    long count = 0;
    String line = br.readLine();
    while (line != null) {
    if (count > length) {
    break;
    }
    count += 2;
    count += line.getBytes("utf-8").length;
    System.out.println(line);
    line = br.readLine();
    }

        System.out.println(count);
        FileInputStream fis = new FileInputStream(file);
        System.out.println(fis.available());[/code]
    

    测试结果:
    1、如果windows上边读windows文件 返回结果是正确的;
    2、如果windows上边读linux文件结果是有偏差的(count += 1)。

    [quote]getBytes
    public byte[] getBytes(Charset charset)使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
    此方法总是使用此字符集的默认替代 byte 数组替代错误输入和不可映射字符序列。如果需要对编码过程进行更多控制,则应该使用 CharsetEncoder 类。
    [/quote]

    难道有些linux字符在windows上无法映射? 你试下 在linux上读取linux文件 结果对吗

    点赞 评论 复制链接分享
  • ansjsun ansj 9年前

    按照byte流读取..不要按照read流读取

    点赞 评论 复制链接分享
  • luwies luwies 9年前

    :oops: 第二行的 String line = br.readLine(); 经读了一些字符了,但是此时count = 0。。。所以你的程序应该少了第二行程序读到的字符数。

    点赞 评论 复制链接分享
  • jinnianshilongnian jinnianshilongnian 9年前

    问题找到了,
    Reader 在读取字符时,在linux上你是把换行符当作一个字节看待,但是如果我忘文件里写了\r\n 你也是看作一个的(就是说linux上也可能写\r\n 可是你只记录了1个字节),所以出问题了。
    [code="java"]
    FileInputStream fis = new FileInputStream(file);
    System.out.println(fis.available());

        long r = 0;
        long n = 0;
        long c = 0;
        int i = fis.read(); 
        while(i != -1) {
            if(i == '\r') {
                r++;
            }
            if(i == '\n') {
                n++;
            }
    
            c++;
            i = fis.read();
        }
        System.out.println(c);
        System.out.println(r);
        System.out.println(n);
    

    [/code]

    点赞 评论 复制链接分享
  • iteye_2652 iteye_2652 9年前

    if (count > length) {

    break;

    }

    这个判断感觉也好别扭。不知道是什么 可能也会影响结果 都非空判断了 不用break了吧 count>length是判断什么的?

    点赞 评论 复制链接分享
  • iteye_2652 iteye_2652 9年前

    count += 1; // Add \r's length 这个不用要了吧,已经作了line != null的判断了 应该会排除掉空的回车。每次读一行就用count += 1;好像是错误的。

    点赞 评论 复制链接分享
  • jinnianshilongnian jinnianshilongnian 9年前

    要考虑 换行符 在window上边 是\r\n(两个字节) 在linux上是\r(一个);

    点赞 评论 复制链接分享

相关推荐