package com.suning.search.datatransfer.common.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class Ftp {
//创建ftp目录,从根目录开始创建
public void CreateFtpDirectory(FTPClient ftp,String serverPath) throws IOException{
ftp.changeWorkingDirectory("/");//从根目录开始创建
String dirs[] = serverPath.split("/");
for(String str:dirs){
if(!"".endsWith(str)){
ftp.makeDirectory(str);
ftp.changeWorkingDirectory(str);
}
}
}
public boolean Upload(FTPClient ftp,String localPath,String serverPath) throws IOException{
//更改目录到上传目录
if(!ftp.changeWorkingDirectory(serverPath)){
CreateFtpDirectory(ftp,serverPath);
ftp.changeWorkingDirectory(serverPath);
}
File file = new File(localPath);
if(file.isDirectory()){ //如果是文件夹
ftp.makeDirectory(file.getName()); //在当前目录下新建文件夹
File[] files = file.listFiles();
for(int i = 0;i < files.length;i++){ //上传文件夹内的子文件
Upload(ftp,files[i].toString(),serverPath+"/"+file.getName());
}
}
else{//如果是文件
try{
FileInputStream fis = new FileInputStream(file);
ftp.storeFile(file.getName(),fis);
fis.close();
}
catch(Exception e){
return false;
}
}
return true;
}
public void DeleteDir(FTPClient ftp,String fileDir) throws IOException{
FTPFile[] files = ftp.listFiles(fileDir);
for(FTPFile dir:files){
if(dir.isDirectory()){
DeleteDir(ftp,fileDir+"/"+dir.getName());
}
else{
ftp.deleteFile(fileDir+"/"+dir.getName());
}
}
ftp.removeDirectory(fileDir);
ftp.deleteFile(fileDir);
}
public boolean FtpUpload(String url,String username,String password,String localPath,String serverPath) throws SocketException, IOException{
FTPClient ftp = new FTPClient();
ftp.connect(url); //连接端口
ftp.login(username,password); //登录
int reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)){ //如果登陆不成功
ftp.disconnect();
System.out.println("连接失败");
return false;
}
final String tempPath = "/FtpUploadTemp";
File file = new File(localPath);
//将本地文件上传到tempPath中,2pc第一步
if(!Upload(ftp,localPath,tempPath)) return false;
DeleteDir(ftp,serverPath+"/"+file.getName());//删除serverPath/analyzer(即新文件覆盖旧文件)
try{//将tempPath/analyzer移动到serverPath/analyzer,2pc第二步
if(!ftp.changeWorkingDirectory(serverPath+"/"+file.getName())){
CreateFtpDirectory(ftp,serverPath+"/"+file.getName());
}
ftp.rename(tempPath+"/"+file.getName(), serverPath+"/"+file.getName());
}
catch(Exception e){
System.out.println(e);
}
DeleteDir(ftp,tempPath);//删除临时目录
ftp.disconnect();
return true;
}
}
</pre><p><pre name="code" class="html">package com.suning.search.admin.web.export;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.Autowired;
import org.springframework.stereotype.Component;
import com.suning.search.admin.util.PropertyUtil;
import com.suning.search.admin.web.service.ExportService;
@Component
public class FtpExportUtil {
private static final Logger LOG = LoggerFactory
.getLogger(FtpExportUtil.class);
@Autowired
private ExportService exportService;
private PropertyUtil pu = new PropertyUtil();
private String propertyPath = "/opt/search/admin/configs/dsExportSql.properties";
public ExportService getExportService() {
return exportService;
}
public void setExportService(ExportService exportService) {
this.exportService = exportService;
}
private String[] resolveFTP(String ftp) {
return ftp.split(",");
}
// 导出热搜词到ftp
public boolean export(String local, String fileName, String remote,
String exportSql, ExportRowMapper erm) {
boolean status = true;
if (!local.endsWith("/")) {
local = local + "/";
}
String dsFtp = pu.read().getProperty("dsIps").replace(":8080", "");
String dsFtpUser = pu.read(propertyPath).getProperty("dsFtpUser");
String dsFtpPass = pu.read(propertyPath).getProperty("dsFtpPass");
String[] ftpArray = resolveFTP(dsFtp);// ftp地址数组
if (createLocalFile(local, fileName, exportSql, erm)) {// 生成本地文件
for (int i = 0; i < ftpArray.length; i++) {
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(ftpArray[i]);// 连接ftp
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOG.error("FTP server refused connection.");
System.exit(1);
}
ftp.login(dsFtpUser, dsFtpPass);
if (changeDirectory(remote, ftp)) {
upload(local, remote, fileName, ftp);// 上传到ftp
} else {
status = false;
}
} catch (IOException e) {
LOG.error("FTP连接异常", e);
status = false;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return status;
}
// 导出数据到ftp
public boolean export(String local, String fileName, String remote,
String exportSql, FtpInfo ftpInfo, ExportRowMapper erm) {
boolean status = true;
if (!local.endsWith("/")) {
local = local + "/";
}
if (!local.endsWith("/")) {
local = local + "/";
}
String[] ftpArray = resolveFTP(ftpInfo.getFtpIp());// ftp地址数组
if (createLocalFile(local, fileName, exportSql, erm)) {// 生成本地文件
for (int i = 0; i < ftpArray.length; i++) {
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(ftpArray[i]);// 连接ftp
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOG.error("FTP server refused connection.");
System.exit(1);
}
ftp.login(ftpInfo.getUser(), ftpInfo.getPassword());
if (changeDirectory(remote, ftp)) {
upload(local, remote, fileName, ftp);// 上传到ftp
} else {
status = false;
}
} catch (IOException e) {
LOG.error("FTP连接异常", e);
status = false;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return status;
}
/* 读取数据库,存到本地,数据量大时,分批查询 */
public boolean createLocalFile(String local, String fileName,
String exportSql, ExportRowMapper erm) {
boolean result = true;
int total = exportService.count(exportSql);// 总数据量
int length = 100000;
File file = new File(local + fileName);
FileWriter fw = null;
try {
if (clear(local, fileName) && file.createNewFile()) {// 清空本地路径文件,再生成新文件
fw = new FileWriter(file.getAbsolutePath(), true);
if (total > length) {
int totalPage = total / length + 1;// 总页数
for (int i = 1; i <= totalPage; i++) {
int begin = length * (i - 1);
int end = length * i;
String sql = "select * from (select t.*,ROWNUMBER() OVER() AS row_no from ("
+ exportSql
+ ")as t ) where row_no >"
+ begin
+ " and row_no <=" + end;
List<Map<String, Object>> list = exportService
.find(sql);
result &= generateFile(fw, list, erm);// 生成本地文件
}
} else {
List<Map<String, Object>> list = exportService
.find(exportSql);
result &= generateFile(fw, list, erm);
}
}
} catch (IOException e) {
LOG.error("生成文件" + fileName + "失败");
result = false;
} finally {
try {
fw.close();
} catch (IOException e) {
LOG.error("IO异常");
}
}
LOG.info("生成文件" + fileName);
return result;
}
// 清空本地路径
private boolean clear(String local, String fileName) {
boolean result = true;
try {
File f = new File(local);
if (!f.exists()) {
result &= f.mkdir();
}
for (File ff : f.listFiles()) {
if (ff.isFile() && ff.getName().equals(fileName)) {
result &= ff.delete();
}
}
} catch (NullPointerException e) {
LOG.error("路径" + local + "没有文件");
}
return result;
}
// 生成文件
private boolean generateFile(FileWriter fw, List<Map<String, Object>> list,
ExportRowMapper erm) throws IOException {
boolean result = true;
for (Map<String, Object> m : list) {
Set<String> keySet = m.keySet();
Iterator<String> iterator = keySet.iterator();
StringBuffer sb = new StringBuffer("");
while (iterator.hasNext()) {
String key = iterator.next();// 获取key
if ("ROW_NO".equals(key)) {
continue;
}
Object value = m.get(key);// 获取值
if (value instanceof String) {
String str = (String) value;
byte[] b = str.getBytes("utf-8");
String s = new String(b, "utf-8");
s = s.replaceAll("\"", "").trim();// 去掉联想词里的引号,逗号
s = s.replaceAll(",", "").trim();
value = s;
}
sb.append(value).append(",");
}
if (erm != null) {
fw.write(erm.mapRow(sb.toString().trim()));
} else {
fw.write(sb.toString() + "\r\n");// windows使用\r\n换行,linux使用\n
}
}
return result;
}
// ftp切换目录,不存在就创建
private boolean changeDirectory(String path, FTPClient ftp) {
FTPFile[] files;
boolean result = false;
String[] str = path.split("/");
for (String s : str) {
try {
boolean exist = false;// 路径是否存在
files = ftp.listFiles();
for (FTPFile f : files) {
if (f.isDirectory() && !"".equals(s)
&& f.getName().equals(s)) {
exist = true;
}
}
if (!exist) {
ftp.makeDirectory(s);
}
result = ftp.changeWorkingDirectory(s);
} catch (IOException e) {
LOG.error("连接FTP异常", e);
}
}
return result;
}
// 上传文件
private void upload(String local, String remote, String fileName,
FTPClient ftp) {
boolean result = true;// 文件上传是否成功
boolean delete = true;
InputStream input;
File directory = new File(local);
for (File f : directory.listFiles()) {
if (f.isFile() && f.getName().equals(fileName)) {
try {
FTPFile[] files = ftp.listFiles();
for (FTPFile ftpFile : files) {
if (ftpFile.isFile()
&& ftpFile.getName().equals(fileName)) {
delete &= ftp.deleteFile(ftpFile.getName());
}
}
if (delete) {
input = new FileInputStream(local + fileName);// name带后缀名
/*
* byte[] buf = new byte[1024]; int hasRead = 0;
* LOG.info("开始上传" + fileName); while ((hasRead =
* input.read(buf)) > 0) { String s = new String(buf, 0,
* hasRead, "UTF-8"); InputStream in = new
* ByteArrayInputStream( s.getBytes("UTF-8")); if
* (!ftp.appendFile(fileName, in)) { result = false;
* LOG.error("上传文件失败"); break; } }
*/
result = ftp.storeFile(fileName, input);
input.close();
if (result) {
LOG.info("文件" + fileName + "上传"
+ ftp.getRemoteAddress() + "成功");
} else {
LOG.info("文件" + fileName + "上传"
+ ftp.getRemoteAddress() + "失败");
}
} else {
LOG.info("删除FTP" + ftp.getRemoteAddress() + "文件"
+ fileName + "失败");
}
} catch (FileNotFoundException e) {
LOG.error("文件" + fileName + "未找到", e);
} catch (IOException e) {
LOG.error("FTP连接异常", e);
}
}
}
}
/**
*
* 功能描述: <br>
* 上传文件至AS服务器
*
* @param local
* @param remote
* @param fileName
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public boolean upload2ASServer(String local, String remote, String fileName) {
String ips = pu.read().getProperty("ips2");
String ftpUser = pu.read().getProperty("ftpUser");
String ftpPassword = pu.read().getProperty("ftpPassword");
boolean status = true;
String[] ftpArray = resolveFTP(ips);// ftp地址数组
for (int i = 0; i < ftpArray.length; i++) {
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect(ftpArray[i]);// 连接ftp
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOG.error("FTP server refused connection.");
System.exit(1);
}
ftp.login(ftpUser, ftpPassword);
if (changeDirectory(remote, ftp)) {
upload(local, remote, fileName, ftp);// 上传到ftp
} else {
status = false;
}
} catch (IOException e) {
LOG.error("FTP连接异常", e);
status = false;
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return status;
}
public static void main(String[] args) {
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect("192.168.33.6");// 连接ftp
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
LOG.error("FTP server refused connection.");
System.exit(1);
}
ftp.login("solrftpuser", "solrftpuser");
System.out.println(ftp.getRemoteAddress());
ftp.changeWorkingDirectory("/query/txt");
FTPFile[] files = ftp.listFiles();
for (FTPFile f : files) {
System.out.println(f.getName());
}
} catch (IOException e) {
LOG.error("FTP连接异常", e);
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}