2017-06-17 11 views
1

Apache Commons VFS Utilityを使用してSFTPサーバーからファイルをコピーしようとしています。SFTPからのコピーがApache Commons VFSで中断されました。

コピー中に、ネットワークに障害が発生した場合は、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> 
+0

コードを見ると、いくつかの問題があります。「try-catch」にはcatch節がありません。あなたが宣言したメソッドは例外をスローしていますが、どこにキャッチされていますか? – Adonis

+0

私はクライアントコードでそれらをキャッチしています。 – arnabkaycee

+0

特定のファイルで系統的ですか?それとも、それは時々起こるのでしょうか?それとも、これは一回限りの事故ですか? –

答えて

0

私はあなたが最終的に真の例外をマスクに問題の古典的な例かもしれないと思います。あなたのネットワーク接続が落ちてしまった場合、最終的にブロックされた問題を解決することに問題があると私は思っています。 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ブロックで発生した例外を覚えておいてください。

+0

私はすでにlocalToRemoteCopyメソッドからFileSystemExceptionをスローしています。このメソッドで例外を早期にキャッチすると、クライアントコードが誤動作する可能性があります。 ExceptionをスローしたAPIコードがあれば、私のクライアントコードは間違いなくそれを捕らえていたでしょう。これは、APIが半分のコピーされたファイルで例外をスローしていない場合です。 – arnabkaycee

+0

VFSには、FileUtil.copyContent https://issues.apache.org/jira/browse/VFS-446を使用しているときに、ネットワークが中断してもAPIが例外をスローしないという問題が記録されているようです。チケットでは、オリジネーターがJavaの先物と独自のループ構造を利用していることも確認できます。 –

0

私は、手動の回避策で、ソースファイルと宛先ファイルのチェックサムを一致させ、チェックサムが異なる場合に例外をスローすることで、この問題を解決することを考えていました。

関連する問題