600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 使用Java输入流(InputStream)读取FTP服务器图片 并上传到另一台FTP服务器

使用Java输入流(InputStream)读取FTP服务器图片 并上传到另一台FTP服务器

时间:2023-06-01 23:15:29

相关推荐

使用Java输入流(InputStream)读取FTP服务器图片 并上传到另一台FTP服务器

使用JavaInputStream读取FTP图片到远程服务器

最近需要做一个新需求,要读取ftp服务器的图片,然后保存到另一台服务器上,ftp的访问路径是经过apache转换的,记录一下遇到的坑。我的方案是想办法拿到这张图片的输入流,然后通过FTPClient上传到另一台服务器,在网上找到了如何拿到输入流,并保存本地的方法。

Java从网络读取图片通过InputStream保存至本地,代码如下:

package com.bayonet.action;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import .HttpURLConnection;import .URL;public class Test{public static void main(String[] args){InputStream inStream = null;FileOutputStream outStream = null;try{// 定义一个URL对象,并把http路径放进去URL urlConet = new URL("http://xxx.xxx.xx.xx/xxx/xxx/P.JPG");// 打开连接HttpURLConnection con = (HttpURLConnection) urlConet.openConnection();// 设置请求方式为GETcon.setRequestMethod("GET");// 设置超时响应时间为5秒con.setConnectTimeout(6 * 1000);// 通过输入流获取图片inStream = con.getInputStream();// 定义图片放置绝对路径String pathName = "D://xxx.JPG";// 通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例File file = new File(pathName);// 如果路径不存在if (!file.exists()){// 那就创建它file.mkdirs();}// 创建输出流,并把文件路径放置进去outStream = new FileOutputStream(file);// 定义缓冲区,即为在内存开的内存空间是1024,也就是一次最多读取1024个字节byte[] b = new byte[1024];// 使用输入流从buffer里把数据读取出来 每次读取的字符串长度,如果为-1,代表全部读取完毕while ((inStream.read(b)) != -1){// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度outStream.write(b);// 写入数据}inStream.close();outStream.close();}catch (Exception e){e.printStackTrace();}finally{if (inStream != null){try{//关闭输入流inStream.close();}catch (IOException e){e.printStackTrace();}}if (outStream != null){try{//关闭输出流outStream.close();}catch (IOException e){e.printStackTrace();}}}}}

Java获取输入流上传图片至FTP服务器,代码如下:

package com.bayonet.action;import java.io.InputStream;import .URL;import com.bayonet.utils.FTPUtil;public class Test{public static void main(String[] args){InputStream inStream = null;try{// 定义一个URL对象,并把http路径放进去URL urlConet = new URL("http://xxx.xxx.xx.xx/xxx/xxx/P.JPG");// 通过输入流获取图片inStream = urlConet.openStream();// new一个Ftp对象FTPUtil ftpUtil = new FTPUtil();// ftp放置文件路径String ftpPath = "xxx/xxx/xxx";// 文件名String fileName = "xxxx.jpg";boolean uploadFile = ftpUtil.uploadFile(ftpPath, inStream, fileName);System.out.println(uploadFile);}catch (Exception e){e.printStackTrace();}}}

package com.bayonet.action;import java.io.IOException;import java.io.InputStream;import mons.lang3.StringUtils;import .ftp.FTPClient;import .ftp.FTPReply;import com.bayonet.constant.Const;public class FTPUtil{/*** Ftp 上传图片* * @param ftpPath* ftp路径* @param inputStream* 输入流* @param fileName* 文件名* @return boolean* @throws Exception* 异常*/public boolean uploadFile(String ftpPath, InputStream inputStream, String fileName) throws Exception{boolean flag = false;Exception exp = new Exception();FTPClient ftpClient = new FTPClient();try{// 连接FTP服务器ftpClient.connect("FTP连接IP地址","FTP连接端口");// 登录FTP服务器ftpClient.login("FTP连接账号", "FTP连接密码");// 是否成功登录FTP服务器 230为登录成功int replyCode = ftpClient.getReplyCode();if (!FTPReply.isPositiveCompletion(replyCode)){return flag;}ftpClient.enterLocalPassiveMode();// 开启被动模式ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);boolean makeDir = makeDir(ftpClient, ftpPath);String printWorkingDirectory = ftpClient.printWorkingDirectory();System.out.println("获取当前目录:" + printWorkingDirectory);/** storeFile(String remote,InputStream local)抛出IOException 使用给定的名称在服务器上存储一个文件,并从给定的 InputStream 获取输入 * 参数: remote - 给远程文件的名称。 local - 从中读取文件的本地 InputStream。* 返回:如果成功完成,则为真,否则为假。*/ftpClient.storeFile(new String(fileName.getBytes(Const.GBK), Const.ISO), inputStream);// 通过发送 QUIT 命令注销 FTP 服务器ftpClient.logout();flag = true;}catch (Exception e){exp = e;e.printStackTrace();}finally{if (ftpClient.isConnected()){try{ftpClient.disconnect();}catch (IOException e){exp = e;throw exp;}}if (inputStream != null){inputStream.close();}}return flag;}/*** ftp创建多级目录(ftp只支持创建一级目录)* * @param ftpClient* ftp连接* @param path* 文件路径* @return boolean*/public boolean makeDir(FTPClient ftpClient, String path){boolean makeDirectory = false;try{String[] split = path.split("/");for (String string : split){if (StringUtils.isEmpty(string)){continue;}/*** changeWorkingDirectory 更改 FTP 会话的当前工作目录。 * 返回:如果成功完成,则为真,否则为假*/if (!ftpClient.changeWorkingDirectory(string)){/*** makeDirectory 在当前目录(如果给定相对路径名)或指定位置(如果给定绝对路径名)的 FTP 服务器上创建一个新子目录 * 返回:如果成功完成,则为真,否则为假。*/makeDirectory = ftpClient.makeDirectory(string);/*** changeWorkingDirectory 更改 FTP 会话的当前工作目录。 * 返回: 如果成功完成,则为真,否则为假。*/ftpClient.changeWorkingDirectory(string);}else{makeDirectory = ftpClient.changeWorkingDirectory(string);}}}catch (Exception e){e.printStackTrace();}return makeDirectory;}}

代码看起来是不是感觉没问题?我在本地咋跑咋流畅,到了测试环境,死活跑不通。一直报java.io.FileNotFoundException: http://xxx.xxx.xx.xx/xxx/xxx/P.JPG这个错误,我是百思不得其解,在网上找了半天。发现网上的解决方案都不是很靠谱。后来发现我的图片里边有中文名称,我就试着把中文名称去掉,发现居然成功了。于是又到了疯狂设置编码格式的时刻,各种设置发现都不行。后来查看了apache日志才发现,要设置urlEncoder的编码格式为UTF-8.

解决方案:

/** .URLEncoderAPI介绍* 对字符串进行编码时,适用以下规则:* 字母数字字符“ a”到“ z”、“ A”到“ Z”和“ 0”到“ 9”保持不变。* 特殊字符“ .”、“ -”、“ *”和“ _”保持不变。* 空格字符“ ”转换为加号“ +”。* 所有其他字符都是不安全的,首先使用某种编码方案将其转换为一个或多个字节。然后每个字节由3个字符的字符串“ ”表* * 示,其中xy是字节的两位十六进制表示。推荐使用的编码方案是 UTF-8。但是,出于兼容性原因,如果未指定编码,则使* 用平台的默认编码。 %xy*///根据自己的路径格式 把中文部分截取出来转换格式后,拼起来再放入URl 这样他就能获取到这个图片了//注:URL的路径必须是http路径String picPath = .URLEncoder.encode(picPath, "UTF-8");URL urlConet = new URL(picPath);

文章仅用作分享记录,如有不当之处,还望指正。

最近开通个人了微信公众号,以后将会定期分享工作学习过程中遇到的问题,欢迎关注与我一道成长交流~:

微信搜索:MYY668999程序猿爱篮球即可上车。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。