今天在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下载网络文件线程挂起问题的更多相关文章

  1. 解决FTPClient linux环境下FTPClient调用retrieveFileStream导致线程挂起(防火墙问题);下载文件小于实际文件问题

    FTPClient调用retrieveFileStream导致线程挂起(防火墙问题):下载文件小于实际文件问题解决 实际是因为FTP的两种传输模式:主动模式和被动模式的不同而导致的 FTPClient ...

  2. JAVA多线程下载网络文件

    JAVA多线程下载网络文件,开启多个线程,同时下载网络文件.   源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...

  3. Java读取并下载网络文件

      CreateTime--2017年8月21日10:11:07 Author:Marydon import java.io.ByteArrayOutputStream; import java.io ...

  4. python下载网络文件

    python下载网络文件 制作人:全心全意 下载图片 #!/usr/bin/python #-*- coding: utf-8 -*- import requests url = "http ...

  5. C#限速下载网络文件

    代码: using System; using System.Collections.Concurrent; using System.Collections.Generic; using Syste ...

  6. DELPHI TDownLoadURL下载网络文件

      DELPHI XE6 FMX 附件:http://files.cnblogs.com/xe2011/IDHttp_fmx.7z unit Unit1; interface uses //引用 Vc ...

  7. 解决FTPClient上传文件为空,显示0字节

    JAVA使用FTPClient上传文件时总是为空,而使用FileZilla客户端时却不会. 后来查了下资料,FTP服务器有被动模式和主动模式.(具体查另外资料) 在JAVA中将FTPClient设置为 ...

  8. 【python】下载网络文件到本地

    # 下载网络图片文件到本地 import urllib.request rsp=urllib.request.urlopen("http://n.sinaimg.cn/ent/transfo ...

  9. java 下载网络文件

    1.FileUtils.copyURLToFile实现: import java.io.File; import java.net.URL; import org.apache.commons.io. ...

随机推荐

  1. [剑指 Offer 28. 对称的二叉树]

    剑指 Offer 28. 对称的二叉树 请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和它的镜像一样,那么它是对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / ...

  2. kali linux 的ssh服务器拒绝了密码 请再试一次

    1.配置kali linux下的SSH,默认情况下kali下的SSH不允许root用户远程登录SSH,需要修改配置文件 /etc/ssh/sshd_config,修改PermitRootLogin y ...

  3. Nature Cancer | 宋尔卫/苏士成团队揭示lncRNA调控巨噬细胞“双刃剑”作用新机制

    巨噬细胞 (macrophage, Mϕ) 是先天免疫系统中重要的免疫细胞,也是血液.淋巴和所有哺乳动物组织类型中最常见的吞噬细胞,具有极强的功能多样性.其中,肿瘤微环境组织中存在的巨噬细胞也被称作肿 ...

  4. PHP-Audit-Labs-Day1 - in_array函数缺陷

    函数缺陷原理分析 先看一段简单的源代码 class Challenge{ const UPLOAD_DIRECTORY = './solutions/'; private $file; private ...

  5. 身边好几个技术一般的程序员都面上了,阿里P7门槛降低?

    经常在网上的论坛里看到讨论程序员的级别,尤其在跳槽类的信息里可以看到对标阿里P7,百度T6,腾讯3.1等字眼,似乎大厂的级别俨然可以成为业内的通用货币,类似于高考分数一样,哪一档就对应着什么样的待遇. ...

  6. 阿里面试官:Android中binder机制的实现原理及过程?

    Binder 是 Android 系统中非常重要的组成部分.Android 系统中的许多功能建立在 Binder 机制之上.在这篇文章中,我们会对 Android 中的 Binder 在系统架构中的作 ...

  7. Windows API 进程相关笔记

    0. 前言 最近做了一个进程信息相关的项目,整理了一下自己做项目时的笔记,分享给大家 1. 相关概念 1.1 HANDLE 概念 HANDLE(句柄)是Windows操作系统中的一个概念. 在Wind ...

  8. js继承方式及特征

    1. 原型链继承 (原型链) function Parent() { this.fruits = ['apple', 'orange']; } Parent.prototype.sayHello = ...

  9. KMP算法的详细解释

    什么是kmp算法呢?这是一个处理字符串的算法,用来判断给出的模式串p是否存在于文本串t中(p的长度小于t). 在本文中,字符串储存在字符数组中,并且第一个字符放在下标为1的元素中. 那么如何理解kmp ...

  10. Python脚本文件中使用中文

    Python做图形用户界面(GUI)开发时经常要在界面上显示中文,需要做如下处理(详见[1]和[2]2.3节): 在py文件的首行写上:# -- coding:utf-8 -- 保存py文件时要存为u ...