JAVA利用commons.net.ftp.FTPClient的storeFileStream方法TXT文件上传. 已经转码UTF-16LE,上传后内容乱码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA利用commons.net.ftp.FTPClient的storeFileStream方法TXT文件上传. 已经转码UTF-16LE,上传后内容乱码相关的知识,希望对你有一定的参考价值。
字数限制所以没说清楚,抱歉。我上传的FTP服务器是Windows平台的.实现思路是先获取字符串数据,然后在本地LINUX服务器生成TXT文件(转码UTF-16LE),再利用FTPClient的storeFileStream方法把文件上传。
本地的TXT文件没乱码问题,利用FTP软件上传之后也是显示正常,JAVA项目的默认环境是UTF-8。
就是通过JAVA程序上传之后出现了乱码,感觉是转码问题,请高手指点,非常感谢~!
~~~~~~~
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: S
1、使用commons-net连接ftp报错,如下所示:
1 org.apache.commons.net.MalformedServerReplyException: Could not parse response code. 2 Server Reply: SSH-2.0-SSH 3 at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:344) 4 at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300) 5 at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:438) 6 at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:962) 7 at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:950) 8 at org.apache.commons.net.SocketClient._connect(SocketClient.java:244) 9 at org.apache.commons.net.SocketClient.connect(SocketClient.java:202) 10 at com.fline.security.adaptation.utils.FtpUtils.uploadFile(FtpUtils.java:63) 11 at com.fline.security.adaptation.utils.FtpUtils.main(FtpUtils.java:29)
其中,使用的commons-net的maven依赖,如下所示:
1 <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> 2 <dependency> 3 <groupId>commons-net</groupId> 4 <artifactId>commons-net</artifactId> 5 <version>3.6</version> 6 </dependency>
案例代码,参考:java 操作 vsftp 文件_彻底拆分,一切可控!-CSDN博客_java操作vsftp,如下所示:
1 package com.fline.security.adaptation.utils; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.OutputStream; 9 10 import org.apache.commons.net.ftp.FTPClient; 11 import org.apache.commons.net.ftp.FTPFile; 12 import org.apache.commons.net.ftp.FTPReply; 13 14 public class FtpUtils 15 16 public static void main(String[] args) throws Exception 17 18 // // =======上传测试============ 19 String localFile = "C:\\\\Users\\\\bhlgo\\\\Downloads\\\\中国.txt"; 20 21 String url = "ip地址"; 22 int port = 端口号; 23 String username = "账号"; 24 String password = "密码"; 25 String path = "目录"; 26 String filename = "中国.txt"; 27 InputStream input = new FileInputStream(new File(localFile)); 28 29 uploadFile(url, port, username, password, path, filename, input); 30 // // =======上传测试============ 31 32 // =======下载测试============ 33 // String localPath = "D:\\\\"; 34 // String url = "192.168.120.133"; 35 // int port = 21; 36 // String username ="ftpuser"; 37 // String password ="ftpuser"; 38 // String remotePath ="/data/admftp/kw"; 39 // String fileName = "test.txt"; 40 // downFile(url, port, username, password, remotePath, fileName, localPath); 41 // =======下载测试============ 42 43 44 45 /** 46 * Description: 向FTP服务器上传文件 47 * 48 * @param url FTP服务器 hostname 49 * @param port FTP服务器端口 默认端 21 50 * @param username FTP登录账号 51 * @param password FTP登录密码 52 * @param path FTP服务器保存目录 53 * @param filename 上传到FTP服务器上的文件名 54 * @param input 输入流 55 * @return 成功返回true,否则返回false 56 */ 57 public static boolean uploadFile(String url, int port, String username, String password, String path, 58 String filename, InputStream input) 59 boolean success = false; 60 FTPClient ftp = new FTPClient(); 61 try 62 int reply; 63 ftp.connect(url, port);// 连接FTP服务器 64 // ftp.connect(url);//连接FTP服务器 65 // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 66 ftp.login(username, password);// 登录 67 // ftp.setFileType(FTPClient.BINARY_FILE_TYPE); 68 // ftp.setControlEncoding("GBK"); 69 reply = ftp.getReplyCode(); 70 if (!FTPReply.isPositiveCompletion(reply)) 71 ftp.disconnect(); 72 return success; 73 74 ftp.changeWorkingDirectory(path); 75 // 设置文件名上传的编码格式为 utf-8 76 ftp.storeFile(new String(filename.getBytes("utf-8"), "iso-8859-1"), input); 77 78 input.close(); 79 ftp.logout(); 80 success = true; 81 catch (IOException e) 82 e.printStackTrace(); 83 finally 84 if (ftp.isConnected()) 85 try 86 ftp.disconnect(); 87 catch (IOException ioe) 88 89 90 91 return success; 92 93 94 /** 95 * Description: 从FTP服务器下载文件 96 * 97 * @param url FTP服务器hostname 98 * @param port FTP服务器端口 99 * @param username FTP登录账号 100 * @param password FTP登录密码 101 * @param remotePath FTP服务器上的相对路径 102 * @param fileName 要下载的文件名 103 * @param localPath 下载后保存到本地的路径 104 * @return 105 */ 106 public static boolean downFile(String url, int port, String username, String password, String remotePath, 107 String fileName, String localPath) 108 boolean success = false; 109 FTPClient ftp = new FTPClient(); 110 try 111 int reply; 112 ftp.connect(url, port); 113 // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器 114 ftp.login(username, password);// 登录 115 reply = ftp.getReplyCode(); 116 if (!FTPReply.isPositiveCompletion(reply)) 117 ftp.disconnect(); 118 return success; 119 120 ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录 121 FTPFile[] fs = ftp.listFiles(); 122 for (FTPFile ff : fs) 123 String remotFileName = new String(ff.getName().getBytes("iso-8859-1"), "utf-8"); 124 if (remotFileName.equals(fileName)) 125 File localFile = new File(localPath + "/" + remotFileName); 126 OutputStream is = new FileOutputStream(localFile); 127 ftp.retrieveFile(ff.getName(), is); 128 is.close(); 129 130 131 132 ftp.logout(); 133 success = true; 134 catch (IOException e) 135 e.printStackTrace(); 136 finally 137 if (ftp.isConnected()) 138 try 139 ftp.disconnect(); 140 catch (IOException ioe) 141 142 143 144 return success; 145 146 147
2、解决方法
使用com.jcraft.jsch.JSch提供的SSH解决方法,参考:java使用Jsch实现远程操作linux服务器进行文件上传、下载,删除和显示目录信息 - 别先生 - 博客园。代码如下:
1 package com.fline.aic.utils; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.InputStreamReader; 10 import java.util.Properties; 11 import java.util.Vector; 12 13 import com.jcraft.jsch.Channel; 14 import com.jcraft.jsch.ChannelExec; 15 import com.jcraft.jsch.ChannelSftp; 16 import com.jcraft.jsch.JSch; 17 import com.jcraft.jsch.JSchException; 18 import com.jcraft.jsch.Session; 19 import com.jcraft.jsch.SftpException; 20 21 /** 22 * 23 * @Description TODO 24 * @author biehl 25 * @Date 2018年10月11日 上午10:20:11 26 * 27 * 说明:exec用于执行命令;sftp用于文件处理 28 */ 29 public class SSHRemoteCall 30 31 // 私有的对象 32 private static SSHRemoteCall sshRemoteCall; 33 34 /** 35 * 私有的构造方法 36 */ 37 private SSHRemoteCall() 38 39 40 // 懒汉式,线程不安全,适合单线程 41 public static SSHRemoteCall getInstance() 42 if (sshRemoteCall == null) 43 sshRemoteCall = new SSHRemoteCall(); 44 45 return sshRemoteCall; 46 47 48 // 懒汉式,线程安全,适合多线程 49 public static synchronized SSHRemoteCall getInstance2() 50 if (sshRemoteCall == null) 51 sshRemoteCall = new SSHRemoteCall(); 52 53 return sshRemoteCall; 54 55 56 private static final int DEFAULT_PORT = 22;// 默认端口号 57 private int port;// 端口号 58 59 private static String ipAddress = "192.168.110.130";// ip地址 60 private static String userName = "root";// 账号 61 private static String password = "hadoop";// 密码 62 63 private Session session;// JSCH session 64 private boolean logined = false;// 是否登陆 65 66 /** 67 * 构造方法,可以直接使用DEFAULT_PORT 68 * 69 * @param ipAddress 70 * @param userName 71 * @param password 72 */ 73 public SSHRemoteCall(String ipAddress, String userName, String password) 74 this(ipAddress, DEFAULT_PORT, userName, password); 75 76 77 /** 78 * 构造方法,方便直接传入ipAddress,userName,password进行调用 79 * 80 * @param ipAddress 81 * @param port 82 * @param userName 83 * @param password 84 */ 85 public SSHRemoteCall(String ipAddress, int port, String userName, String password) 86 super(); 87 this.ipAddress = ipAddress; 88 this.userName = userName; 89 this.password = password; 90 this.port = port; 91 92 93 /** 94 * 远程登陆 95 * 96 * @throws Exception 97 */ 98 public void sshRemoteCallLogin(String ipAddress, String userName, String password) throws Exception 99 // 如果登陆就直接返回 100 if (logined) 101 return; 102 103 // 创建jSch对象 104 JSch jSch = new JSch(); 105 try 106 // 获取到jSch的session, 根据用户名、主机ip、端口号获取一个Session对象 107 session = jSch.getSession(userName, ipAddress, DEFAULT_PORT); 108 // 设置密码 109 session.setPassword(password); 110 111 // 方式一,通过Session建立连接 112 // session.setConfig("StrictHostKeyChecking", "no"); 113 // session.connect(); 114 115 // 方式二,通过Session建立连接 116 // java.util.Properties; 117 Properties config = new Properties(); 118 config.put("StrictHostKeyChecking", "no"); 119 session.setConfig(config);// 为Session对象设置properties 120 // session.setTimeout(3000);// 设置超时 121 session.connect(); 通过Session建立连接 122 123 // 设置登陆状态 124 logined = true; 125 catch (JSchException e) 126 // 设置登陆状态为false 127 logined = false; 128 throw new Exception( 129 "主机登录失败, IP = " + ipAddress + ", USERNAME = " + userName + ", Exception:" + e.getMessage()); 130 131 132 133 /** 134 * 关闭连接 135 */ 136 public void closeSession() 137 // 调用session的关闭连接的方法 138 if (session != null) 139 // 如果session不为空,调用session的关闭连接的方法 140 session.disconnect(); 141 142 143 144 145 /** 146 * 执行相关的命令 147 * 148 * @param command 149 * @throws IOException 150 */ 151 public void execCommand(String command) throws IOException 152 InputStream in = null;// 输入流(读) 153 Channel channel = null;// 定义channel变量 154 try 155 // 如果命令command不等于null 156 if (command != null) 157 // 打开channel 158 //说明:exec用于执行命令;sftp用于文件处理 159 channel = session.openChannel("exec"); 160 // 设置command 161 ((ChannelExec) channel).setCommand(command); 162 // channel进行连接 163 channel.connect(); 164 // 获取到输入流 165 in = channel.getInputStream(); 166 // 执行相关的命令 167 String processDataStream = processDataStream(in); 168 // 打印相关的命令 169 System.out.println("1、打印相关返回的命令: " + processDataStream); 170 171 catch (JSchException e) 172 e.printStackTrace(); 173 catch (IOException e) 174 e.printStackTrace(); 175 catch (Exception e) 176 e.printStackTrace(); 177 finally 178 if (in != null) 179 in.close(); 180 181 if (channel != null) 182 channel.disconnect(); 183 184 185 186 187 188 /** 189 * 对将要执行的linux的命令进行遍历 190 * 191 * @param in 192 * @return 193 * @throws Exception 194 */ 195 public String processDataStream(InputStream in) throws Exception 196 StringBuffer sb = new StringBuffer(); 197 BufferedReader br = new BufferedReader(new InputStreamReader(in)); 198 String result = ""; 199 try 200 while ((result = br.readLine()) != null) 201 sb.append(result); 202 // System.out.println(sb.toString()); 203 204 catch (Exception e) 205 throw new Exception("获取数据流失败: " + e); 206 finally 207 br.close(); 208 209 return sb.toString(); 210 211 212 /** 213 * 上传文件 可参考:https://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html 214 * 215 * @param directory 216 * 上传文件的目录 217 * @param uploadFile 218 * 将要上传的文件 219 */ 220 public void uploadFile(String directory, String uploadFile) 221 try 222 // 打开channelSftp 223 ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); 224 // 远程连接 225 channelSftp.connect(); 226 // 创建一个文件名称问uploadFile的文件 227 File file = new File(uploadFile); 228 // 将文件进行上传(sftp协议) 229 // 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同. 230 // 采用默认的传输模式:OVERWRITE 231 channelSftp.put(new FileInputStream(file), directory, ChannelSftp.OVERWRITE); 232 // 切断远程连接 233 channelSftp.exit(); 234 System.out.println("2、" + file.getName() + " 文件上传成功....."); 235 catch (JSchException e) 236 e.printStackTrace(); 237 catch (SftpException e) 238 e.printStackTrace(); 239 catch (FileNotFoundException e) 240 e.printStackTrace(); 241 242 243 244 245 /** 246 * 下载文件 采用默认的传输模式:OVERWRITE 247 * 248 * @param src 249 * linux服务器文件地址 250 * @param dst 251 * 本地存放地址 252 * @throws JSchException 253 * @throws SftpException 254 */ 255 public void fileDownload(String src, String dst) throws JSchException, SftpException 256 // src 是linux服务器文件地址,dst 本地存放地址 257 ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); 258 // 远程连接 259 channelSftp.connect(); 260 // 下载文件,多个重载方法 261 channelSftp.get(src, dst); 262 // 切断远程连接,quit()等同于exit(),都是调用disconnect() 263 channelSftp.quit(); 264 // channelSftp.disconnect(); 265 System.out.println("3、" + src + " ,下载文件成功....."); 266 267 268 /** 269 * 删除文件 270 * 271 * @param directory 272 * 要删除文件所在目录 273 * @param deleteFile 274 * 要删除的文件 275 * @param sftp 276 * @throws SftpException 277 * @throws JSchException 278 */ 279 public void deleteFile(String directoryFile) throws SftpException, JSchException 280 // 打开openChannel的sftp 281 ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); 282 // 远程连接 283 channelSftp.connect(); 284 // 删除文件 285 channelSftp.rm(directoryFile); 286 // 切断远程连接 287 channelSftp.exit(); 288 System.out.println("4、" + directoryFile + " 删除的文件....."); 289 290 291 /** 292 * 列出目录下的文件 293 * 294 * @param directory 295 * 要列出的目录 296 * @param sftp 297 * @return 298 * @throws SftpException 299 * @throws JSchException 300 */ 301 public Vector listFiles(String directory) throws JSchException, SftpException 302 ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); 303 // 远程连接 304 channelSftp.connect(); 305 // 显示目录信息 306 Vector ls = channelSftp.ls(directory); 307 System.out.println("5、" + ls); 308 // 切断连接 309 channelSftp.exit(); 310 return ls; 311 312 313 public static void main(String[] args) 314 // 连接到指定的服务器 315 try 316 // 1、首先远程连接ssh 317 SSHRemoteCall.getInstance().sshRemoteCallLogin(ipAddress, userName, password); 318 // 打印信息 319 System.out.println("0、连接192.168.110.130,ip地址: " + ipAddress + ",账号: " + userName + ",连接成功....."); 320 321 // 2、执行相关的命令 322 // 查看目录信息 323 // String command = "ls /home/hadoop/package "; 324 // 查看文件信息 325 // String command = "cat /home/hadoop/package/test "; 326 // 查看磁盘空间大小 327 // String command = "df -lh "; 328 // 查看cpu的使用情况 329 // String command = "top -bn 1 -i -c "; 330 // 查看内存的使用情况 331 String command = "free "; 332 SSHRemoteCall.getInstance().execCommand(command); 333 334 // 3、上传文件 335 String directory = "/home/hadoop/package/poi.xlsx";// 目标文件名 336 String uploadFile = "E:\\\\poi.xlsx";// 本地文件名 337 SSHRemoteCall.getInstance().uploadFile(directory, uploadFile); 338 339 // 4、下载文件 340 // src 是linux服务器文件地址,dst 本地存放地址,采用默认的传输模式:OVERWRITE 341 //test为文件名称哈 342 String src = "/home/hadoop/package/test"; 343 String dst = "E:\\\\"; 344 SSHRemoteCall.getInstance().fileDownload(src, dst); 345 346 // 5、刪除文件 347 String deleteDirectoryFile = "/home/hadoop/package/test"; 348 SSHRemoteCall.getInstance().deleteFile(deleteDirectoryFile); 349 350 // 6、展示目录下的文件信息 351 String lsDirectory = "/home/hadoop/package"; 352 SSHRemoteCall.getInstance().listFiles(lsDirectory); 353 354 // 7、关闭连接 355 SSHRemoteCall.getInstance().closeSession(); 356 catch (Exception e) 357 // 打印错误信息 358 System.err.println("远程连接失败......"); 359 e.printStackTrace(); 360 361 362 363
以上是关于JAVA利用commons.net.ftp.FTPClient的storeFileStream方法TXT文件上传. 已经转码UTF-16LE,上传后内容乱码的主要内容,如果未能解决你的问题,请参考以下文章
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: S
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: S
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: S
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: S