SCP使用JSCH的二进制文件

时间:2017-04-02 16:07:40

标签: java android jsch

我正在使用SSH的Java实现,JSCH从远程到本地执行scp。遵循JSCH示例代码到scpfrom我能够接收文件。我使用了与上面链接相同的实现。

问题: 发送的压缩文件/照片已损坏。文本文件显示相同。但是,当我发送二进制文件(如.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();
}

1 个答案:

答案 0 :(得分:0)

您发布的代码与ScpFrom.java example中的代码不同。

你显然不能在二进制文件上使用inputStream.readUTF()。 UTF是文本编码。任何使用任何编码解释二进制文件的尝试都会破坏它(或者实际上在这种情况下,UTF解码器会破坏二进制数据,过早地终止文件传输)。

实际上,代码甚至不能用于文本文件,因为您不检查下载数据的大小(您从不使用filesize值)。所以你可以阅读文件结束之外的内容。虽然它可能偶然起作用,因为UTF解码器可能在文件内容之后打破NULL终止符。

(我知道这可能实际上是你试图解决另一个问题)