在Java中复制数据的速度更快?

时间:2012-12-06 16:35:13

标签: java performance file-io copy bufferedinputstream

我被赋予了从服务器复制数据的任务。我正在使用BufferedInputStream和输出流来复制数据,我正在逐字节地进行。即使它正在运行但复制数据需要花费很长时间,因为其中一些数据是100的MB,所以肯定它不会起作用。任何人都可以建议我Byte副本的Byte副本,以便我的代码可以复制几百MB的文件。 缓冲区是2048。

以下是我的代码的样子:

static void copyFiles(SmbFile[] files, String parent) throws IOException {

  SmbFileInputStream input = null;
  FileOutputStream output = null;
  BufferedInputStream buf_input = null;
  try {
    for (SmbFile f : files) {
      System.out.println("Working on files :" + f.getName());
      if (f.isDirectory()) {

        File folderToBeCreated = new File(parent+f.getName());
        if (!folderToBeCreated.exists()) {
          folderToBeCreated.mkdir();
          System.out.println("Folder name " + parent
                + f.getName() + "has been created");
        } else {
          System.out.println("exists");

        }

        copyFiles(f.listFiles(), parent +  f.getName());
      } else {

        input = (SmbFileInputStream) f.getInputStream();

        buf_input = new BufferedInputStream(input, BUFFER);

        File t = new File(parent + f.getName());
        if (!t.exists()) {
          t.createNewFile();
        }
        output = new FileOutputStream(t);

        int c;

        int count;
        byte data[] = new byte[BUFFER];

        while ((count = buf_input.read(data, 0, BUFFER)) != -1) {
          output.write(data, 0, count);
        }
      }
    }
  } catch (IOException e) {
    e.printStackTrace();

  } finally {
    if (input != null) {
      input.close();
    }
    if (output != null) {
      output.close();
    }
  }
}

5 个答案:

答案 0 :(得分:12)

以下是link to an excellent post解释如何使用nio频道制作流的副本。它引入了一个帮助方法ChannelTools.fastChannelCopy,可以让你像这样复制流:

final InputStream input = new FileInputStream(inputFile);
final OutputStream output = new FileOutputStream(outputFile);
final ReadableByteChannel inputChannel = Channels.newChannel(input);
final WriteableByteChannel outputChannel = Channels.newChannel(output);
ChannelTools.fastChannelCopy(inputChannel, outputChannel);
inputChannel.close();
outputChannel.close()

答案 1 :(得分:3)

好吧,因为您使用的是BufferedInputStream,所以您不是逐字节读取,而是缓冲区的大小。您可以尝试增加缓冲区大小。

答案 2 :(得分:1)

逐字节读/写肯定会变慢,即使实际的读/写是由缓冲区大小的块完成的。加快速度的一种方法是按块读/写。请查看read(byte[] b, int off, int len)的{​​{1}}方法。但是它可能不会给你足够的改进。

使用BufferedInputStream包(新IO)使用nio通道复制数据会更好。有关详细信息,请查看nio documentation

答案 3 :(得分:0)

看看这个link,它描述了在使用SmbFileInputStream时可以尝试提高性能的一些事项。

答案 4 :(得分:0)

我建议使用FileUtils中的org.apache.commons.io。它有足够的实用方法来执行文件操作。

org.apache.commons.io.FileUtils API Here