定义ftp操作接口

import java.io.InputStream;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient; /**
* FTP服务器操作*/
public interface iFtpServU {
public FTPClient ftp(String ip, String user, String password);
public List<String[]> csv(InputStream in);
}

接口实现类

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import com.csvreader.CsvReader; /**
* FTP服务器操作具体实现*/
public class FtpServUImpl implements iFtpServU {
/** 本地字符编码 */
private static String LOCAL_CHARSET = "GBK";
// FTP协议里面,规定文件名编码为iso-8859-1
private static String SERVER_CHARSET = "ISO-8859-1"; /**
*
* <b>登录ftp 返回ftpClient事件<b>
*
* @param ip
* ftp所在ip
* @param user
* 登录名
* @param password
* 密码
*/
public FTPClient ftp(String ip, String user, String password) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(ip); if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
if (ftpClient.login(user, password)) {
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();// 设置被动模式
// ftpClient.setFileType(getTransforModule());// 设置传输的模式 }
} // ftpClient.login(user, password);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (!ftpClient.isConnected()) {
ftpClient = null;
} return ftpClient;
} /**
* <b>将一个IO流解析,转化数组形式的集合<b>
*
* @param in
* 文件inputStream流
*/
public List<String[]> csv(InputStream in) {
List<String[]> csvList = new ArrayList<String[]>();
if (null != in) {
CsvReader reader = new CsvReader(in, ',', Charset.forName("GBK"));
try {
// 遍历每一行,若有#注释部分,则不处理,若没有,则加入csvList
while (reader.readRecord()) {
if (!reader.getValues()[0].contains("#"))// 清除注释部分
{
csvList.add(reader.getValues());
}
}
} catch (IOException e) {
e.printStackTrace();
} reader.close();
}
return csvList;
} }

业务场景中,调用ftp发生在对账操作,用户通过输入交易笔数、csv文件名,从而判断ftp服务器上是否存在该文件,如果存在该文件,则首先获取文件中的内容条数,与输入的笔数数值比较,一致的话就继续获取csv文件内容与系统数据库中进行比较、对账,从而完成对账操作。

import java.io.InputStream;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//配置文件工具类
import com.online.charge.customer.deployconfig.util.DeployConfigUtil; /**
* @ClassName: QueryFtpFilesUtils
* @Description: 获取Ftp上文件列表
*
*/
public class QueryFtpFilesUtils {
/**
* 获取Ftp客户端
*
* @return
*/
public static FTPClient getFtpClient() {
String ip = DeployConfigUtil.getInterfaceDeployConfig().getFtpUrl();
String userName = DeployConfigUtil.getInterfaceDeployConfig()
.getFtpUserName();
String userPassword = DeployConfigUtil.getInterfaceDeployConfig()
.getFtpPassword();
// 通过配置文件获取ip,username,password
FTPClient ftpClient = getiFtpServU().ftp(ip, userName, userPassword);
return ftpClient;
} /**
* 获取ftp接口服务
*
* @return
*/
private static iFtpServU getiFtpServU() {
return new FtpServUImpl();
} /**
* 获取明细条数
*
* @param fileName
* csv文件名称 如:0320180908110523.csv 文件的名称为 0320180908110523
* @return 明细条数
*/
public static Integer getFtpFileCount(String fileName) {
Integer count = 0;
boolean isContain = Boolean.FALSE;
FTPClient ftpClient = getFtpClient();
List<String[]> fileList = null;
if (null != ftpClient) {
try {
FTPFile[] file = ftpClient.listFiles();
if (file == null || file.length <= 0) {
return -1;
}
// 遍历所有文件,匹配需要查找的文件
for (int i = 0; i < file.length; i++) {
// 匹配到则进入
if (file[i].getName().equals(fileName.concat(".csv"))) {
isContain = Boolean.TRUE;
// 将匹配到的文件流传入接口,转化成数组集合
InputStream in = ftpClient.retrieveFileStream(file[i].getName());
fileList = getiFtpServU().csv(in);
in.close();
}
}
if (!isContain) {
return -1;
}
if (CollectionUtils.isNotEmpty(fileList) && fileList.size() > 0) {
count = fileList.size();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return count;
} /**
* 获取FTP文件内容
*
* @param fileName
* @return
*/
public static void getFtpFileContent(String fileName,
List<String[]> fileContent) {
FTPClient ftpClient = getFtpClient();
if (null != ftpClient) {
try {
FTPFile[] file = ftpClient.listFiles();
// 遍历所有文件,匹配需要查找的文件
for (int i = 0; i < file.length; i++) {
// 匹配到则进入
if (file[i].getName().contains(fileName)) {
InputStream in = ftpClient.retrieveFileStream(file[i].getName());
fileContent.addAll(getiFtpServU().csv(in));
in.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} }

在测试中,遇到能够通过 listFiles方法获取到ftp服务器上的文件列表,但调用 retrieveFileStream方法获取文件内容失败(返回不是null),网上找了很多方法,尝试都失败,现总结如下:

// 匹配到则进入
if (file[i].getName().equals(fileName.concat(Constant.ACCOUNT_FILE_EXTENDS_NAME))) {
isContain = Boolean.TRUE;
// 1.设置主动模式
//ftpClient.enterLocalPassiveMode();
// 2.文件类型问题,设置文件类型
//ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 3.编码问题,设置编码
//InputStream in = ftpClient.retrieveFileStream(new String(file[i].getName().getBytes("UTF-8"),"ISO-8859-1"));
InputStream in = ftpClient.retrieveFileStream(file[i].getName());
// 将匹配到的文件流传入接口,转化成数组集合
fileList = getiFtpServU().csv(in);
in.close();
// 4.流关闭之后获取返回状态
//ftpClient.completePendingCommand();
}

怀疑是 retrieveFileStream方法调用Socket获取流中间出现的问题,但问题目前无法定位(读者如果知道原因麻烦不吝赐教!)

为解决该问题,换了个思路:因为ftp上的文件都有数据,且输入的笔数都大于0,所以当确定ftp上确实有该文件时,首先还是调用 retrieveFileStream方法以流的方式获取该文件,转换为数组后判断,如果长度为0,就说明获取文件内容失败,此时换种方法:使用 retrieveFile方法将ftp服务器上的文件下载到本地,通过io流来获取其内容。实现方法如下:

    // 匹配到则进入
if (file[i].getName().equals(fileName.concat(".csv"))) {
isContain = Boolean.TRUE;
// 将匹配到的文件流传入接口,转化成数组集合
InputStream in = ftpClient.retrieveFileStream(file[i].getName());
fileList = getiFtpServU().csv(in);
in.close();
if(fileList.size() == 0){
//下载ftp文件到本地
String osFileName = "G:/ftpFiles/"+file[i].getName();
File localFile = new File(osFileName);
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file[i].getName() , os);
os.close(); InputStream ins = new FileInputStream(new File(osFileName));
fileList = getiFtpServU().csv(ins);
ins.close();
}
}

java实现读取ftp服务器上的csv文件的更多相关文章

  1. 使用SAXReader读取ftp服务器上的xml文件(原创)

    根据项目需求,需要监测ftp服务器上的文件变化情况,并将新添加的文件读入项目系统(不需要下载). spring配置定时任务就不多说了,需要注意的一点就是,现在的项目很多都是通过maven构建的,分好多 ...

  2. 使用批处理文件在FTP服务器 上传下载文件

    1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt   192.168.1.1 建立一个 ...

  3. Spring学习---Spring中利用组件实现从FTP服务器上传/下载文件

    FtpUtil.java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcepti ...

  4. JAVA通过FTP方式向远程服务器或者客户端上传、下载文件,以及删除FTP服务器上的文件

    1.在目标服务器上搭建FTP服务器 搭建方式有多种大家可以自行选择,例如使用Serv-U或者FTPServer.exe:这里我以FTPServer.exe为例搭建:在目标服务器(这里对应的IP是10. ...

  5. 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器

    引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...

  6. 从 FTP 服务器上下载并保存文件

    本例演示如何运用 C# 中的 FtpWebRequest 等对象从 FTP 服务器上获取文件,并结合 Stream 对象中的方法来保存下载的文件: using System; using System ...

  7. 解决FTP服务器上中文名文件下载后为空的问题

    转: 解决FTP服务器上中文名文件下载后为空的问题 2017年07月20日 15:19:21 代码的寂寞 阅读数 2428  版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  8. java:nginx(java代码操作ftp服务器)

    1.检查是否安装了vsftpd [root@linux01 ~]# rpm -qa|grep vsftpd 2.安装vsftpd [root@linux01 ~]# yum -y install vs ...

  9. 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹

    打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问 在win98,winme,win2000,win2003下都能正常上传文件夹,但在winxp+sp2下同样的文件夹就可能出现问题 1. 打开 ...

随机推荐

  1. linux下编程epoll实现将GPS定位信息上报到服务器

    操作系统:CentOS 开发板:fl2440 开发模块:A7(GPS/GPRS),RT3070(无线网卡) ********************************************** ...

  2. 如何使用chrome自带的Javascript调试工具 【转】

    http://zhangyongbluesky.blog.163.com/blog/static/1831941620113155739840/ 将写好的Javascript代码用chrome打开. ...

  3. 前端基于jquery的UI框架

    正在做的一个项目选择jquery作为前端js核心库.然后就想选一个基于jquery的ui库,然后悲催的事情发生了. 至于为什么使用jquery,一是因为不想为授权费用,而又不想引起可能法律纠纷:另一方 ...

  4. 热修复 AndFix 阿里 apkpatch MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. SQL 连接操作 及 查询分析

  6. JAVA-找不到元素 'beans' 的声明

    问题: Tomcat启动时,spring加载配置文件applicationContext.xml出错,抛出nested exception is og.xml.sax.SAXParseExceptio ...

  7. Eclipse Maven项目报错3之找不到配置文件spring-servlet-context.xml

    一.具体错误如下图所示 根据文字提示可以看出是这个文件找不到,但是我去项目的这个目录找了,这个文件确实存在,那么是什么问题呢 二.解决问题 原因分析(来自网上) 代码编译的过程,是一个自动生成相应编译 ...

  8. 如何在 Kaggle 首战中进入前 10%

    原文:https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/ Introduction Kaggle 是目前最 ...

  9. MAC升级nodejs和npm到最新版

    第一步,先查看本机node.js版本: node -v 第二步,清除node.js的cache: sudo npm cache clean -f 第三步,安装 n 工具,这个工具是专门用来管理node ...

  10. PHPCMS标签

    获取栏目名:{$CAT[catname]}或{$catname}获取父栏目名:{$CATEGORYS[$CAT[parentid]][catname]} 获取同级栏目列表: {pc:content a ...