今天发现用  如下方法下载一个2.2M的zip文件但是只下载了500K没有下载完全,但是方法  返回的却是true

boolean org.apache.commons.net.ftp.FTPClient.retrieveFile(String remote, OutputStream local) throws IOException
 
根据网上查的资料设置了
 

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
ftp.configure(conf);

发现有时候成功有时候失败(有时候只下载了1.8M就返回true了)

后来又设置了ftp.setDataTimeout(300 * 1000);

ftp.setReceiveBufferSize(1024 * 1024);
ftp.setBufferSize(1024 * 1024);

试了几次没有发现只下载了部分(比如1.8M)的问题了,后续再继续观察

20190919更新

部署到正式环境发现CKS的ftp下载还是有下载不完全问题,我又改了一下程序,判断下载下来的文件大小和ftp上的文件大小是不是size相等,不相等就不删除,等待下次重新下载。如果是zip文件还可以判断一下是否是能够解压的zip再删除。具体代码如下

public static boolean downloadFile(String ftpOdmPath, Integer port, OdmInfo odmInfo, String downloadLocalPath){
boolean downloadStatus = false;

FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");

try {
int reply;
ftp.setDefaultTimeout(30 * 1000);
ftp.setConnectTimeout(30 * 1000);
ftp.setDataTimeout(300 * 1000);

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
ftp.configure(conf);

logger.info("start to connect ftp server");
ftp.connect(odmInfo.getFtpserver(), port);// 连接FTP服务器
logger.info("connect ftp server success");
ftp.login(odmInfo.getFtpusername(), odmInfo.getFtppwd());// 登录
//设置ftp为被动模式,解决有时候ftp会卡住问题
ftp.enterLocalPassiveMode();

ftp.setReceiveBufferSize(1024 * 1024);
ftp.setBufferSize(1024 * 1024);

logger.info("login ftp server success");
reply = ftp.getReplyCode();
logger.info("reply======"+reply);
if (!FTPReply.isPositiveCompletion(reply)) {

ftp.disconnect();
return downloadStatus;
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

//切换FTP目录
logger.info("ftpOdmPath======"+ftpOdmPath);
boolean changeDirStatus=ftp.changeWorkingDirectory(ftpOdmPath);
if(changeDirStatus)
{
FTPFile[] ftpFiles = ftp.listFiles();
for(FTPFile file : ftpFiles){
long fileSize=file.getSize();
OutputStream os=null;
boolean retrieveStatus=false;
try {
logger.info("download file======"+downloadLocalPath + "/" + file.getName());
File localFile = new File(downloadLocalPath + "/" + file.getName());
if (!localFile.getParentFile().exists()) {
localFile.getParentFile().mkdirs();
}
if(localFile.isDirectory())
{
continue;
}
os = new FileOutputStream(localFile);
retrieveStatus=ftp.retrieveFile(file.getName(), os);
logger.info("ftp download file======"+file.getName()+"===="+retrieveStatus);
if(os!=null)
{
os.flush();
}

} catch (Exception e) {
// TODO Auto-generated catch block
logger.error("",e);
} finally {
if(os!=null)
{
os.close();
}
}

//如果下载成功删除ftp上的文件,并且文件大小和ftp上的一样才删除文件,如果是zip文件还要判断一下是不是zip文件再删除ftp上的文件
if(retrieveStatus)
{
try {
File localFileCheckSize = new File(downloadLocalPath + "/" + file.getName());
long localFileSize=localFileCheckSize.length();

logger.info("ftp file size======"+fileSize+"===local file size===="+localFileSize);
if(fileSize==localFileSize)
{
if(file.getName()!=null&&file.getName().endsWith(".zip"))
{
if(CompressUtil.checkZipFile(localFileCheckSize))
{
ftp.dele(file.getName());
logger.info("delete ftp file======"+file.getName());
}
else
{
logger.info("download from ftp file is not zip file======"+downloadLocalPath + "/" + file.getName());
}
}
else
{
ftp.dele(file.getName());
logger.info("delete ftp file======"+file.getName());
}

}
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error("",e);
}
}

}
}
ftp.logout();
downloadStatus = true;
logger.info("download file success");
} catch (Exception e) {
logger.error("",e);
downloadStatus = false;
} finally{
if(ftp.isConnected()){
try{
ftp.disconnect();
}catch(IOException e){
logger.error("",e);
downloadStatus = false;
}
}

}
return downloadStatus;
}

如下网上的文章是解决这次问题的参考

https://blog.csdn.net/dise0092/article/details/100765177

在使用java的ftp下载服务器上的文件获取文件的byte[],然后对byte进行加密传输时,

注意是要获取byte[],而不是下载文件到本地;

发现下载的byte[]大小总是小于文件实际大小,并且下载的大小是变化的

到网上查阅发现,ftp传输是不稳定的,会随网络情况波动;

所以对下载的方法进行了修改;

import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;

public String download(String ftpFile, FtpClient ftpClient) {

InputStream is = null;
byte[] data = null;
try {
// 获取ftp上的文件
long size=ftpClient.getSize(ftpFile);
System.out.println(ftpClient.getSize(ftpFile));
is = ftpClient.getFileStream(ftpFile);
// System.out.println(is.available());

int count =is.available();
System.out.println("count:"+count);

while (count>0 || (data==null?0:data.length)<size) {// 获取到的大小小于文件大小也进入
byte[] b = new byte[count];
is.read(b);
System.out.println("b:"+b.length);
data= byteMerger(b,data);
count = is.available();
}

is.close();

ftpClient.close();

}catch (FtpProtocolException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
System.out.println("data size:"+data.length);
String encodeBase64Str =org.apache.commons.codec.binary.Base64.encodeBase64String(data);

return encodeBase64Str;
}

// 参考 https://blog.csdn.net/shb2058/article/details/52637213
public static byte[] byteMerger(byte[] byte1, byte[] byte2){
if (byte1==null && byte2!=null){
return byte2;
}

if (byte2 == null && byte1!=null){
return byte1;
}

if (byte2 == null && byte1 ==null){
return null;
}
byte[] byte3 = new byte[byte1.length+byte2.length];
System.arraycopy(byte1, 0, byte3, 0, byte1.length);
System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
return byte3;
}

/***
* 连接ftp
* @param url
* @param port
* @param username
* @param password
* @return
*/
public FtpClient connectFTP(String url, int port, String username, String password) {
//创建ftp
FtpClient ftp = null;
try {
//创建地址
SocketAddress addr = new InetSocketAddress(url, port);
//连接
ftp = FtpClient.create();
ftp.connect(addr);
//登陆
ftp.login(username, password.toCharArray());
ftp.setBinaryType();

ftp.enablePassiveMode(true);//这句最好加告诉对面服务器开一个端口

} catch (FtpProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return ftp;
}
运行发现果然波动是很大的

参考:

https://blog.csdn.net/shb2058/article/details/52637213

网上还有个说法,下午试试

如果小文件可以下载,但是大文件下载后缺少几字节之类的话,可以设置ftpClient.setFileType(FTP.BINARY_FILE_TYPE)以二进制去传输,如果是大文件直接完全下载不了,卡死的话,建议设置为ftpClient.enterLocalPassiveMode(),并且设置超时时间,做一个5-10次的for循环,保证能够下载下来。

java ftp retrieveFile 较大文件丢失内容的更多相关文章

  1. 【Web应用】JAVA网络上传大文件报500错误

    问题描述 当通过 JAVA 网站上传大文件,会报 500 错误. 问题分析 因为 Azure 的 Java 网站都是基于 IIS 转发的,所以我们需要关注 IIS 的文件上传限制以及 requestT ...

  2. java 分次读取大文件的三种方法

    1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...

  3. java处理excel-xlsx格式大文件的解决方案

    1.第一次读取7M左右的ecxel文件,使用poi 库实现,参考了下面的博文. http://www.cnblogs.com/chenfool/p/3632642.html 使用上面的方法在 下面Wo ...

  4. java多线程实现复制大文件

    有些开发的时候我们经常遇到这样一个问题,对大文件的处理.比如:日志文件.那么十几G的大文件.我们应该如何复制呢? 还有就是希望从本地和远程复制文件,文件都很大,10G级的如何办呢? 在这里我告诉你们, ...

  5. java使用WebUploader做大文件的分块和断点续传

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  6. 使用原生Java Web来实现大文件的上传

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  7. Java实现浏览器端大文件分片上传

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  8. java Io流输出指定文件的内容

    package com.hp.io; import java.io.*; public class  BufferedReaderTest{ /** *@param   想想 */ public st ...

  9. Java thymeleaf模板获取资源文件的内容

    我们在某些时候可能需要获取配置文件properties中的配置信息,而不需要用Java传给模板,在模板中就可以直接获取 我们需要在resources/下定义国际化配置文件即可,注意名称必须中messa ...

随机推荐

  1. 微pe安装原版win10怎么装|wepe安装原版win10 1803教程

    http://www.xitongcheng.com/jiaocheng/xtazjc_article_42199.html 怎么制作wepe启动盘?微pe是一款全新高效.多功能pe维护工具箱,同时支 ...

  2. 排错:Unable to create a new session key. It is likely that the cache is unavailable.

    排错:Unable to create a new session key. It is likely that the cache is unavailable. 问题 登录openstack页面, ...

  3. Samrty技术的 初步了解

    <span style="font-size:18px;">Smarty 技术的使用 <?php #smarty 测试 #引入smarty require_onc ...

  4. 【C# in depth 第三版】温故而知新(1) (转)

    声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7192354.html 前言 关于这本书(<深入理解C# 第三版>)的详细情况以及好坏,自行 ...

  5. Redis 部署安装

    一.Redis介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多 ...

  6. CORS,jsonp解决跨域问题

    同源和跨域 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上 ...

  7. 【Zookeeper】本地模式安装

    安装步骤 上传gz包 通过rz命令,将zookeeper-3.4.10.tar.gz安装包上传到/opt/soft/文件夹下. [root@bigdata111 soft]# rz [root@big ...

  8. 【Web网站服务器开发】apache和tomcat 阿帕奇和汤姆猫

    经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料,总 ...

  9. JavaScript日期格式化处理

    /** * 获取年月,如:2018-08 */ export function getMonth () { return formatDate(new Date(), 'yyyy-MM') } /** ...

  10. Spring boot + Jpa + Maven + Mysql 初级整合

    1.使用Idea创建spring boot工程的博客 https://www.cnblogs.com/black-spike/p/8017768.html 2.本篇博客参考网址 https://blo ...