不管是ftp还是sftp都要引入下面的第三方jar包
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
csv文件操作需要引入第三方jar包:
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
ftp工具类
ftputils:(会自动创建未存在的目录)
import com.csvreader.CsvReader;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* FTP工具类
*
* @author ZhiXy
* @since 2018-02-27 21:57
*/
public class FtpUtils {
private static Logger logger = LoggerFactory.getLogger(FtpUtils.class);
public final static char SEPARATOR_CSV = ',';
/**
* 上传文件
*
* @param ftpHost FTP服务器地址
* @param ftpPort FTP服务器端口号
* @param ftpUserName FTP登录帐号
* @param ftpPassword FTP登录密码
* @param ftpPath FTP服务器保存目录
* @param fileName 上传到FTP服务器后的文件名称
* @param csvData csv文件值
* @return
*/
public static boolean uploadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
String ftpPath, String fileName, String csvData) {
ftpPath = ftpPath.replaceAll("\\\\{1,}","/");
ftpPath = ftpPath.replaceAll("/{1,}","/");
boolean flag = false;
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
try {
ByteArrayInputStream inputStream = new ByteArrayInputStream(csvData.getBytes());
//连接FTP服务器
ftpClient.connect(ftpHost, ftpPort);
//登录FTP服务器
ftpClient.login(ftpUserName, ftpPassword);
//是否成功登录FTP服务器
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//切换到上传目录,不存在则创建
if (!createDir(ftpPath, ftpClient)) {
logger.info("ftp目录创建失败,{}",ftpPath);
return false;
}
ftpClient.changeWorkingDirectory(ftpPath);
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
flag = true;
} catch (Exception e) {
logger.info("ftp文件上传错误", e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag;
}
/**
* 创建目录(有则切换目录,没有则创建目录)
* @param dir
* @return
*/
public static boolean createDir(String dir, FTPClient ftp){
String d;
try {
//目录编码,解决中文路径问题
d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");
//尝试切入目录
if(ftp.changeWorkingDirectory(d)) {
return true;
}
if (dir.matches("^/.*")) {
dir = dir.substring(1);
}
if (dir.matches(".*/$")) {
dir = dir.substring(0,dir.length() - 2);
}
// dir.replaceAll("\\\\\\\\","/");
String[] arr = dir.split("/");
StringBuffer sbfDir=new StringBuffer();
//循环生成子目录
for(String s : arr){
sbfDir.append("/");
sbfDir.append(s);
//目录编码,解决中文路径问题
d = new String(sbfDir.toString().getBytes("GBK"),"iso-8859-1");
//尝试切入目录
if(ftp.changeWorkingDirectory(d)) {
continue;
}
if(!ftp.makeDirectory(String.valueOf(sbfDir))){
logger.info("[失败]ftp创建目录:"+sbfDir.toString());
return false;
}
logger.info("[成功]创建ftp目录:"+sbfDir.toString());
}
//将目录切换至指定路径
return ftp.changeWorkingDirectory(d);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static List<String> readCsv(String filePath, String fileName) {
List<String> records = new ArrayList<>();
if (StringUtils.isEmpty(filePath) || StringUtils.isEmpty(fileName)) {
return null;
}
try {
// 创建CSV读对象
CsvReader csvReader = new CsvReader(filePath +File.separator + fileName, SEPARATOR_CSV, Charset.forName("UTF-8"));
// 读表头
/* csvReader.readHeaders();
System.out.println(JSON.toJSONString(csvReader.getHeaders()));*/
while (csvReader.readRecord()) {
// 读一整行
records.add(csvReader.getRawRecord());
// 读这行的某一列
//System.out.println(csvReader.get(1));
}
} catch (Exception e) {
logger.warn("读取CSV文件异常", e);
}
return records;
}
/**
* 创建目录
*
* @param hostname FTP服务器地址
* @param port FTP服务器端口号
* @param username FTP登录帐号
* @param password FTP登录密码
* @param pathname 创建的目录
* @return
*/
public static boolean createDir(String hostname, int port, String username, String password, String pathname) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
//连接FTP服务器
ftpClient.connect(hostname, port);
//登录FTP服务器
ftpClient.login(username, password);
//验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return flag;
}
if (ftpClient.changeWorkingDirectory(pathname)) {
return true;
} else if (!ftpClient.makeDirectory(pathname)) {
logger.info("创建目录错误,path={}", pathname);
return false;
}
ftpClient.logout();
flag = true;
} catch (Exception e) {
logger.info("创建目录失败", e);
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
} catch (IOException e) {
}
}
}
return flag;
}
/**
* 下载文件
* @param hostname FTP服务器地址
* @param port FTP服务器端口号
* @param username FTP登录帐号
* @param password FTP登录密码
* @param pathname FTP服务器文件目录
* @param filename 文件名称
* @param localPath 下载后的文件路径
* @return
*/
public static boolean downloadFile(String hostname, int port, String username, String password, String pathname,
String filename, String localPath){
boolean flag = false;
FTPClient ftpClient = new FTPClient();
try {
//连接FTP服务器
ftpClient.connect(hostname, port);
//登录FTP服务器
ftpClient.login(username, password);
//验证FTP服务器是否登录成功
int replyCode = ftpClient.getReplyCode();
if(!FTPReply.isPositiveCompletion(replyCode)){
return flag;
}
//切换FTP目录
ftpClient.changeWorkingDirectory(pathname);
FTPFile[] ftpFiles = ftpClient.listFiles();
for(FTPFile file : ftpFiles){
if(filename.equalsIgnoreCase(file.getName())){
File localFile = new File(localPath + File.separator + file.getName());
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally{
if(ftpClient.isConnected()){
try {
ftpClient.logout();
} catch (IOException e) {
}
}
}
return flag;
}
}
sftp工具类
/**
* sftp下载工具(会自动创建未存在的目录)
*/
import com.bosssoft.itfinance.citizen.teamcommon.BaseException;
import com.csvreader.CsvReader;
import com.jcraft.jsch.*;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
public class SftpUtils {
private final static Logger logger = LoggerFactory.getLogger(SftpUtils.class);
public final static char SEPARATOR_CSV = ',';
public final static String NO_SUCH_FILE = "No such file";
/**
* 从SFTP服务器下载文件
* @param ftpHost SFTP IP地址
* @param ftpUserName SFTP 用户名
* @param ftpPassword SFTP用户名密码
* @param ftpPort SFTP端口
* @param ftpPath SFTP服务器中文件所在路径 格式: ftptest/aa
* @param localPath 下载到本地的位置 格式:H:/download
* @param fileName 文件名称
*/
public static void downloadSftpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
String ftpPath, String localPath, String fileName) throws Exception {
Session session = null;
Channel channel = null;
ChannelSftp chSftp = null;
String downMsgLog = null;
try {
JSch jsch = new JSch();
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
session.setPassword(ftpPassword);
session.setTimeout(100000);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "req");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
chSftp = (ChannelSftp) channel;
String ftpFilePath = ftpPath + "/" + fileName;
String localFilePath = localPath + File.separatorChar + fileName;
File file = new File(localPath);
if (!file.exists() && !file.isDirectory()) {
logger.warn("本地文件路径不存在,创建本地文件路径");
file.mkdirs();
}
chSftp.get(ftpFilePath, localFilePath);
logger.info("文件下载完成");
} catch (SftpException sftpException) {
if (NO_SUCH_FILE.equals(sftpException.getMessage())) {
throw new BaseException("-1", "对账文件不存在,请稍后下载");
} else {
logger.warn("文件下载失败");
throw sftpException;
}
} catch (Exception e) {
logger.warn("文件下载错误");
throw e;
} finally {
chSftp.quit();
channel.disconnect();
session.disconnect();
}
}
/**
* 上传文件到SFTP服务器
* @param ftpHost SFTP IP地址
* @param ftpUserName SFTP 用户名
* @param ftpPassword SFTP用户名密码
* @param ftpPort SFTP端口
* @param ftpPath SFTP服务器中文件所在路径 格式: ftptest/aa
* @param fileName 文件名称
*/
public static void uploadSftpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
String ftpPath, String fileName, String csvData) throws BaseException {
ftpPath = ftpPath.replaceAll("\\\\{1,}","/");
ftpPath = ftpPath.replaceAll("/{1,}","/");
Session session = null;
Channel channel = null;
ChannelSftp chSftp = null;
try {
JSch jsch = new JSch();
session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
session.setPassword(ftpPassword);
session.setTimeout(100000);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "req");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
chSftp = (ChannelSftp) channel;
String ftpFilePath = ftpPath + "/" + fileName;
ByteArrayInputStream stream = new ByteArrayInputStream(csvData.getBytes());
mkDir(ftpPath,chSftp);
chSftp.put(stream, ftpFilePath);
logger.info("上传文件完成,ftpHost={},ftpUserName={},ftpPassword={},ftpPort={},ftpPath={},fileName={}",
ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName);
} catch (Exception e) {
logger.info("上传文件异常,ftpHost={},ftpUserName={},ftpPassword={},ftpPort={},ftpPath={},fileName={}",
ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName, e);
throw new BaseException("-1", "上传文件异常,e=" + e.getMessage());
} finally {
if (chSftp != null) {
chSftp.quit();
}
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
/**
* 创建指定文件夹
*
* @param dirName
* dirName
*/
public static void mkDir(String dirName,ChannelSftp chSftp) throws UnsupportedEncodingException {
if (dirName.matches("^/.*")) {
dirName = dirName.substring(1);
}
String[] dirs = dirName.split("/");
try
{
String now = chSftp.pwd();
chSftp.cd("/");
for (int i = 0; i < dirs.length; i++)
{
String isodir = dirs[i];
boolean dirExists = openDir(isodir,chSftp);
if (!dirExists)
{
chSftp.mkdir(isodir);
chSftp.cd(isodir);
logger.info("创建{}成功",isodir);
}
}
chSftp.cd("/");
}
catch (SftpException e)
{
logger.error("mkDir Exception : " + e);
}
}
/**
* 打开指定目录
*
* @param directory
* directory
* @return 是否打开目录
*/
public static boolean openDir(String directory,ChannelSftp sftp)
{
try
{
sftp.cd(directory);
logger.info("进入{}成功",directory);
return true;
}
catch (SftpException e)
{
logger.info("进入{}失败",directory);
return false;
}
}
}
测试:
@Test
public void g() {
String ftpHost = "127.0.0.1";
String ftpUserName = "test";
String ftpPassword = "1";
int ftpPort = 21;
String ftpPath = "/home/test/wlt/l/t/";
String csvData = "ceshi shuj ";
String fileName = "mt.txt";
FtpUtils.uploadFtpFile(ftpHost, ftpUserName,ftpPassword ,ftpPort, ftpPath, fileName,csvData);
}