Копирование из SFTP прервано с помощью Apache Commons VFS

Я пытаюсь скопировать файл с SFTP-сервера с помощью Apache Commons VFS Utility.

При копировании, если есть какой-либо тип сбоя сети, ожидается, что я получу 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>

2 ответа

Я думал о том, чтобы решить эту проблему с помощью обходного пути вручную, выполнив сопоставление контрольной суммы исходного файла и файла назначения, а затем выдав исключение, если контрольная сумма отличается.

Я думаю, что вы можете быть классическим примером проблемы, когда вы, наконец, маскируете истинное исключение. Я подозреваю, что если вы отключили подключение к сети, то у вас проблемы с очисткой в ​​вашем блоке 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, скрывает исключение, которое выдается в вашем основном блоке.

Другие вопросы по тегам