2012-12-06 25 views
3

我已经从服务器复制数据的任务。我使用BufferedInputStream和输出流来复制数据,我正在逐字节地做。即使它正在运行,但它需要很长时间才能复制数据,因为其中一些数据的大小为100 MB,所以绝对不会奏效。任何人都可以建议我任何字节副本的副本,以便我的代码可以复制几百MB的文件。 缓冲区是2048在Java中复制数据的更快捷方式?

下面是我的代码如下所示:

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(); 
    } 
    } 
} 
+1

分享你的代码。 – vels4j

+0

现在你已经显示了代码,除非BUFFER是1,否则你不会逐字节地读取数据。(你的异常处理可以做一些工作,顺便说一下......这几乎从来都不是合适的catch块。 ) –

+0

@JonSkeet你的意思是我应该把尽量捕捉每一个文件,这样即使一个文件失败,其余应该不会受到影响 – Dude

回答

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() 
+0

出现一些错误,是正确的? – Dude

+0

@Batman它可能是因为'Channels.newChannel'需要'InputStream','SmbFileInputStream'是'InputStream'。我一定会试一试。 – dasblinkenlight

+0

它的工作和摇摆:) – Dude

3

嘛,因为你使用的是BufferedInputStream,你是不是按字节读取字节,而是缓冲区的大小。你可以尝试增加缓冲区大小。

1

读/写逐字节是肯定会是缓慢的,即使实际读取/写入通过缓冲块进行尺寸。加速它的一种方法是按块读取/写入。看看read(byte[] b, int off, int len)方法BufferedInputStream。但它可能不会给你足够的改进。

是什么更好的方法是使用nio包(新的IO)复制使用NIO渠道的数据。有关更多信息,请参阅nio documentation

0

看看这个link描述有些事情你可以尝试用SmbFileInputStream工作时来提高性能。