【发布时间】:2013-06-11 04:05:26
【问题描述】:
我正在开发一个小程序以允许从 web 应用进行 FTP 上传...
发送操作正常,但我希望能够取消正在进行的文件存储。
我对线程不是很流利。我的第一次尝试是在取消线程中调用 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();
【问题讨论】:
-
是的,如果 commons net FTPClient 有 API 来中止传输,例如使用复制侦听器,您可以返回一个布尔值作为 false 中止传输。
-
不要考虑中断线程,而是尝试使 ftp = new FTPClient() 可访问。当用户单击取消按钮时,向该按钮添加一个事件,该事件将获取 ftp 并在 ftp 实例上运行方法 abor()。
标签: java ftp apache-commons-net