黑马程序员技术交流社区
标题:
关于基础测试题的小问题
[打印本页]
作者:
黑马---邢志伟
时间:
2012-6-26 09:18
标题:
关于基础测试题的小问题
编写程序拷贝一个文件. 尽量使用效率高的方式。这个不是太懂。麻烦高手讲解一下。。。:#
作者:
韦念欣
时间:
2012-6-26 09:22
本帖最后由 韦念欣 于 2012-6-26 09:24 编辑
为了提高性能,先把数据写到内存中的缓冲区中,也可理解为先写到输出流中,当缓冲满的时候,才会将数据写到硬盘上的文件。之所以这样能提升性能,是因为CPU向内存中写数据的速度远远大于直接写到硬盘的速度,缓冲区正是匹配了高速度的CPU和低速的磁盘文件
可以申请一个临时的数组
byte[] buf = new byte[1024];
这个起到临时存储功能的数组当然可以看作缓冲区.
作者:
唐辉辉
时间:
2012-6-26 09:24
看下毕老师IO流的讲解。就知道了!
作者:
陆强强
时间:
2012-6-26 09:44
class IOForCopy
{
public static void main(String[] args)throws IOException
{
iocopy("1.txt","1复件txt");
}
public static void iocopy(String toRead,String toCopy)throws IOException
{
BufferedWriter bw=null;
BufferedReader br=null;
try
{
br=new BufferedReader(new FileReader(toRead));
bw=new BufferedWriter(new FileWriter(toCopy));
String line=null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}
}
catch (Exception e)
{
throw new IOException("找不到文件");
}
finally
{
try
{
if (br!=null)
br.close();
}
catch (Exception e)
{
throw new IOException("读取流关闭失败");
}
try
{
if (bw!=null)
bw.close();
}
catch (Exception e)
{
throw new IOException("写入流关闭失败");
}
}
}
}
作者:
谭立文
时间:
2012-6-26 15:07
使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢?
最近看了看NIO决定试一试 java NIO 到底有什么性能的提升.
第一种方法:古老的方式
public static long forJava(File f1,File f2) throws Exception{
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
byte[] buffer=new byte[length];
while(true){
int ins=in.read(buffer);
if(ins==-1){
in.close();
out.flush();
out.close();
return new Date().getTime()-time;
}else
out.write(buffer,0,ins);
}
}
方法的2参数分别是原始文件,和拷贝的目的文件.这里不做过多介绍.
实现方法很简单,分别对2个文件构建输入输出流,并且使用一个字节数组作为我们内存的缓存器, 然后使用流从f1 中读出数据到缓存里,在将缓存数据写到f2里面去.这里的缓存是2MB的字节数组
第2种方法:使用NIO中的管道到管道传输
public static long forTransfer(File f1,File f2) throws Exception{
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
FileChannel inC=in.getChannel();
FileChannel outC=out.getChannel();
int i=0;
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<20971520)
length=(int)(inC.size()-inC.position());
else
length=20971520;
inC.transferTo(inC.position(),length,outC);
inC.position(inC.position()+length);
i++;
}
}
实现方法:在第一种实现方法基础上对输入输出流获得其管道,然后分批次的从f1的管道中像f2的管道中输入数据每次输入的数据最大为2MB
方法3:内存文件景象写(读文件没有使用文件景象,有兴趣的可以回去试试,,我就不试了,估计会更快)
public static long forImage(File f1,File f2) throws Exception{
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
RandomAccessFile out=new RandomAccessFile(f2,"rw");
FileChannel inC=in.getChannel();
MappedByteBuffer outC=null;
MappedByteBuffer inbuffer=null;
byte[] b=new byte[length];
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.force();
out.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<length){
length=(int)(inC.size()-inC.position());
}else{
length=20971520;
}
b=new byte[length];
inbuffer=inC.map(MapMode.READ_ONLY,inC.position(),length);
inbuffer.load();
inbuffer.get(b);
outC=out.getChannel().map(MapMode.READ_WRITE,inC.position(),length);
inC.position(b.length+inC.position());
outC.put(b);
outC.force();
}
}
实现方法:跟伤2个例子不一样,这里写文件流没有使用管道而是使用内存文件映射(假设文件f2在内存中).在循环中从f1的管道中读取数据到字节数组里,然后在像内存映射的f2文件中写数据.
第4种方法:管道对管道
public static long forChannel(File f1,File f2) throws Exception{
long time=new Date().getTime();
int length=2097152;
FileInputStream in=new FileInputStream(f1);
FileOutputStream out=new FileOutputStream(f2);
FileChannel inC=in.getChannel();
FileChannel outC=out.getChannel();
ByteBuffer b=null;
while(true){
if(inC.position()==inC.size()){
inC.close();
outC.close();
return new Date().getTime()-time;
}
if((inC.size()-inC.position())<length){
length=(int)(inC.size()-inC.position());
}else
length=2097152;
b=ByteBuffer.allocateDirect(length);
inC.read(b);
b.flip();
outC.write(b);
outC.force(false);
}
}
这里实现方式与第3种实现方式很类似,不过没有使用内存影射.
下面是对49.3MB的文件进行拷贝的测试时间(毫秒)
Start Copy File... file size:50290KB
CopyFile:b1.rmvb mode:forChannel RunTime:3203
CopyFile:b1.rmvb mode:forImage RunTime:3328
CopyFile:b1.rmvb mode:forJava RunTime:2172
CopyFile:b1.rmvb mode:forTransfer RunTime:1406
End Copy File!
解释: 在测试结果中看到 古老方式,和管道向管道传输是最快的,,,,,为什么呢?
我分析是这样的,由于另外2种方法内部都使用了 字节数组作为缓存中转,在加上NIO内部有一个贴近系统的缓存区,这无意就增加了另一个缓存器,所以相对于这2个方法就要慢许多,,如果不使用 字节数组作为数据中转的话相信速度会更快的..
摘自CSDN.
作者:
李文龙
时间:
2012-6-26 15:10
给你想要的
public static void Copy(File file1,File file2)
{
BufferedInputStream f1 = null;
BufferedOutputStream f2 = null;
try {
f1 = new BufferedInputStream(new FileInputStream(file1));
f2 = new BufferedOutputStream(new FileOutputStream(file2));
while(f1.available()!=0)
{
f2.write(f1.read());
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if(f1!=null)
{
try
{
f1.close();
f1 = null;
}
catch (IOException e)
{
e.printStackTrace();
}
}
if(f2!=null)
{
try
{
f2.close();
f2 = null;
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
作者:
周朋飞
时间:
2012-6-27 01:09
所谓高效率就是让字符写到缓冲池当中,这样就不用读一个字节写一个字节了
只要记住 这样两句最简单的就行
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("文件路径")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileoutputStream("文件路径")));
然后就是内部的循环了
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line );
//换行 可以用bufferReader的newLine
bw.newLine();
bw.flush();
}
作者:
那罗庭
时间:
2012-6-28 21:49
明白一些了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2