[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统计的数目比实际的要少,这是什么原因造成的?
[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文件 结果对吗
要考虑 换行符 在window上边 是\r\n(两个字节) 在linux上是\r(一个);
count += 1; // Add \r's length 这个不用要了吧,已经作了line != null的判断了 应该会排除掉空的回车。每次读一行就用count += 1;好像是错误的。
if (count > length) {
break;
}
这个判断感觉也好别扭。不知道是什么 可能也会影响结果 都非空判断了 不用break了吧 count>length是判断什么的?
问题找到了,
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]
:oops: 第二行的 String line = br.readLine(); 经读了一些字符了,但是此时count = 0。。。所以你的程序应该少了第二行程序读到的字符数。
按照byte流读取..不要按照read流读取