使用 Util.copyStream 的带有进度条的 FTP - JAVA

Posted

技术标签:

【中文标题】使用 Util.copyStream 的带有进度条的 FTP - JAVA【英文标题】:FTP with progress bar using Util.copyStream - JAVA 【发布时间】:2013-09-20 02:56:11 【问题描述】:

我正在使用 Util.copyStream() 通过 FTP 上传文件。它在进度条上显示进度,但是当我尝试通过 FTP 客户端(例如 FileZilla)查看文件时,它不存在。谁能帮帮我?

这是 FTPUpload 类:

    package restrictedareamanager;

    import java.awt.HeadlessException;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import javax.swing.JOptionPane;
    import javax.swing.SwingWorker;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    import org.apache.commons.net.io.CopyStreamAdapter;
    import org.apache.commons.net.io.CopyStreamEvent;
    import org.apache.commons.net.io.CopyStreamListener;
    import org.apache.commons.net.io.Util;

    public class FTPUploader extends SwingWorker <Object,Object> 

        private String servidor;
        private String usuario;
        private String senha;
        private String titulo;
        private String subtitulo;
        private File dest;

    public FTPUploader (String servidor, String usuario, String senha, String titulo, String subtitulo, File dest) 

        this.servidor = servidor;
        this.usuario = usuario;
        this.senha = senha;
        this.titulo = titulo;
        this.subtitulo = subtitulo;
        this.dest = dest;

       

    @Override
    protected Object doInBackground() throws Exception 

    FTPClient ftp = new FTPClient ();
    final ProgressBar bar = ProgressBar.getInstancia();   

                try   
                 ftp.connect(servidor);  

                 //verifica se conectou com sucesso!  
                 if( FTPReply.isPositiveCompletion( ftp.getReplyCode() ) )   
                     ftp.login (usuario, senha);  
                  else   
                     //erro ao se conectar  
                     ftp.disconnect();  
                     JOptionPane.showMessageDialog(null, "Ocorreu um erro ao se conectar com o servidor FTP", "Erro", JOptionPane.ERROR_MESSAGE);    
                     System.exit(1);  
                   

                     ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
                     ftp.changeWorkingDirectory("/download");
                     ftp.changeWorkingDirectory(this.titulo);
                     ftp.changeWorkingDirectory (this.subtitulo);

                     bar.setLabel1("Sending " + dest.getName());
                     bar.setLabel2("To " + this.servidor + "/download" + "/" + titulo + "/" + subtitulo);
                     bar.setLabel3 ("Progress: ");

                     OutputStream output = new BufferedOutputStream(ftp.storeFileStream(dest.getName().toString()));
                     CopyStreamListener listener = new CopyStreamListener() 

                            @Override
                            public void bytesTransferred(final long totalBytesTransferred, final int bytesTransferred, final long streamSize) 
                            setProgress((int) Math.round(((double) totalBytesTransferred / (double) streamSize) * 100d));
                            

                            @Override
                            public void bytesTransferred(CopyStreamEvent arg0) 
                            // TODO Auto-generated method stub
                            

                      ;

                        Util.copyStream(new FileInputStream(dest), output , ftp.getBufferSize(), dest.length(), listener);
                        //ftp.storeFile (dest.getName(), new FileInputStream (dest.getPath().toString()));
                        ftp.logout();
                        ftp.disconnect(); 

                  catch( IOException | HeadlessException e )   
                     JOptionPane.showMessageDialog(null, "Ocorreu um erro ao enviar o arquivo.", "Erro", JOptionPane.ERROR_MESSAGE);  
                     System.exit(1);
                  catch (Exception e) 
                     System.out.println (e.toString());
                 


       bar.dispose();
       return null;
    

    

【问题讨论】:

“文件”是什么意思?你什么时候看? 您是否尝试过关闭流? chrylis 它不在应有的目录中。 @MadProgrammer 是的,我试过了。顺便说一句,ftp.storeFile 工作得很好,但这不会更新 progressBar 【参考方案1】:

storeFileStream 的 JavaDocs 说您必须在完成后关闭流。我不你这样做。这可能是一个很好的起点。除了非常冗长之外,您的代码看起来非常可靠。

我不使用侦听器或流,但我一直使用此代码通过 FTP 发送文件并且它可以工作。

注意ftpFTPClient 的一个实例

/**
 * Transmits a file to the FTP server
 * @param filePath The location on the server to place the file
 * @param data The contents of the file
 * @return True if the operation completes successfully, false otherwise
 */
public boolean send(String filePath, byte[] data)

    if(isConnected() == false)
    
        logger.log(Level.WARNING, "Attempting operation when not connected to FTP Server");
        return false;
    

    try 
    
        boolean success =  ftp.storeFile(filePath, new ByteArrayInputStream(data));
        if(success)
        
            logger.log(Level.FINEST, "Succesfully transmitted file: " + filePath);
            return true;
        
        else
        
            logger.log(Level.WARNING, "Could not transmit file: " + filePath);
            logger.log(Level.WARNING, getLastReply());
            return false;
        
     
    catch (IOException ex) 
    
        logger.log(Level.SEVERE, "Could not transmit file: " + filePath, ex);
        return false;
    

【讨论】:

感谢您的回答!试图关闭流,但仍然无法正常工作。你用的是ftp.storeFile()函数,但是我不能用这个函数更新progressBar,所以必须实现Util.copyStream(),或者另外一个……

以上是关于使用 Util.copyStream 的带有进度条的 FTP - JAVA的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义列表的进度条

带有图像和圆形进度条的圆形按钮

在 Xamarin Forms 中下载带有进度条的文件

请问进度条上方带有文字进度、并且跟随进度条移动的进度条该怎么实现?

带有进度条下载更新的自定义 UITableViewCell

带有进度条的 jQuery ajax 上传 - 没有 flash