Java Apache Commons Net FTPClient中止文件存储

Java Apache Commons Net FTPClient中止文件存储,java,ftp,apache-commons-net,Java,Ftp,Apache Commons Net,我正在开发一个小程序,允许从webapp上传FTP 发送操作工作正常,但我希望能够取消正在存储的文件 我的线程不是很流利。我的第一次尝试是在cancel线程中调用ftp.abort(),但是只有在storeFile方法完成时才会调用abort方法,就像发送线程锁定ftp对象一样 因此,我更改了代码以中断发送线程,并在复制流侦听器中检查它。文件存储会按预期停止,但ftp.abort()调用会挂起应用程序,它永远不会完成 有什么想法吗 谢谢, 菲利浦 发送操作: botaoEnviar.setE

我正在开发一个小程序,允许从webapp上传FTP

发送操作工作正常,但我希望能够取消正在存储的文件

我的线程不是很流利。我的第一次尝试是在cancel线程中调用ftp.abort(),但是只有在storeFile方法完成时才会调用abort方法,就像发送线程锁定ftp对象一样

因此,我更改了代码以中断发送线程,并在复制流侦听器中检查它。文件存储会按预期停止,但ftp.abort()调用会挂起应用程序,它永远不会完成

有什么想法吗

谢谢, 菲利浦

发送操作:

  botaoEnviar.setEnabled(false);
  botaoCancelar.setEnabled(true);
  textField.requestFocus();

  threadEnvio = new Thread(new Runnable()
  {
     @Override
     public void run()
     {            
        FileInputStream fis = null;
        try
        {
           if(arquivoSelecionado == null)
           {
              throw new IllegalArgumentException("Arquivo deve ser informado");
           }

           try
           {
              ftp = new FTPClient();
              ftp.connect("192.168.1.243");
           }
           catch(Exception e)
           {
              throw new FtpConnectionException("Não foi possível conectar no servidor FTP", e);
           }

           if(!ftp.login("c001", "0AJF2J36"))
           {
              throw new IllegalArgumentException("Não foi possível autenticar no servidor FTP");
           }

           ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

           ftp.setCopyStreamListener(new CopyStreamAdapter()
           {                  
              @Override
              public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize)
              {
                 if(threadEnvio.isInterrupted())
                 {
                    try
                    {
                       ftp.abort();                           
                    }
                    catch(IOException ex)
                    {
                       handleException(ex);
                    }
                 }
                 else
                 {
                    int percent = (int) (totalBytesTransferred * 100 / arquivoSelecionado.length());
                    progressBar.setValue(percent);
                 }
              }
           });

           fis = new FileInputStream(arquivoSelecionado);               
           if(ftp.storeFile(arquivoSelecionado.getName(), fis))
           {
              JOptionPane.showMessageDialog(null, "Arquivo enviado com suceso");
           }
           else
           {
              JOptionPane.showMessageDialog(null, "Não foi possível enviar o arquivo", "Erro", JOptionPane.ERROR_MESSAGE);
           }

           ftp.logout();
        }            
        catch(Exception e)
        {
           handleException(e);
        }
        finally
        {
           if(fis != null)
           {
              try
              {
                 fis.close();
              }
              catch(IOException ex)
              {
                 handleException(ex);
              }
           }

           if(ftp != null)
           {
              try
              {
                 ftp.disconnect();
              }
              catch(IOException ex)
              {
                 handleException(ex);
              }
           }

           progressBar.setValue(0);
           botaoEnviar.setEnabled(true);               
           botaoCancelar.setEnabled(false);               
        }
     }
  });
  threadEnvio.start();
botaoCancelar.setEnabled(false);

  new Thread(new Runnable()
  {
     @Override
     public void run()
     {
        try
        {               
           threadEnvio.interrupt();
        }
        catch(Exception ex)
        {
           handleException(ex);
        }
        finally
        {
           botaoCancelar.setEnabled(true);               
        }
     }

  }).start();
取消操作:

  botaoEnviar.setEnabled(false);
  botaoCancelar.setEnabled(true);
  textField.requestFocus();

  threadEnvio = new Thread(new Runnable()
  {
     @Override
     public void run()
     {            
        FileInputStream fis = null;
        try
        {
           if(arquivoSelecionado == null)
           {
              throw new IllegalArgumentException("Arquivo deve ser informado");
           }

           try
           {
              ftp = new FTPClient();
              ftp.connect("192.168.1.243");
           }
           catch(Exception e)
           {
              throw new FtpConnectionException("Não foi possível conectar no servidor FTP", e);
           }

           if(!ftp.login("c001", "0AJF2J36"))
           {
              throw new IllegalArgumentException("Não foi possível autenticar no servidor FTP");
           }

           ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

           ftp.setCopyStreamListener(new CopyStreamAdapter()
           {                  
              @Override
              public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize)
              {
                 if(threadEnvio.isInterrupted())
                 {
                    try
                    {
                       ftp.abort();                           
                    }
                    catch(IOException ex)
                    {
                       handleException(ex);
                    }
                 }
                 else
                 {
                    int percent = (int) (totalBytesTransferred * 100 / arquivoSelecionado.length());
                    progressBar.setValue(percent);
                 }
              }
           });

           fis = new FileInputStream(arquivoSelecionado);               
           if(ftp.storeFile(arquivoSelecionado.getName(), fis))
           {
              JOptionPane.showMessageDialog(null, "Arquivo enviado com suceso");
           }
           else
           {
              JOptionPane.showMessageDialog(null, "Não foi possível enviar o arquivo", "Erro", JOptionPane.ERROR_MESSAGE);
           }

           ftp.logout();
        }            
        catch(Exception e)
        {
           handleException(e);
        }
        finally
        {
           if(fis != null)
           {
              try
              {
                 fis.close();
              }
              catch(IOException ex)
              {
                 handleException(ex);
              }
           }

           if(ftp != null)
           {
              try
              {
                 ftp.disconnect();
              }
              catch(IOException ex)
              {
                 handleException(ex);
              }
           }

           progressBar.setValue(0);
           botaoEnviar.setEnabled(true);               
           botaoCancelar.setEnabled(false);               
        }
     }
  });
  threadEnvio.start();
botaoCancelar.setEnabled(false);

  new Thread(new Runnable()
  {
     @Override
     public void run()
     {
        try
        {               
           threadEnvio.interrupt();
        }
        catch(Exception ex)
        {
           handleException(ex);
        }
        finally
        {
           botaoCancelar.setEnabled(true);               
        }
     }

  }).start();

像这样中断一个线程是不正确的,它会导致你的线程在编译器正在你的线程中读取的那一行等待几秒(甚至几毫秒)
中止ftp上传的唯一方法是让线程休眠一段时间,然后中止上传,最后等待线程自行完成
请参见:

   try {
            try {
                    Thread.currentThread();
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } 

            try {
                    mFTP.abort();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    } catch (NetworkOnMainThreadException e) {

    }

是的,如果commons net FTPClient具有中止传输的API,那就太好了,例如使用复制侦听器,您可以将布尔值返回为false以中止传输。与其考虑中断线程,不如尝试使ftp=new FTPClient()可访问。当用户单击Cancel按钮时,向该按钮添加一个事件,该事件将获取ftp并在ftp实例上运行该方法。