解决FTPClient下载网络文件线程挂起问题
今天在windows上调试FTP下载文件时,出险线程假死,代码如下:
if (inputStream != null) {
byte[] data = null;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
data = new byte[inputStream.available()];
int len = 0;
while ((len = inputStream.read(data)) != -1) {
outStream.write(data, 0, len);
}
data = outStream.toByteArray();
Base64.Encoder encoder = Base64.getEncoder();
re = encoder.encodeToString(data);
}
通过打印日志排查到while死循环,查看read方法源码注释:
/* <p> If the length of <code>b</code> is zero, then no bytes are read and
* <code>0</code> is returned; otherwise, there is an attempt to read at
* least one byte. If no byte is available because the stream is at the
* end of the file, the value <code>-1</code> is returned; otherwise, at
* least one byte is read and stored into <code>b</code>.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
在date字节数组长度为1时,read方法返回0,while出现死循环,原因是因为网络传输数据不及时,导致inputStream.available()方法未取到本地内存的字节数据返回0。
由于下载的文件大小不是很大,默认给了一个2048大小的字节数组,于是做了以下优化:
if (inputStream != null) {
byte[] data = null;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
if (inputStream.available() == 0) {
data = new byte[2048];
} else {
data = new byte[inputStream.available()];
}
int len = 0;
while ((len = inputStream.read(data)) != -1) {
outStream.write(data, 0, len);
}
data = outStream.toByteArray();
Base64.Encoder encoder = Base64.getEncoder();
re = encoder.encodeToString(data);
}
再次调试,问题解决。
但是,在将程序部署到Linux服务器上依然假死,
问题分析:
FTPClient调用retrieveFileStream线程假死
FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状 态。于是各种网上资料查找
FTP的两种传输模式:主动模式和被动模式
在调用这两个方法之前,调用 FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于防火墙安全限制,可能某些端口没有开启,所以就出现阻塞。
解决方法:ftpClient.enterLocalPassiveMode(); //开启本地被动模式,此代码设置在登陆之后或者之前都可以。
同样,如果上传的话需要enterRemotePassiveMode()//开启远程被动传输模式
感谢网络上的大神们的分享,不然又得钻牛角了。
解决FTPClient下载网络文件线程挂起问题的更多相关文章
- 解决FTPClient linux环境下FTPClient调用retrieveFileStream导致线程挂起(防火墙问题);下载文件小于实际文件问题
FTPClient调用retrieveFileStream导致线程挂起(防火墙问题):下载文件小于实际文件问题解决 实际是因为FTP的两种传输模式:主动模式和被动模式的不同而导致的 FTPClient ...
- JAVA多线程下载网络文件
JAVA多线程下载网络文件,开启多个线程,同时下载网络文件. 源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...
- Java读取并下载网络文件
CreateTime--2017年8月21日10:11:07 Author:Marydon import java.io.ByteArrayOutputStream; import java.io ...
- python下载网络文件
python下载网络文件 制作人:全心全意 下载图片 #!/usr/bin/python #-*- coding: utf-8 -*- import requests url = "http ...
- C#限速下载网络文件
代码: using System; using System.Collections.Concurrent; using System.Collections.Generic; using Syste ...
- DELPHI TDownLoadURL下载网络文件
DELPHI XE6 FMX 附件:http://files.cnblogs.com/xe2011/IDHttp_fmx.7z unit Unit1; interface uses //引用 Vc ...
- 解决FTPClient上传文件为空,显示0字节
JAVA使用FTPClient上传文件时总是为空,而使用FileZilla客户端时却不会. 后来查了下资料,FTP服务器有被动模式和主动模式.(具体查另外资料) 在JAVA中将FTPClient设置为 ...
- 【python】下载网络文件到本地
# 下载网络图片文件到本地 import urllib.request rsp=urllib.request.urlopen("http://n.sinaimg.cn/ent/transfo ...
- java 下载网络文件
1.FileUtils.copyURLToFile实现: import java.io.File; import java.net.URL; import org.apache.commons.io. ...
随机推荐
- Android 自定义属性(attrs)、样式(Style)、主题(Theme)
Android 自定义属性(attrs).样式(Style).主题(Theme) https://www.cnblogs.com/dandre/p/4507024.html https://blog. ...
- ElasticSearch进阶检索
ElasticSearch进阶检索 入门检索中讲了如何导入elastic提供的样本测试数据,下面我们用这些数据进一步检索 一.SearchAPI ES 支持两种基本方式检索 : 1.一种是通过使用 R ...
- C语言运算符(杂项运算符 ↦ sizeof & 三元)
实列 1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 4; 6 short b; 7 double c; 8 int* ptr; 9 1 ...
- AspNetCore添加API限流
最近发现有客户在大量的请求我们的接口,出于性能考虑遂添加了请求频率限制. 由于我们接口请求的是.Net Core写的API网关,所以可以直接添加一个中间件,中间件中使用请求的地址当key,通过配置中心 ...
- [SQL]修改和删除基本表
修改基本表 SQL语言用alter table语句修改基本表,其一般格式如下: alter table <表名> add <列名> <数据类型> [<列级完整 ...
- 实战爬取拷背漫画-Python
一.抓包获取链接 以爬取<前科者>为例 获取搜索链接 https://api.copymanga.com/api/v3/search/comic?limit=5&q=前科者 ...
- Linux 文件、目录与磁盘格式
文件属性 连接数 文件持有者 文件所属群组 文件容量 文件最后修改时间 文件名(就那个..) 第一栏其中文件属性有10,第一个属性代表这个文件是目录.文件或链接文件: [d]目录 [-]文 ...
- HashMap底层实现-基础
1.数据结构 1.7 数组+链表,键值对是以Entry内部类的数组存放的.键计算得到哈希值是该数组的下标.又称桶数组当存在哈希冲突时,会通过Entry类内部的成员变量 Entry<k,v> ...
- Sqli-Labs less29-31
Less-29 可以从介绍上看出,第29关被称为世界上最好的WAF,网上许多讲解的办法就是和第一关差不多,其实是不对的. sqli-labs文件夹下面还有tomcat文件,这才是真正的less,里面的 ...
- uniapp scroll-view 组件横向滑动失效(ios问题出的最多)
注意事项(做好以下几点就很难出问题): 一.scroll-view组件必须有固定高度,不可出现高度坍塌或让高度消失等现象;(重中之重) 二.一般问题出的多的就是在nvue环境下去使用的scroll-v ...