简体   繁体   English

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

[英]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.

相关问题 使用Apache Commons Vfs2的SFTP文件传输 - SFTP file transfer using Apache Commons Vfs2 SFTP上传下载使用Apache Commons VFS进行存在和移动 - SFTP Upload Download Exist and Move using Apache Commons VFS 使用 Apache Commons VFS-SFTP,上传到服务器 - Using Apache Commons VFS- SFTP, uploading to a server 当使用 Apache Commons VFS 进行 SFTP 上传时,必须面对 org.apache.commons.vfs2.FileSystemException:找不到带有 URI 的文件 - When SFTP Upload using Apache Commons VFS have to face org.apache.commons.vfs2.FileSystemException: Could not find file with URI 如何修复使用 Apache Commons VFS 将文件上传到 SFTP 服务器时发生的错误 - How to fix error occurring while uploading file to SFTP server using Apache Commons VFS 使用 Apache Commons vfs2(spring boot) 的 SFTP 文件传输失败并出现 IOException:错误 - SFTP file transfer using Apache Commons vfs2(spring boot) fails with IOException: error org.apache.commons.vfs2.FileSystemException:无法连接到 SFTP 服务器 - org.apache.commons.vfs2.FileSystemException: Could not connect to SFTP server 使用apache vfs与相互身份验证进行sftp - sftp with mutual auth using apache vfs 如何使用commons-VFS在SFTP期间跳过密码提示 - How to skip password prompt during SFTP using commons-VFS Apache Commons VFS 与 Quercus - Apache Commons VFS with Quercus
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM