[英]Copy from SFTP interrupted using Apache Commons VFS
I am trying to copy a file from an SFTP server using Apache Commons VFS Utility. 我正在尝试使用Apache Commons VFS Utility从SFTP服务器复制文件。
While copying, if there is any type of network failure, it is expected that I will get an IOException
. 复制时,如果有任何类型的网络故障,我预计会收到IOException
。 But I am unable to find any exception thrown (checked my logs). 但我无法找到任何抛出的异常(检查我的日志)。 Hence, I find a file that has been half copied. 因此,我找到了一半被复制的文件。 (Tried with text file.) Below is the code snippet: (试过文本文件。)下面是代码片段:
public class SFTPFileHandler implements IFileSystemHandler {
private String hostName;
private String userName;
private String password;
private String knownHost;
private String privateKey;
private FileSystemOptions fileSystemOptions;
private StandardFileSystemManager fileSystemManager;
private FileObject remoteRootDirectory;
private boolean initialized = false;
private FileType fileType;
//code to initialize stuff
....
/**
* Method to Connect to the Server
*
* @throws URISyntaxException
* @throws FileSystemException
* @throws FileHandlerInitializationException
*/
private void connect() throws URISyntaxException, FileSystemException, FileHandlerInitializationException {
createDefaultOptions();
String connectionUrl = buildConnectionUrl();
remoteRootDirectory = fileSystemManager.resolveFile(connectionUrl,fileSystemOptions);
}
/**
* Method to copy a from the local file system to SFTP server
*/
public void localToRemoteCopy(String srcPath, String destPath) throws FileSystemException {
LocalFile localFileObject = null;
FileObject remoteFileObject = null;
try {
localFileObject = (LocalFile) fileSystemManager
.resolveFile(srcPath);
remoteFileObject = remoteRootDirectory.resolveFile(destPath);
remoteFileObject.copyFrom(localFileObject, new AllFileSelector());
} finally {
if(null != localFileObject ){
localFileObject.close();
}
if(null != remoteFileObject ){
remoteFileObject.close();
}
}
}
// other code
}
And if I look at the source, it does throw an exception. 如果我查看源代码,它会抛出异常。
/**
* Copies another file to this file.
* @param file The FileObject to copy.
* @param selector The FileSelector.
* @throws FileSystemException if an error occurs.
*/
public void copyFrom(final FileObject file, final FileSelector selector)
throws FileSystemException
{
if (!file.exists())
{
throw new FileSystemException("vfs.provider/copy-missing-file.error", file);
}
/* we do not alway know if a file is writeable
if (!isWriteable())
{
throw new FileSystemException("vfs.provider/copy-read-only.error", new Object[]{file.getType(),
file.getName(), this}, null);
}
*/
// Locate the files to copy across
final ArrayList<FileObject> files = new ArrayList<FileObject>();
file.findFiles(selector, false, files);
// Copy everything across
final int count = files.size();
for (int i = 0; i < count; i++)
{
final FileObject srcFile = files.get(i);
// Determine the destination file
final String relPath = file.getName().getRelativeName(srcFile.getName());
final FileObject destFile = resolveFile(relPath, NameScope.DESCENDENT_OR_SELF);
// Clean up the destination file, if necessary
if (destFile.exists() && destFile.getType() != srcFile.getType())
{
// The destination file exists, and is not of the same type,
// so delete it
// TODO - add a pluggable policy for deleting and overwriting existing files
destFile.delete(Selectors.SELECT_ALL);
}
// Copy across
try
{
if (srcFile.getType().hasContent())
{
FileUtil.copyContent(srcFile, destFile);
}
else if (srcFile.getType().hasChildren())
{
destFile.createFolder();
}
}
catch (final IOException e)
{
throw new FileSystemException("vfs.provider/copy-file.error", new Object[]{srcFile, destFile}, e);
}
}
}
and I am using the below dependencies: 我正在使用以下依赖项:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
I think you may be a classic example of an issue in your finally masking the true exception. 我认为你可能是一个经典的例子,你最终掩盖了真正的例外。 I suspect if your dropping network connectivity then you are problem having clean up issues in your finally block as well. 我怀疑如果你的网络连接丢失,那么你在finally块中清理问题也是有问题的。 Can you try modifying your finally block so you actually catch exceptions if they are occurring in your finally block? 您是否可以尝试修改finally块,以便在finally块中发生异常时实际捕获异常?
Change 更改
} finally {
if(null != localFileObject ){
localFileObject.close();
}
if(null != remoteFileObject ){
remoteFileObject.close();
}
}
to 至
} finally {
if(null != localFileObject ){
try {
localFileObject.close();
} catch (Exception ex) { //ignore or add just a logging call }
}
if(null != remoteFileObject ){
try {
remoteFileObject.close();
} catch (Exception ex) { //ignore or add just a logging call }
}
}
Remember an exception raised in a finally block will hide an exception thrown in your main block. 请记住,finally块中引发的异常将隐藏主块中抛出的异常。
我正在考虑通过手动解决方法解决此问题,通过对源文件和目标文件进行校验和匹配,然后在校验和不同时抛出异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.