定义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. Android Animatioin总结

    一.动画分类 1.  View Animation (Tween动画)  执行一系列简单的转换.      针对 视图对象内容进行移动,放大,缩小以及产生透明度的变化等四种动画操作.仅针对视图对象内容 ...

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

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

  3. jQuery操作Frame(iFrame)

    没找到很好的方法只好用DOM方法与jquery方法结合的方式实现了 1.在父窗口中操作 选中IFRAME中的所有单选钮$(window.frames["iframe1"].docu ...

  4. MFC中打印对话框CPrintDialog类

    void CCPrintDialogView::OnPrint() { DWORD dwflags=PD_ALLPAGES|PD_NOPAGENUMS|PD_USEDEVMODECOPIES|PD_S ...

  5. Java面试问题总结

    前几天Java面试中遇到的问题,这仅仅是当中的一部分问题.面试中有非常多问题是关于数据结构和算法的.在这里做下总结,希望有能力的人能够试着做一下,并在评论区留下您的答案.让大家相互学习.谢谢 程序设计 ...

  6. Laravel学习笔记之Session源码解析(下)

    说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码.实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介 ...

  7. R-向量

  8. Sublime 格式化代码 设置快捷键以及插件使用

    实在sublime中已经自建了格式化按钮: Edit  ->  Line  ->  Reindent 只是sublime并没有给他赋予快捷键,所以只需加上快捷键即可 Preference ...

  9. SpringBoot添加对jsp的支持

    1.在pom.xml添加如下内容: <dependency> <groupId>org.apache.tomcat.embed</groupId> <arti ...

  10. 微信小程序 - 分包加载(独立分包)

    独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行.从独立分包中页面进入小程序时,不需要下载主包.当用户进入普通分包或主包内页面时,主包才会被下载 将某些具有一定功能独立性的页面配置到 ...