Apache Commons Net FTPClient abort file store
Asked Answered
H

1

7

I'm developing an applet to allow FTP upload from a webapp...

The send operation is working fine, but I'd like to able to cancel a file storing in progress.

I'm not very fluent with threads. My first attempt was to call ftp.abort() in the cancel thread, but the abort method was only called when the storeFile method finished, like if the send thread was locking the ftp object.

So I changed the code to interrupt the send thread and check it in the copy stream listener. The file storing stops as expected, but ftp.abort() call hangs the application, it never complete.

Any ideas?

Thanks, Philip

Send operation:

  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();

Cancel operation:

botaoCancelar.setEnabled(false);

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

  }).start();
Highkeyed answered 14/6, 2013 at 13:28 Comment(2)
Yeah would be nice if commons net FTPClient had API to abort a transfer, for example using the copy listener, where you can return a boolean as false to abort the transfer.Incurious
Instead of thinking in terms interrupting the thread, try to make the ftp = new FTPClient() accessible. When the user clicks on the Cancel button, add a event to that button that will get the ftp and run the method abor() on the ftp instance.Selfsatisfied
H
2

interrupting a thread like this is not correct, it causes your thread to wait for some seconds at exactly which line that compiler is reading in your thread

the only way that you can abort your ftp upload is to make the thread sleep for some time

then abort your upload and wait for the thread to complete itself

see this :

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

    try {
        mFTP.abort();
    } catch (IOException e) {
        e.printStackTrace();
    }
} catch (NetworkOnMainThreadException e) {
    e.printStackTrace();
} 
Harmattan answered 10/10, 2015 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.