最近获得了一个1000万以内的素数表。直接拷贝至Word电脑吃不消,我就用java实现。
成功拷贝。但是我在查看的时候发现每10000总会丢掉很小一部分。
我尝试着用9000来分段,发现还是会在不经意中丢掉一部分,我很不明白这是为什么。
一下是代码:
package io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class CopyTXT {
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\xia\\Desktop\\ss.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
int i = 0;
int t = 0;
String str = null;
File target = null;
BufferedWriter bw = null;
while ( (str = br.readLine()) != null) {
if (i % 10000 == 0) {
System.out.println(i);
target = new File("C:\\Users\\xia\\Desktop\\"+t+".txt");
bw = new BufferedWriter(new FileWriter(target));
t ++;
}
i ++;
if (str.indexOf(i+":") == -1)
System.out.println("error"+i);
bw.write(str);
bw.write("\t\r\n");
}
br.close();
bw.close();
}
}
希望知道的人能解释一下
------解决方案--------------------
bw只是个引用,关键要看你new了多少次,这才是真正要关闭的内容。
如果还不明白,给你举个例子阐述下引用和对象本身的关系吧:你有一台电视机(对象实体),想要换台,于是搞了一个遥控器(引用)。咱们通过这个遥控器,实现了对电视机的各种操作。
你的这个是用方式类似于,这个遥控器不变,又给家里各个房间都买了一台电视机(都是同一个牌子的)。然后你用你的bw遥控器,将家里的电视机一个个打开了,最后恰好走到客厅,然后按了关闭按钮,于是感觉对所有的电视都关了。嗯,它们都关了么?
只是打个比方哈,LZ思考下,或者在每个new的地方,直接打印下bw,看看打印的对象内存地址是不是不一样的。
------解决方案--------------------
在close()之前先flush()是个好习惯。
那问题的原因呢??
io,特别是io中的write并不是一个能快速响应的请求,因为它包含了内存中的数据处理和磁盘io两个部分。
其中磁盘io的性能完全取决于操作系统和硬件,而且熟悉硬件的人都知道,磁盘io的速度是远远小于内存读写速度的,大文件的复制往往是不到几乎可以忽略的cpu时间+1%的内存io+99%磁盘io。
如果直接调用close()方法,可能导致数据全部进去内存,但是内存的数据没有全部被硬盘处理的情况,这样在整个size中未处理的部分就被遗弃了。
而flush方法会刷新内存的时候,会等待内存中的全部数据被io到磁盘上。