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();
        }
    }

原文地址:https://www.cnblogs.com/zjfjava/p/9611194.html

时间: 2024-08-03 01:56:34

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

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

根据项目需求,需要监测ftp服务器上的文件变化情况,并将新添加的文件读入项目系统(不需要下载). spring配置定时任务就不多说了,需要注意的一点就是,现在的项目很多都是通过maven构建的,分好多子项目,通过pom互相依赖,定时任务的配置文件需要放到tomcat等容器发布的工程下,而不要放到任务所在的子项目里面,bean的class属性是可以通过项目依赖读取到其他子项目里面的class的,而且任务类需要有构造方法,涉及到spring架构的bean的知识,说的有点多了... =========

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

1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt   192.168.1.1 建立一个批处理文件:命名为 test.bat(名称可以随便,为了方便操作,直接命名为1.bat)  然后将上面的内容拷贝进去 ftpconfig.txt的文件内容是: testuser test get test.exe    C:\ftptest\testdownload.exe bye 解释: 前两条命

Java通过FTP服务器上传下载文件的解决方案

对于使用文件进行交换数据的应用来说,使用FTP 服务器是一个很不错的解决方案.本文使用Apache Jakarta Commons Net(commons-net-3.3.jar)基于FileZilla Server服务器实现FTP服务器上文件的上传/下载/删除等操作. 关于FileZilla Server服务器的详细搭建配置过程,详情请见FileZilla Server安装配置教程.之前有朋友说,上传大文件(几百M以上的文件)到FTP服务器时会重现无法重命名的问题,但本人亲测上传2G的文件到F

如何直接处理FTP服务器上的压缩文件?

我最近要写一个供有相关权限的管理人员查询大额资金明细的程序,界面如下: 所需的数据文件是放在报表服务器上,每天一个压缩文件,该压缩文件中除了所需的储蓄流水账文件外,还有很多其他的文件.如果先把该压缩文件从报表服务器下载到应用服务器上,再进行解压缩处理的话,一是多下载了该压缩文件中我们不需要的其他文件,二是还必须在应用服务器上建立以SessionID等方法标识的临时文件,以免其他用户也在进行查询时文件名冲突,三是使用完毕后还必须删除该临时文件. 我的处理方法是如下: using (ZipInput

Spring中利用组件实现从FTP服务器上传/下载文件

FtpUtil.java import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.ne

java读取FTP服务器上gz文件

FTPClient client = new FTPClient(); client.connect(CREDITDATA_FTP_IP, CREDITDATA_FTP_PORT); client.login(FTP_USERNAME, FTP_PASSWORD); client.changeWorkingDirectory("/out"); client.enterLocalPassiveMode(); //打开本地被动模式 client.setFileType(FTPClient.

在FTP服务器上给不同的用户设置不同的权限实现不同的功能

实验环境:一台原始干净的虚拟机,ip地址为172.20.53.1.并且事先为这台虚拟机安装上web服务器和ftp服务器 实验目的:使zhangsan能实现上传下载,lisi只能上传,匿名用户只能下载 实验步骤: 首先创建FTP站点,默认情况下,IIS管理器中只有一个Web站点,下面新建一个FTP站点,单击右侧"操作"面板中的"添加FTP站点"选项.启动"添加FTP站点"向导. 为站点起个名字,并指定FTP站点的主目录,FTP默认的主目录是:C:\

windows、linux通过ftp从ftp服务器上传和下载

最近需要用到文件的上传和下载,查看我们使用的系统,发现有一个进程为t_ftpd,怀疑其为一个ftp的守护进程,于是想要用ftp的方式实现. 在windows上使用bat脚本的方式实现: 首先写一个bat脚本: download.bat @echo off ftp -s:E:\Sylixos\SylixOS_Qt\build-TCWareWigget-Desktop_Qt_5_7_1_MinGW_32bit-Debug\debug\ftp\ftp.txt 这样就会调用ftp.txt文件 ftp.t

从ftp服务器上下载文件

从ftp服务器上下载文件 FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务. FTP是File Transfer Protocol(文件传输协议).顾名思义,就是专门用来传输文件的协议.简单地说,支持FTP协议的服务器就是FTP服务器. 那么怎样从ftp服务器上下载文件呢?具体操作如下: ftpget -u zyx -p 123456  192.168.1.156  /hello ftpget :指令