java实现读取ftp服务器上的csv文件
定义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文件的更多相关文章
- 使用SAXReader读取ftp服务器上的xml文件(原创)
根据项目需求,需要监测ftp服务器上的文件变化情况,并将新添加的文件读入项目系统(不需要下载). spring配置定时任务就不多说了,需要注意的一点就是,现在的项目很多都是通过maven构建的,分好多 ...
- 使用批处理文件在FTP服务器 上传下载文件
1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt 192.168.1.1 建立一个 ...
- Spring学习---Spring中利用组件实现从FTP服务器上传/下载文件
FtpUtil.java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcepti ...
- JAVA通过FTP方式向远程服务器或者客户端上传、下载文件,以及删除FTP服务器上的文件
1.在目标服务器上搭建FTP服务器 搭建方式有多种大家可以自行选择,例如使用Serv-U或者FTPServer.exe:这里我以FTPServer.exe为例搭建:在目标服务器(这里对应的IP是10. ...
- 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器
引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...
- 从 FTP 服务器上下载并保存文件
本例演示如何运用 C# 中的 FtpWebRequest 等对象从 FTP 服务器上获取文件,并结合 Stream 对象中的方法来保存下载的文件: using System; using System ...
- 解决FTP服务器上中文名文件下载后为空的问题
转: 解决FTP服务器上中文名文件下载后为空的问题 2017年07月20日 15:19:21 代码的寂寞 阅读数 2428 版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...
- java:nginx(java代码操作ftp服务器)
1.检查是否安装了vsftpd [root@linux01 ~]# rpm -qa|grep vsftpd 2.安装vsftpd [root@linux01 ~]# yum -y install vs ...
- 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹
打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问 在win98,winme,win2000,win2003下都能正常上传文件夹,但在winxp+sp2下同样的文件夹就可能出现问题 1. 打开 ...
随机推荐
- 第二章 logstash - 输出插件之redis与es
最常用的两个输出插件: redis es 一.redis 1.用法 output { redis{ batch => false batch_events => 50 batch_time ...
- libcurl库的http get和http post使用【转】
一.libcurl中的http get使用方法 1. 为什么要使用libcurl 1) 作为http的客户端,可以直接用socket连接服务器,然后对到的数据进行http解析,但要分析协议头,实现代理 ...
- Binary Tree Maximum Path Sum leetcode java
题目: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tr ...
- (转)C# SendMessage 参数与例子
原文:http://hi.baidu.com/ytmeng/blog/item/25f5de5157931a888c543001.html using System;using System.IO;u ...
- oracle常用& to_date()怎么转换带am pm的时间格式
Oracle一.字符函数--大小写转换函数1.LOWER (strexp) 返回字符串,并将所有的字符小写. select lower('ABCDE') from dual --输出empbai ...
- python os.path模块常用方法详解 ZZ
os.path模块主要用于文件的属性获取,在编程中经常用到,以下是该模块的几种常用方法.更多的方法可以去查看官方文档:http://docs.python.org/library/os.path.ht ...
- 对Attention is all you need 的理解
https://blog.csdn.net/mijiaoxiaosan/article/details/73251443 本文参考的原始论文地址:https://arxiv.org/abs/1706. ...
- lvs 隧道模式请求没有回应的解决
众所周知,lvs共有三种转发机制:NAT,IPTUNNELING与DIRECT ROUTING 我在做隧道模式实验时遇到了一个问题,客户端向虚拟ip(即隧道0的ip)发送请求后,lvs服务器接收到了请 ...
- [Functional Programming] Using Last monoid with Maybe
Imaging we have a deck of cards, eveytimes we need to pick one card from deck, the result we want to ...
- cocos2d-x3.0 XML解析
在2dx3.0中xml解析已经不用自己找库了.已经为我们集成好了. text.xml <?xml version ="1.0" encoding ="UTF8&qu ...