Копирование из 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, скрывает исключение, которое выдается в вашем основном блоке.