如果寫入文件到ftp時要改變編碼的話用 ftpClient.setAutodetectUTF8(true);而不是string.getbates("utf-8").編碼影響到了md5,sha等加密的值。親試過的坑
import com.vividsolutions.jts.io.InputStreamInStream;
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.beans.factory.annotation.Value;
import java.io.*;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class FtpUtils {
private static final Logger logger = LoggerFactory.getLogger(FtpUtils.class);
public FTPClient ftpClient = null;
/**
* 初始化ftp服務器
*/
public boolean initFtpClient() {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("utf-8");
try {
logger.info("連接ftp服務器:"+ BaseParamConfig.hostname+":"+BaseParamConfig.port);
ftpClient.connect(BaseParamConfig.hostname, BaseParamConfig.port); //連接ftp服務器
ftpClient.login(BaseParamConfig.username, BaseParamConfig.password); //登錄ftp服務器
int replyCode = ftpClient.getReplyCode(); //是否成功登錄服務器
if(!FTPReply.isPositiveCompletion(replyCode)){
logger.error("【郵儲清分】連接失敗...ftp服務器:");
return false;
}
logger.info("連接成功...ftp服務器:");
}catch (MalformedURLException e) {
e.printStackTrace();
logger.error("【郵儲清分】連接出現異常-----"+e.getMessage());
return false;
}catch (IOException e) {
e.printStackTrace();
logger.error("【郵儲清分】連接出現異常-----"+e.getMessage());
return false;
}
return true;
}
/**
* 把文件寫入到ftp
* startName 開始文件名
* path 路勁
* fileContent 內容
* fileName 文件名全名
*/
public boolean writeFile(String path,String fileContent,String fileName,String startName){
logger.info("開始執行寫入--"+"路徑: "+path +" 文件名:"+fileName);
InputStream is = null;
try {
// 1.輸入流
is = new ByteArrayInputStream(fileContent.getBytes());
// Inputin = new InputStreamInStream(is);
// 4.指定寫入的目錄
ftpClient.changeWorkingDirectory(path);
FTPFile[] ftpFiles = ftpClient.listFiles();
//因爲文件經過加密 密值都不同 覆蓋不了原先文件 所以要先刪除當日之前上傳過的文件
for (int i = 0; i < ftpFiles.length; i++) {
String name = ftpFiles[i].getName();//文件名
if (name.startsWith(startName)) {
ftpClient.dele(name);
logger.info("刪除了文件:{}",name);
}
}
//5.寫操作
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setFileTransferMode(FTPClient.BINARY_FILE_TYPE);
ftpClient.setAutodetectUTF8(true);
ftpClient.storeFile(fileName, is);
FTPFile[] ftpFiles2 = ftpClient.listFiles();
ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
logger.warn("【郵儲清分】寫入文件時出現異常---"+e.getMessage());
return false;
}finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (Exception e) {
e.printStackTrace();
logger.warn("【郵儲清分】寫入文件時出現異常---"+e.getMessage());
return false;
}
}
}
return true;
}
/**
* 上傳文件
* @param pathname ftp服務保存地址
* @param fileName 上傳到ftp的文件名
* @param originfilename 待上傳文件的名稱(絕對地址) *
* @return
*/
public boolean uploadFile( String pathname, String fileName,String originfilename){
boolean flag = false;
InputStream inputStream = null;
try{
System.out.println("開始上傳文件");
inputStream = new FileInputStream(new File(originfilename));
initFtpClient();
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
CreateDirecroty(pathname);
ftpClient.makeDirectory(pathname);
ftpClient.changeWorkingDirectory(pathname);
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
flag = true;
System.out.println("上傳文件成功");
}catch (Exception e) {
System.out.println("上傳文件失敗");
e.printStackTrace();
}finally{
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
/**
* 上傳文件
* @param pathname ftp服務保存地址
* @param fileName 上傳到ftp的文件名
* @param inputStream 輸入文件流
* @return
*/
public boolean uploadFile( String pathname, String fileName,InputStream inputStream){
boolean flag = false;
try{
System.out.println("開始上傳文件");
initFtpClient();
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
CreateDirecroty(pathname);
ftpClient.makeDirectory(pathname);
ftpClient.changeWorkingDirectory(pathname);
ftpClient.storeFile(fileName, inputStream);
inputStream.close();
ftpClient.logout();
flag = true;
System.out.println("上傳文件成功");
}catch (Exception e) {
System.out.println("上傳文件失敗");
e.printStackTrace();
}finally{
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
//改變目錄路徑
public boolean changeWorkingDirectory(String directory) {
boolean flag = true;
try {
flag = ftpClient.changeWorkingDirectory(directory);
if (flag) {
System.out.println("進入文件夾" + directory + " 成功!");
} else {
System.out.println("進入文件夾" + directory + " 失敗!開始創建文件夾");
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return flag;
}
//創建多層目錄文件,如果有ftp服務器已存在該文件,則不創建,如果無,則創建
public boolean CreateDirecroty(String remote) throws IOException {
boolean success = true;
String directory = remote + "/";
// 如果遠程目錄不存在,則遞歸創建遠程服務器目錄
if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
int start = 0;
int end = 0;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
String path = "";
String paths = "";
while (true) {
String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
path = path + "/" + subDirectory;
if (!existFile(path)) {
if (makeDirectory(subDirectory)) {
changeWorkingDirectory(subDirectory);
} else {
System.out.println("創建目錄[" + subDirectory + "]失敗");
changeWorkingDirectory(subDirectory);
}
} else {
changeWorkingDirectory(subDirectory);
}
paths = paths + "/" + subDirectory;
start = end + 1;
end = directory.indexOf("/", start);
// 檢查所有目錄是否創建完畢
if (end <= start) {
break;
}
}
}
return success;
}
//判斷ftp服務器文件是否存在
public boolean existFile(String path) throws IOException {
boolean flag = false;
FTPFile[] ftpFileArr = ftpClient.listFiles(path);
if (ftpFileArr.length > 0) {
flag = true;
}
return flag;
}
//創建目錄
public boolean makeDirectory(String dir) {
boolean flag = true;
try {
flag = ftpClient.makeDirectory(dir);
if (flag) {
System.out.println("創建文件夾" + dir + " 成功!");
} else {
System.out.println("創建文件夾" + dir + " 失敗!");
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 根據條件模糊查詢文件
* pathname linux絕對路徑
* filename 開頭字符串 如:Q_20181011
*/
public FtpSettleVO likeFileList(String pathname, String filename, String endFileName) {
FtpSettleVO settleVO = new FtpSettleVO();
logger.info("開始讀取郵儲回盤的文件---"+"路徑:"+pathname +" 開頭名:"+filename+" 結束名: "+endFileName);
List<String > lists = new ArrayList<>();
try {
ftpClient.changeWorkingDirectory(pathname);
FTPFile[] ftpFiles = ftpClient.listFiles();
//現在只做讀取單個就退出
for (int i = 0; i < ftpFiles.length; i++) {
String name = ftpFiles[i].getName();//文件名
logger.info("正在讀取的文件名稱---"+name);
if (name.startsWith(filename)&&name.endsWith(endFileName)) {
logger.info("正在執行的文件名稱---"+name);
InputStream ins = null;
StringBuilder builder = null;
String str="";
try {
// 從服務器上讀取指定的文件
ins = ftpClient.retrieveFileStream(ftpFiles[i].getName());
BufferedReader reader = new BufferedReader(new InputStreamReader(ins, "utf-8"));
String line;
builder = new StringBuilder();
int s=0;
while ((line = reader.readLine()) != null) {
if (s>0){
builder.append("\n");
}
lists.add(line);
builder.append(line);
s++;
}
str = builder.toString();
str = new String(str.getBytes("gbk"));
reader.close();
if (ins != null) {
ins.close();
} //主動調用一次getReply()把接下來的226消費掉. 這樣做是可以解決這個返回null問題
ftpClient.getReply();
} catch (Exception e) {
e.printStackTrace();
settleVO.setExMessage(e.toString()+":"+e.getMessage());
logger.warn("執行讀取文件出現異常-----"+e.getMessage());
}
settleVO.setFileName(name);
settleVO.setConten(str);
settleVO.setList(lists);
return settleVO;
}
}
ftpClient.logout();
settleVO.setList(lists);
return settleVO;
} catch (IOException e) {
e.printStackTrace();
settleVO.setExMessage(e.toString()+":"+e.getMessage());
logger.warn("【郵儲清分】讀取文件時出現異常-----"+e.getMessage());
} finally {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
settleVO.setExMessage(e.toString()+":"+e.getMessage());
logger.warn("【郵儲清分】讀取文件時出現異常-----"+e.getMessage());
}
}
}
return settleVO;
}
/** * 下載文件 *
* @param pathname FTP服務器文件目錄 *
* @param filename 文件名稱 *
* @param localpath 下載後的文件路徑 *
* @return */
public boolean downloadFile(String pathname, String filename, String localpath){
boolean flag = false;
OutputStream os=null;
try {
System.out.println("開始下載文件");
initFtpClient();
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathname);
FTPFile[] ftpFiles = ftpClient.listFiles();
for(FTPFile file : ftpFiles){
if(filename.equalsIgnoreCase(file.getName())){
File localFile = new File(localpath + "/" + file.getName());
os = new FileOutputStream(localFile);
ftpClient.retrieveFile(file.getName(), os);
os.close();
}
}
ftpClient.logout();
flag = true;
System.out.println("下載文件成功");
} catch (Exception e) {
System.out.println("下載文件失敗");
e.printStackTrace();
} finally{
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
if(null != os){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return flag;
}
/** * 刪除文件 *
* @param pathname FTP服務器保存目錄 *
* @param filename 要刪除的文件名稱 *
* @return */
public boolean deleteFile(String pathname, String filename){
boolean flag = false;
try {
System.out.println("開始刪除文件");
initFtpClient();
//切換FTP目錄
ftpClient.changeWorkingDirectory(pathname);
ftpClient.dele(filename);
ftpClient.logout();
flag = true;
System.out.println("刪除文件成功");
} catch (Exception e) {
System.out.println("刪除文件失敗");
e.printStackTrace();
} finally {
if(ftpClient.isConnected()){
try{
ftpClient.disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
return flag;
}
public static void main(String[] args) {
FtpUtils ftp =new FtpUtils();
ftp.initFtpClient();
ClearingVO clea = new ClearingVO();
clea.setMerchant("00023155");
clea.setMerchantName("大神");
clea.setDate(DateUtil.getYYYYMMDD(new Date()));
String number = Myutil.formatDate();
clea.setOrderNo(number);
clea.setBankNo("");
clea.setAccountName("張三");
clea.setAccount("6210985800000004763");
clea.setMoney("10000");
clea.setSummary("無摘要");
clea.setRemark("這筆是正確的");
List<ClearingVO> list = new ArrayList<>();
for (int i = 0; i < 30; i++) {
list.add(clea);
}
//模擬郵儲清分
StringBuilder str = new StringBuilder();
str.append("30");//總筆數
str.append("|");
str.append("300000");//總金額
str.append("|");
int a =0;
for (ClearingVO c:list) {
a++;
str.append("\n");
str.append(a);//清分id
str.append("|");
str.append(Myutil.toString(c.getMerchant()));//商戶號
str.append("|");
str.append(Myutil.toString(c.getMerchantName()));//商戶名
str.append("|");
str.append(c.getDate());//訂單日期
str.append("|");
str.append(c.getOrderNo()+a);//訂單號
str.append("|");
str.append(Myutil.toString(c.getBankNo()));//支付行號
str.append("|");
str.append(Myutil.toString(c.getAccountName()));//收款人姓名
str.append("|");
str.append(Myutil.toString(c.getAccount()));//收款賬號
str.append("|");
str.append(Myutil.toString(c.getMoney()));//清分金額
str.append("|");
str.append(Myutil.toString(c.getSummary()));//摘要
str.append("|");
str.append(Myutil.toString(c.getRemark()));//備註
str.append("|");
}
// System.out.println(str.toString());
//文件名 文件名規格 請求文件名 QS_YYYYMMDDNNN_XXX_Q.txt
// String fileName ="QS_"+DateUtil.getYYYYMMDD(new Date())+"001"+"_001"+"_Q.txt";
/**
* 把內容寫成TXT 傳到ftp
*/
// boolean result = ftp.writeFile("/zcode",str.toString(),fileName);
// boolean result = ftp.writeFile("/postal",str.toString(),"ftp.txt");
// System.out.println(result);
/**
* 根據模糊條件讀取ftp文件
*/
// String fileName ="QS_"+DateUtil.getYYYYMMDD(new Date())+"001"+"_001"+"_R.txt";
String fileName ="QS_20181017";
List<String > lists = ftp.likeFileList("/postal",fileName,"001_R.txt");
}