解决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. ...
随机推荐
- django有什么CMS比较好用?哪个好?
这个网站有目前在电子商务领域流行的django cms的横向对比表格,可以看看 https://djangopackages.org/grids/g/ecommerce/ 从结果上来看,django- ...
- UE4 Slate控件之TreeView 使用例子(一)
TreeView例子 先从Contruct中往子Slot添加Widget,先声明指向STreeView的指针,后续方便进行视图的一些操作 TSharedPtr<STreeView<TSha ...
- XCTF-ics-05(文件包含+preg_replace函数/e修正符下的代码执行漏洞)
记一道preg_replace函数/e模式下的代码执行漏洞利用的题. 只有设备维护中心页面可以进入,页面没有什么可点击的,查看源代码,发现这里有个参数. 拼接到url,页面显示index,拼接/etc ...
- (1)用 if语句 区间判断
/*此例子只做比喻演示*/ 1 #include <stdio.h> 2 int main() 3 { 4 5 int p; 6 scanf("%d",&p); ...
- Salesforce Integration 概览(五) Remote Call-In(远程操作 外部->salesforce)
本篇参考:https://resources.docs.salesforce.com/sfdc/pdf/integration_patterns_and_practices.pdf 本篇博客介绍 Re ...
- JAVA基础语法:常用功能符以及循环结构和分支结构(转载)
3.JAVA基础语法:常用功能符以及循环结构和分支结构 1.常用功能符 注释 ("文字"是被注释的部分) //文字 单行注释 /文字/ 多行注释 算术运算符 + - * / / 整 ...
- Notes about multiboot usb creator
U盘上的多系统启动工具,Windows上YUMI比较好,Ubuntu上MultiSystem用法复杂,unetbootin是另外一款,需要安装p7zip(apt-get install p7zip-f ...
- 让Dev支持C++11特性
如果你使用的是 Dev-C++ ,忘记了在设置中包含 -std=c++11是无法让Dev支持C++11特性的,导致一些C++11 中的好用的函数可能会产⽣生编译⽆无法通过的情况. 这时候你有两个方法 ...
- nc基本操作&反弹shell
一.nc简介 nc 被称为瑞士军刀netcat ,所做的就是在两台电脑之间建立链接,并返回两个数据流. 可运行在TCP或者UDP模式,添加参数 -u 则调整为UDP,默认为TCP 即可用在window ...
- SpringBoot 整合 SpringSecurity 梳理
文档 Spring Security Reference SpringBoot+SpringSecurity+jwt整合及初体验 JSON Web Token 入门教程 - 阮一峰 JWT 官网 Sp ...