ChannelSftp.cd(path)时总是抛出com.jcraft.jsch.ChannelSftp.throwStatusError

在项目中遇到了这个问题   转自    https://blog.csdn.net/qq_34721505/article/details/78262673

package com.summer.util;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
 
/**
 * 通过SFTP通道实现文件的上传与下载
 * API在线文档:
 * 		http://epaul.github.io/jsch-documentation/javadoc/com/jcraft/jsch/ChannelSftp.html
 * @author Administrator
 * 
 */
public class SFTPUtil {
 
	private Logger log = Logger.getLogger(SFTPUtil.class);
	private static Session session;
	private static Channel channel;
	private static ChannelSftp sftp;
 
	/**
	 * 创建SFTP通道
	 * 
	 * @param username
	 *            访问SFTP服务器的用户名
	 * @param host
	 *            SFTP服务器的IP
	 * @param port
	 *            SFTP服务器的端口号
	 * @param password
	 *            访问SFTP服务器的密码
	 * @param timeOut
	 *            访问SFTP服务器超时时间,单位:毫秒
	 */
	public ChannelSftp getSFTPConnection(String username, String host,
			int port, String password, int timeOut) {
 
		try {
			JSch jsch = new JSch();
			// 参数为sftp服务器的IP、PORT、USERNAME、PASSWORD
			// getSession(String username, String host, int port), 默认端口号是22
			session = jsch.getSession(username, host, port);
			session.setPassword(password);
			Properties config = new Properties();
			// Jsch优先使用RSA key type密钥的方式登陆
			// 此处使用用户名和密码方式登录
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);
			// 设置访问超时时间
			session.connect();
			log.info("连接会话开启成功!");
			// 创建sftp通信通道
			channel = session.openChannel("sftp");
			channel.connect();
			log.info("SFTP连接成功");
 
			sftp = (ChannelSftp) channel;
 
			// sftp.quit();
		} catch (JSchException e) {
			log.error("创建sftp通道失败");
			log.error(e.getMessage());
		} finally {
			// sftp通道需返回给调用者,所以fianlly中不能关闭,需在调用后关闭
			/*
			 * if (sftp != null) sftp.disconnect(); if (channel != null)
			 * channel.disconnect(); if (session != null) session.disconnect();
			 */
		}
		return sftp;
	}
 
	/**
	 * 使用SFTP通道上传文件
	 * 
	 * @param sftp
	 * @param sourceFile
	 *            要上传的源文件
	 * @param destFile
	 *            目标文件
	 * @return 上传成功返回true,失败返回false
	 */
	public boolean fileUpload(ChannelSftp sftp, String sourceFile,
			String destFile) {
 
		OutputStream outstream = null;
		InputStream instream = null;
		try {
			// 以下代码实现从本地上传一个文件到服务器/usr/uploadFileName.txt文件,如果要实现下载,对换以下流就可以了
			outstream = sftp.put(destFile);
			instream = new FileInputStream(new File(sourceFile));
 
			byte b[] = new byte[1024];
			int n;
			while ((n = instream.read(b)) != -1) {
				outstream.write(b, 0, n);
			}
 
			outstream.flush();
			log.info("文件上传成功");
			return true;
			// sftp.disconnect();
			// sftp.quit();
		} catch (IOException e) {
			log.error("文件上传失败");
			log.error(e.getMessage());
			return false;
		} catch (SftpException e) {
			log.error("文件上传失败");
			log.error(e.getMessage());
			return false;
		} finally {
			try {
				if (instream != null)
					instream.close();
				if (outstream != null)
					outstream.close();
				if (sftp != null)
					sftp.disconnect();
			} catch (IOException e) {
				log.error("关闭流失败");
				log.error(e.getMessage());
			}
		}
	}
 
	/**
	 * 断开连接,关闭资源
	 */
	public void close() {
		//closes this channel.
		if (sftp != null)
			sftp.disconnect();
		if (channel != null)
			channel.disconnect();
		if (session != null)
			session.disconnect();
	}
 
	/**
	 * 测试
	 * @param args
	 * @throws SftpException 
	 * @throws UnsupportedEncodingException 
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws SftpException, UnsupportedEncodingException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		SFTPUtil util = new SFTPUtil();
		ChannelSftp sftp = util.getSFTPConnection("ftp", "192.168.11.*", 22,
					"ftp", 30000);
		
		Class cl = ChannelSftp.class;  
		Field field =cl.getDeclaredField("server_version");  
		field.setAccessible(true);  
		field.set(sftp, 2); 	
		sftp.setFilenameEncoding("GBK");		
		
	  /*1、文件分隔符使用/,而不要使用\\;
		2、添加第167-171行代码;
		3、将路径配置成如下格式:F:/银监会文件交换服务客户端/F049H101331104001/最高人民法院/Download	*/
		String path = "F:/银监会文件交换服务客户端/F049H101331104001/最高人民法院/Download";
		
		sftp.cd(path);
		
		util.close();
	}
 
}

Exception in thread "main" 0: Failure

at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2836)
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2327)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
at com.summer.util.SFTPUtil.main(SFTPUtil.java:178)

Failure说明路径错误;Success说明路径正确,但字符集不对;

Exception in thread "main" 0: Success
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2833)
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2327)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
at com.summer.util.SFTPUtil.main(SFTPUtil.java:177)

在测试过程中几次遇到如上所示异常信息:出现该异常的原因可能有以下几种情况:

1、ChannelSftp.cd(path)中的路径path不存在,比如写错文件或文件夹的名称等;

解决方法:仔细检查path路径是否正确;

2、ChannelSftp中默认的FilenameEncoding为UTF-8,path所在操作系统的字符集不是UTF-8;

解决方法:添加如下代码
 

Class cl = ChannelSftp.class;  
Field field =cl.getDeclaredField("server_version");  
field.setAccessible(true);  
field.set(sftp, 2); 	
sftp.setFilenameEncoding("GBK");

"GBK"是path路径所在操作系统字符集,以win7为例,查看操作系统字符集方法如下:

开始-->运行-->cmd,打开DOS命令窗口,右键“标题栏”-->属性-->选项,即可看到操作系统字符集

3、path路径格式不对,比如文件分隔符使用"\\";

解决方法:文件分隔符请使用“/”,例:F:/银监会文件交换服务客户端/F049H101331104001/最高人民法院/Download

4、path路径格式不对,比如path=/D/APPS/apps_srv/LOCALAPP/TFRM/test//最高民人法高/Download

解决方法:请使用正确的系统路径,比如path=F:/银监会文件交换服务客户端/F049H101331104001/最高人民法院/Download
 

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值