/**
 * Author:smilewater
 */
package java_optimize;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;public class CopyFile { /**
 * @param args
 * @throws Exception
 */
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
long startTime, endTime;
startTime = System.currentTimeMillis();
CopyFile.copyFile("D:\\API_ALL\\api.rar", "D:\\API_ALL\\apiCopy.rar");
endTime = System.currentTimeMillis();
System.out.println("缓冲为1024b时,拷贝文件耗时为:" + (endTime - startTime)
+ "毫秒"); startTime = System.currentTimeMillis();
CopyFile.copyFile2("D:\\API_ALL\\api.rar", "D:\\API_ALL\\apiCopy2.rar");
endTime = System.currentTimeMillis();
System.out.println("缓冲为10240b时,拷贝文件耗时为:" + (endTime - startTime)
+ "毫秒"); startTime = System.currentTimeMillis();
CopyFile.copyFile3("D:\\API_ALL\\api.rar", "D:\\API_ALL\\apiCopy3.rar");
endTime = System.currentTimeMillis();
System.out.println("采用系统默认缓冲512b时,拷贝文件耗时为:" + (endTime - startTime)
+ "毫秒"); startTime = System.currentTimeMillis();
CopyFile.copyFile4("D:\\API_ALL\\api.rar", "D:\\API_ALL\\apiCopy4.rar");
endTime = System.currentTimeMillis();
System.out.println("采用字符流默认缓冲时,拷贝文件耗时为:" + (endTime - startTime)
+ "毫秒");

startTime = System.currentTimeMillis();
CopyFile.copyFile5("D:\\API_ALL\\api.rar", "D:\\API_ALL\\apiCopy5.rar");
endTime = System.currentTimeMillis();
System.out.println("采用字符流自定义缓冲1024b时,拷贝文件耗时为:" + (endTime - startTime)
+ "毫秒"); }

//static 修饰的方法执行效率比较高,相当于c++中的内联函数
public static void copyFile(String fileFromPath, String fileToPath)
throws Exception {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(fileFromPath);
out = new FileOutputStream(fileToPath);
int length = in.available();
int len = (length % 1024 == 0) ? (length / 1024)
: (length / 1024 + 1);
byte[] temp = new byte[1024];
for (int i = 0; i < len; i++) {
in.read(temp);
out.write(temp);
}
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
} public static void copyFile2(String fileFromPath, String fileToPath)
throws Exception {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(fileFromPath);
out = new FileOutputStream(fileToPath);
int length = in.available();
int len = (length % 10240 == 0) ? (length / 10240)
: (length / 10240 + 1);
byte[] temp = new byte[10240];
for (int i = 0; i < len; i++) {
in.read(temp);
out.write(temp);
}
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
} public static void copyFile3(String fileFromPath, String fileToPath)
throws Exception {
InputStream inBuffer = null;
OutputStream outBuffer = null;
try {
InputStream in = new FileInputStream(fileFromPath);
inBuffer = new BufferedInputStream(in);
OutputStream out = new FileOutputStream(fileToPath);
outBuffer = new BufferedOutputStream(out);
while (true) {
int byteData = inBuffer.read();
if (byteData == -1)
break;
out.write(byteData);
} } finally {
if (inBuffer != null)
inBuffer.close();
if (outBuffer != null)
outBuffer.close();
}
} public static void copyFile4(String fileFromPath, String fileToPath)
throws Exception {
Reader readBuffer = null;
Writer writeBuffer = null; try {
Reader read = new FileReader(fileFromPath);
readBuffer = new BufferedReader(read);
Writer write = new FileWriter(fileToPath);
writeBuffer = new BufferedWriter(write);
while (true) {
int byteData = readBuffer.read();
if (byteData == 1)
break;
writeBuffer.write(byteData); }
} finally {
if (readBuffer != null)
readBuffer.close();
if (writeBuffer != null)
writeBuffer.close();
}
} public static void copyFile5(String fileFromPath, String fileToPath)
throws Exception {
Reader readBuffer = null;
Writer writeBuffer = null; try {

Reader read = new FileReader(fileFromPath);
readBuffer = new BufferedReader(read,1024);
Writer write = new FileWriter(fileToPath);
writeBuffer = new BufferedWriter(write);
char[] temp=new char[1024];
int c;
while(true){
c=readBuffer.read(temp);
if(c==-1)
break;
writeBuffer.write(temp);
}
} finally {
if (readBuffer != null)
readBuffer.close();
if (writeBuffer != null)
writeBuffer.close();
}
}}
运行结果如下:
缓冲为1024b时,拷贝文件耗时为:78毫秒
缓冲为10240b时,拷贝文件耗时为:47毫秒
采用系统默认缓冲512b时,拷贝文件耗时为:19203毫秒
采用字符流默认缓冲时,拷贝文件耗时为:1140毫秒
采用字符流自定义缓冲1024个字符时,拷贝文件耗时为:813毫秒由以上程序运行结果可以看出用字节流并且定义合适的缓冲区时速度最快,效率最高
(注意!!!!)字符流拷贝文件时得确定文件内容是字符,否则如果文件是字节流的话,尽管文件拷贝成功,但是却是损坏的,例如.rar,.zip,图片等运行环境:
系统:server2003
cpu:奔腾2.66G
内存:512M

解决方案 »

  1.   

    楼主的精神可嘉啊,!感觉在Java版能见到楼主这种愿意在这种问题上钻研的人很少了。而且你还注意到了图片是不能看的了1,我觉得文件Copy,根本就不要实验Reader和Writer。copy file的时候,file就要完全被当成Binary文件处理。
    2,我没有进行过详细实验,建议你用JNI去调用Windows API,CopyFile和MoveFile试一试,把事情交给操作系统做,恐怕是最快的了。
    你想要实验的话,我可以提供支持。
      

  2.   

    in.read(temp); 
    out.write(temp); 这种写法有问题,
    int length;
    。length = in.read(temp);
    out.write(temp,0,length);....
      

  3.   

    in.read(temp); 
    out.write(temp); 这种写法有问题,Java code    int length; 。 length = in.read(temp); out.write(temp,0,length); ....楼上的正解。
      

  4.   

    那你用 NIO 的 FileChannel 来试试看呢
      

  5.   

    NIO的应该是快的,本质就是JNI嘛。
      

  6.   

    仅供参考:package mypackage.test;import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;public class CopyFile {

    //拷贝文件
    private void copyFile(String source, String dest) {
    try {
    File in = new File(source);
    File out = new File(dest);
    FileInputStream inFile = new FileInputStream(in);
    FileOutputStream outFile = new FileOutputStream(out);
    byte[] buffer = new byte[1024];
    int i = 0;
    while ((i = inFile.read(buffer)) != -1) {
    outFile.write(buffer, 0, i);
    }//end while
    inFile.close();
    outFile.close();
    }//end try
    catch (Exception e) { }//end catch
    }//end copyFile //处理目录
    public void copyDict(String source, String dest) {
    String source1;
    String dest1; File[] file = (new File(source)).listFiles();
    for (int i = 0; i < file.length; i++)
    if (file[i].isFile()) {
    source1 = source + "/" + file[i].getName();
    dest1 = dest + "/" + file[i].getName();
    copyFile(source1, dest1);
    }//end if
    for (int i = 0; i < file.length; i++)
    if (file[i].isDirectory()) {
    source1 = source + "/" + file[i].getName();
    dest1 = dest + "/" + file[i].getName();
    File dest2 = new File(dest1);
    dest2.mkdir();
    copyDict(source1, dest1);
    }//end if
    }//end copyDict public static void main(String args[]) {
    CopyFile copyFile = new CopyFile();
    copyFile.copyDict("D:/temp0", "D:/tempApp");
    }
    }//end CopyFile
      

  7.   

    测测 common-io 的 copyFile 速度
    有兴趣的话
    顺便看看他们是怎么实现的
      

  8.   

    恩,正要学习
    JNI,敢问能给介绍本jni的书籍不?
    感激啊!!!
    呵呵
      

  9.   

    我曾经做过类似的测试
    缓冲区越大速度肯定越快
    当然速度最快的肯定是JNI
      

  10.   

    要什么jni啊 
    不稳定的够用了 你要做什么啊 
    要那么快 
    已经是够快的了 
      

  11.   

    楼主精神可嘉觉得Java对操作系统文件流控制的有限。。JNI可以看看