我正在使用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();
}
答案 0 :(得分:0)
您发布的代码与ScpFrom.java example中的代码不同。
你显然不能在二进制文件上使用inputStream.readUTF()
。 UTF是文本编码。任何使用任何编码解释二进制文件的尝试都会破坏它(或者实际上在这种情况下,UTF解码器会破坏二进制数据,过早地终止文件传输)。
实际上,代码甚至不能用于文本文件,因为您不检查下载数据的大小(您从不使用filesize
值)。所以你可以阅读文件结束之外的内容。虽然它可能偶然起作用,因为UTF解码器可能在文件内容之后打破NULL终止符。
(我知道这可能实际上是你试图解决另一个问题)