繁体   English   中英

使用Apache Commons VFS中断从SFTP中复制

[英]Copy from SFTP interrupted using Apache Commons VFS

我正在尝试使用Apache Commons VFS Utility从SFTP服务器复制文件。

复制时,如果有任何类型的网络故障,我预计会收到IOException 但我无法找到任何抛出的异常(检查我的日志)。 因此,我找到了一半被复制的文件。 (试过文本文件。)下面是代码片段:

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

}

如果我查看源代码,它会抛出异常。

/**
     * 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);
            }
        }
    }

我正在使用以下依赖项:

        <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>

我认为你可能是一个经典的例子,你最终掩盖了真正的例外。 我怀疑如果你的网络连接丢失,那么你在finally块中清理问题也是有问题的。 您是否可以尝试修改finally块,以便在finally块中发生异常时实际捕获异常?

更改

} finally {
        if(null != localFileObject ){
        localFileObject.close();
        }
        if(null != remoteFileObject ){
        remoteFileObject.close();
        }
}

} 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 }
        }
}

请记住,finally块中引发的异常将隐藏主块中抛出的异常。

我正在考虑通过手动解决方法解决此问题,通过对源文件和目标文件进行校验和匹配,然后在校验和不同时抛出异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM