加快java中的复制速度

时间:2014-03-28 06:54:54

标签: java

我的程序正在将所有数据从外部驱动器复制到我的电脑上的特定位置。

这是我的计划: -

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy 
{
public static void main(String[] args)
{
    String[] letters = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I"};
    File[] drives = new File[letters.length];
    int copy=0;int l;File files[]=null;boolean pluggedIn=false;
    FileInputStream fis=null;
    FileOutputStream fos=null;

    boolean[] isDrive = new boolean[letters.length];
    for (int i = 0; i < letters.length; ++i) 
    {
        drives[i] = new File(letters[i] + ":/");
        isDrive[i] = drives[i].canRead();
    }
    System.out.println("FindDrive: waiting for devices...");
    while (true) 
    {
        try 
        {
        for (int i = 0; i < letters.length; ++i) 
        {
            pluggedIn = drives[i].canRead();
            if (pluggedIn != isDrive[i]) 
            {
                if (pluggedIn) 
                {
                    System.out.println("Drive " + letters[i] + " has been plugged in");
                    files = drives[i].getAbsoluteFile().listFiles();
                    File file;
                    int fread;
                    for (l = 0; l < files.length; l++) 
                    {
                        if (files[l].isFile()) 
                        {
                            file = new File("G://copied//" + files[l].getName());

                                file.createNewFile();
                                fis = new FileInputStream(drives[i].getAbsolutePath() + files[l].getName());
                                fos = new FileOutputStream(file);
                                while (true) 
                                {
                                    fread = fis.read();
                                    if (fread == -1) 
                                    {
                                        break;
                                    }
                                    fos.write(fread);
                                }
                        }
                        else 
                        {
                            func(files[l].getAbsoluteFile(), "G://copied");
                        }
                        if(l==files.length-1)
                        {
                            System.out.print("copy complete");
                            fos.close();
                            fis.close();
                        }
                   }
                } 
                else 
                {
                    System.out.println("Drive " + letters[i] + " has been unplugged");
                }
                isDrive[i] = pluggedIn;
            }
        }
        Thread.sleep(5000);
        }
        catch (FileNotFoundException e) { } 
        catch (IOException e) {  }
        catch (InterruptedException e) {}
    }
}
public static void func(File dir, String path) 
{
    File file = new File(path + "//" + dir.getName());
    file.mkdir();
    File[] files = dir.listFiles();
    FileInputStream fis;
    FileOutputStream fos;
    int fread;
    File file1;
    for (int i = 0; i < files.length; i++) 
    {
        if (files[i].isFile()) 
        {
            file1 = new File(file.getAbsolutePath() + "//" + files[i].getName());
            try 
            {
                file1.createNewFile();
                fis = new FileInputStream(files[i]);
                fos = new FileOutputStream(file1);
                while (true) 
                {
                    fread = fis.read();
                    if (fread == -1) 
                    {
                        break;
                    }
                    fos.write(fread);
                }
            } catch (FileNotFoundException e) {} catch (IOException e) {}
        } 
        else 
        {
            func(files[i], file.getAbsolutePath());
        }
    }
}
}

现在复制大文件需要很长时间。

有没有办法可以更快地执行复制操作?

提前填写任何建议。

3 个答案:

答案 0 :(得分:8)

如果您可以使用Java 7或更高版本:java.nio.file.Files#copy

如果您遇到旧Java:java.nio.channels.FileChannel#transferTo

从文件流中获取FileChannel个实例的基本示例:

public void copy( FileInputStream fis, FileOutputStream fos ) throws IOException {
    FileChannel fic = fis.getChannel();
    FileChannel foc = fos.getChannel();

    long position = 0;
    long remaining = fic.size();
    while ( remaining > 0 ) {
        long transferred = fic.transferTo( position, remaining, foc );
        position += transferred;
        remaining -= transferred;
    }
}

答案 1 :(得分:4)

你必须使用缓冲区。复制逻辑应该是这样的:

byte[] buffer = new byte[4096];
int n;
while ((n = input.read(buffer) != -1)
{
    output.write(buffer, 0, n);
}
output.close();
input.close();

这样,您可以一次复制4096个字节的块,而不是每个字节的字节。

答案 2 :(得分:1)

                            file.createNewFile();

删除它。这是多余的。 new FileOutputStream()无论如何都会这样做。你只是在这里添加处理,并在那里添加磁盘处理。

                            fis = new FileInputStream(drives[i].getAbsolutePath() + files[l].getName());
                            fos = new FileOutputStream(file);

现在添加:

int count;
byte[] buffer = new byte[8192]; // or much more if you can afford the space
while ((count = fis.read(buffer)) > 0)
{
    fos.write(buffer, 0, count);
}

返回您的代码:

                            while (true) 
                            {
                                fread = fis.read();
                                if (fread == -1) 
                                {
                                    break;
                                }
                                fos.write(fread);
                            }

删除所有内容。一次读取一个字节的效率低得多。