2017-04-02 126 views
0

我正在使用SSH,JSCH的Java實現來執行從遠程到本地的scp。按照JSCH示例代碼到scpfrom我可以接收文件。我已經使用了與上述鏈接相同的實現。SCP使用JSCH的二進制文件

問題: 發送的壓縮文件/照片已損壞。文本文件顯示相同。但是,當我發送二進制文件(如.tgz)時,解壓縮程序會抱怨文件已損壞。我懷疑這是一個二進制vs ascii問題。這是否因爲我正在將數據寫入Java文件?如何使用JSCH正確接收和寫入二進制文件?

我寫的代碼 -

private void executeCommand(String username, String pwd, String hostname, int port) 
     throws JSchException, IOException { 
    JSch jSch = new JSch(); 
    Session session = jSch.getSession(username, hostname, port); 
    session.setPassword(pwd); 

    Properties properties = new Properties(); 
    properties.put("StrictHostKeyChecking", "no"); 
    session.setConfig(properties); 

    session.connect(); 

    ChannelExec channelExec = (ChannelExec) session.openChannel("exec"); 
    channelExec.setCommand("scp -f /home/rish/haha.txt"); 

    OutputStream outputStream = channelExec.getOutputStream(); 
    DataInputStream inputStream = new DataInputStream(channelExec.getInputStream()); 
    DataOutputStream fos; 

    channelExec.connect(); 

    byte[] buf = new byte[1024]; 

    buf[0] = 0; 
    outputStream.write(buf, 0, 1); 
    outputStream.flush(); 

    while (true) { 
     int c = checkAck(inputStream); 
     if (c != 'C') { 
      break; 
     } 

     // read '0644 ' 
     inputStream.read(buf, 0, 5); 

     long filesize = 0L; 
     while (true) { 
      if (inputStream.read(buf, 0, 1) < 0) { 
       // error 
       break; 
      } 
      if (buf[0] == ' ') break; 
      filesize = filesize * 10L + (long) (buf[0] - '0'); 
     } 

     String file = null; 
     for (int i = 0; ; i++) { 
      inputStream.read(buf, i, 1); 
      if (buf[i] == (byte) 0x0a) { 
       file = new String(buf, 0, i); 
       break; 
      } 
     } 

     // send '\0' 
     buf[0] = 0; 
     outputStream.write(buf, 0, 1); 
     outputStream.flush(); 

     // String fileName = "/data/data/" + getPackageName() + "/crearofile" + new Random().nextInt(100) + ".txt"; 
     String fileName = "/data/data/rish.crearo.trial/haha.txt"; 

     File file1 = new File(fileName); 
     if (file1.exists()) file1.delete(); 
     if (file1.createNewFile()) Log.d(TAG, "File created"); 
     else Log.d(TAG, "File not created"); 

     // read a content of lfile 
     fos = new DataOutputStream(new FileOutputStream(fileName)); 

     String count; 
     while ((count = inputStream.readUTF()) != null) { 
      System.out.println(count); 
      fos.writeBytes(count); 
     } 
     fos.close(); 

     if (checkAck(inputStream) != 0) { 
      System.exit(0); 
     } 

     inputStream.close(); 
     // send '\0' 
     buf[0] = 0; 
     outputStream.write(buf, 0, 1); 
     outputStream.flush(); 
    } 

    session.disconnect(); 
} 
+0

要添加到上面,我已經試過纏繞一個DataInputStream/DataOutputStream類我inputstreams和outputstreams。沒有幫助! –

+0

請提供確切的最小代碼片段+數據源/文件,以便重現您的問題 –

+0

您是否看到http://stackoverflow.com/questions/40066370/jsch-scp-file-transfer-using-exec-channel? – 2017-04-02 18:05:09

回答

0

你已經發布的代碼是不一樣的ScpFrom.java example

您顯然無法在二進制文件上使用inputStream.readUTF()。 UTF是文本編碼。任何使用任何編碼解釋二進制文件的嘗試都會破壞它(或者實際上在這種情況下,UTF解碼器會破壞二進制數據,提前終止文件傳輸)。

實際上,該代碼甚至不能用於文本文件,因爲您不檢查下載數據的大小(您從不使用filesize值)。所以你可以閱讀文件結束。雖然它可能偶然地工作,因爲UTF解碼器可能會在文件內容之後在NULL終止符處中斷。

(據我所知,這可能是其實你試圖要解決一些另外一個問題)