定义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. C#中转义字符[转]

    https://www.cnblogs.com/muran/p/3174865.html 编程中很多细节问题我们都要十分的注意,要不一个小小的字母错误就能引起程序的无法运行. C#中转义字符分2中,一 ...

  2. easyui +ASP.NET 前后台乱码解决方法

    前端接口 decodeURIencodeURI 后台接口 System.Web.HttpUtility.UrlEncode(user.name) 凡是涉及到中文的地方都要使用这几个接口

  3. ASP.NET中Session的个人浅谈

    看到博客园的一个哥们写的面试经历,想到了面试中常问到的Session,一时手痒就谈下自己对Session的理解,这东西最开始在用户登录登出的时候用到过,后来一直没怎么用过,里面还是有很多知识点值得注意 ...

  4. Unique Paths leetcode java

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  5. Mac系统下编译支持Android平台的最新X264编码器

    Mac系统下编译支持Android平台的最新X264编码器 原文来自 http://www.mingjianhua.com,转载请注明出处 1.首先去官网下载最新的x264源代码,解压到任意目录 ht ...

  6. ACCESS和MSSQL-如何随机读取数据库记录

    查询语句只要这样写,就可以随机取出记录了 SQL="Select top 6 * from Dv_bbs1 where isbest = 1 and layer = 1 order by n ...

  7. Python过滤emoji

    参考博客:http://my.oschina.net/jiemachina/blog/189460 1. 将emoji表情替换为指定字符串 import re def filter_emoji(des ...

  8. Netcore使用MailKit进行邮件发送

    public void TestSendMailDemo() { var message = new MimeKit.MimeMessage(); message.From.Add(new MimeK ...

  9. SQL Server 2008——SQL命令INSERT

    T-SQL的INSERT命令的语法: INSERT [INTO]     {table_name|view_name}     [{(column_name,column_name,-)}]     ...

  10. 栈的实现与操作(C语言实现)

    栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作 ...