Java操作FTP


使用IIS方式搭建FTP

Windows下使用FileZilla搭建FTP

1、與FTP服務器建立連接

/**
 * 初始化客戶端並完成對服務端的連接
 * @param server 服務端地址
 * @param port 端口號
 * @param username 用戶名
 * @param password 密碼
 * @param path 遠程路徑 值可以為空
 * @throws SocketException
 * @throws IOException
 */
public static FTPClient connectServer(String server, int port, String username,String password, String path)  {
	if(null == path){
		path = "";
	}
	try {
		FTPClient ftp = new FTPClient();
		//下面四行代碼必須要,而且不能改變編碼格式,否則不能正確下載中文文件
		// 如果使用serv-u發布ftp站點,則需要勾掉“高級選項”中的“對所有已收發的路徑和文件名使用UTF-8編碼”
		ftp.setControlEncoding("GBK");
		FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
		conf.setServerLanguageCode("zh");
		ftp.configure(conf);
		
		ftp.connect(server, port);
		ftp.setDataTimeout(120000);

		// 判斷ftp是否存在
		if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {	
			ftp.disconnect();	// 如果不存在,斷開ftp連接
			log.warn(server + "  FTP拒絕連接");
		}
		// 登陸ftp
		boolean flag = ftp.login(username, password);
		if (flag) {
			log.info("FTP登錄成功。");
		}else {
			log.error("FTP登錄失敗。");
		}
		
		// 根據輸入的路徑,切換工作目錄。這樣ftp端的路徑就可以使用相對路徑了
		if (path.length() != 0) {
			if (path != null && !"".equals(path.trim())) {
				// 對路徑按照‘/’進行切割,一層一層的進入
				String[] pathes = path.split("/");
				for (String onepath : pathes) {
					if (onepath == null || "".equals(onepath.trim())) {
						continue;
					}               
					if (!ftp.changeWorkingDirectory(onepath)) {
						ftp.makeDirectory(onepath);
						boolean flagDir = ftp.changeWorkingDirectory(onepath);
						log.info(ftp.printWorkingDirectory());
						if (flagDir) {
							log.info("成功連接ftp目錄:" + ftp.printWorkingDirectory());
						} else {
							log.error("未能連接ftp目錄:" + ftp.printWorkingDirectory());
						}
					}
				}
			}
		}
		return ftp;
	}catch(SocketException e){
		e.printStackTrace();
		return null;
	}
	catch (IOException e) {
		e.printStackTrace();
		return null;
	}
}

2、返回目錄下的所有文件(包括文件夾)

/**
 * 返回給定目錄下的所有文件(包括文件夾)
 * @param path
 * @return FTPFile組成的集合
 * @throws IOException
 */
public static List<String> getFileList(FTPClient ftp,String path) throws IOException {
	
	ftp.changeWorkingDirectory(path);//切換對應路徑下
	log.info("FTP當前目錄:"+ftp.printWorkingDirectory());
	FTPFile[] ftpFiles = ftp.listFiles();    // ftpFiles.length返回當前目錄下的文件數
	List retList = new ArrayList();
	if (ftpFiles == null || ftpFiles.length == 0) {
		return retList;
	}
	for (int i = 0; i < ftpFiles.length; i++) {
		FTPFile ftpFile = ftpFiles[i];
//		if (ftpFile.isFile()) {	// 判斷是否為文件,這樣返回的就是所有的文件名
//			retList.add(ftpFile.getName());
//		}
		retList.add(ftpFile.getName());
	}
	return retList;
}

3、獲取指定路徑下的所有文件(不管多少文件夾下)

/**
 * 遞歸遍歷文件夾以及子文件夾的文件
 * 獲取指定路徑下的所有文件(不管多少文件夾下)
 * @param pathName 
 * @param filePathList
 * @throws IOException
 */
public static void getFileListRecursion(FTPClient ftp,String pathName, List<String> filePathList) throws IOException {
	
	if(null == pathName){
		pathName = "/";
	}else{
		pathName = pathName.replace("\\", "/");
	}
	if(!pathName.startsWith("/")){
		pathName ="/"+pathName;
	}
	if(!pathName.endsWith("/")){
		pathName = pathName + "/";
	}
	
	ftp.changeWorkingDirectory(pathName);
	FTPFile[] files = ftp.listFiles();
	for (int i = 0; i < files.length; i++) {
		if (files[i].isFile()) {
			log.info("得到文件:" + files[i].getName());
			log.info("--------------");
			filePathList.add(ftp.printWorkingDirectory()+"/"+files[i].getName());
		} else if (files[i].isDirectory()) {
			getFileListRecursion(ftp,pathName + files[i].getName() + "/", filePathList);
		}
	}
}

4、刪除指定目錄(遞歸)

/**
 * 刪除指定目錄下的所有文件
 * @param ftp
 * @param pathname
 * @return
 */
public static boolean removeAll(FTPClient ftp, String pathname) {
	try {
		ftp.removeDirectory(pathname);
		FTPFile[] files = ftp.listFiles(pathname);
		for (FTPFile f : files) {
			if (f.isDirectory()) {
				removeAll(ftp,pathname + "/" + f.getName());
				boolean isDelDir = ftp.removeDirectory(pathname);
				log.info("FTP目錄是否已刪除>>"+isDelDir);
			}
			if (f.isFile()) {
				boolean isDelFile = ftp.deleteFile(pathname + "/" + f.getName());
				ftp.removeDirectory(pathname);
				log.info("FTP文件是否已刪除>>"+isDelFile);
			}
		}
	} catch (IOException e) {
		e.printStackTrace();
		return false;
	}
	return true;
}

5、上傳文件,並重命名

/**
 * 上傳文件,並重命名.
 * @param filePathName 上傳的文件,包含目錄的文件名
 * @param newName 新的文件名
 * @return 上傳結果,是否成功.
 * @throws IOException
 */
public static boolean uploadFile(FTPClient ftp,String filePathName, String newName)
		throws IOException {
	boolean flag = false;
	InputStream iStream = null;
	try {
		log.info("ftp new file name : "+newName);
		ftp.setControlEncoding("GBK");
		iStream = new FileInputStream(filePathName);
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);  
		//將當前數據連接模式設置為PASSIVE_LOCAL_DATA_CONNECTION_MODE,即:被動模式
		ftp.enterLocalPassiveMode();
		//將流寫到服務器
		ftp.storeFile(new String(filePathName.getBytes("GBK"),"iso-8859-1"),iStream);
		flag = ftp.storeFile(newName, iStream);
	} catch (IOException e) {
		flag = false;
		return flag;
	} finally {
		if (iStream != null) {
			iStream.close();
		}
	}
	return flag;
}

6、從ftp上下載文件到本地

/**
 * 從ftp上下載文件到本地
 * @param ftpClient:ftp連接
 * @param remoteFilepath:ftp服務器端路徑
 * @param localFilePath:本地路徑
 * @return 是否下載成功
 */
public static boolean downloadFileFromFtp(FTPClient ftpClient,String remoteFilepath,String localFilePath){
	
	boolean flag = false;
	try {
		//判斷本地文件是否已經存在,如果已經存在,則無需下載
		//FTPClient ftpClient = FtpUtil.connectServer(ftp);
		File localFile = new File(localFilePath);
		if (!localFile.exists()) {
			InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath);
			if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath);
		}else {
			if (localFile.length() == 0) {
				log.info("文件大小為0,即將為您重新下載!");
				localFile.delete();
				InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath);
				if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath);	// 將文件流轉化為本地文件
			}else{
				log.info("本地文件已存在.......");
				flag = true;
			}
		}
		FtpUtil.closeServer(ftpClient);
		return flag;
	} catch (Exception e) {
		flag = false;
		log.error("從FTP下載文件到本地失敗...");
		log.error(e);
		e.printStackTrace();
		return flag;
	}
}
	
/**
 * 將文件流轉化為本地文件
 * @param inputStream
 * @param localFilePath
 * @return boolean
 * @throws IOException 
 */
public static boolean inputStreamToFile(InputStream inputStream,String localFilePath) throws IOException {
	File newDir = new File(localFilePath.replace("\\", "/").substring(0, localFilePath.lastIndexOf("\\")));
	if (!newDir.exists()) newDir.mkdirs();
	FileOutputStream fs= new FileOutputStream(localFilePath);
	try {
		/*FileChannel fc= ((FileInputStream) inputStream).getChannel();  
		log.info("文件大小:"+fc.size());*/
		int bytesum = 0;
		int byteread = 0;
		
		byte[] buffer = new byte[1024];
		long startTime = System.currentTimeMillis();
		while ((byteread = inputStream.read(buffer)) != -1) {
			bytesum += byteread; // 字節數 文件大小
			fs.write(buffer, 0, byteread);
		}
		fs.flush();
		long endTime = System.currentTimeMillis();
		log.info("將文件流轉化為本地文件耗時/毫秒:"+(endTime-startTime));
		return true;
	} catch (Exception e) {
		log.error("將文件流轉化為本地文件失敗",e);
		return false;
	}finally{
		fs.close();
	}
}

7、獲取下一級目錄列表 文件+文件夾(返回list<PathVo>)

/**
 * 獲取下一級目錄列表 文件+文件夾(返回list<PathVo>)
 * @param ftp
 * @param pathName
 * @return
 * @throws IOException
 */
public static List<PathVo> getNextDirectory(FTPClient ftp,String pathName) throws IOException {
	log.info("Ftp中pathName:"+pathName);
	List<PathVo> filePathList = new ArrayList<PathVo>();
	if(null == pathName) pathName = "/";
	else pathName = pathName.replace("\\", "/");
	if(!pathName.startsWith("/")) pathName ="/"+pathName;
	if(!pathName.endsWith("/")) pathName = pathName + "/";
	
	boolean flag = ftp.changeWorkingDirectory(pathName);
	if (!flag) {
		log.info("重定位失敗。");
		return filePathList;
	}
	log.info("目錄切換"+ftp.printWorkingDirectory());
	//ftp.enterLocalActiveMode();//主動模式,默認
	ftp.enterLocalPassiveMode();//被動模式
	//ftp.configure(new FTPClientConfig("dist.dgp.util.fileZillaPlugin.UnixFTPEntryParser"));//FileZilla安裝FTP時使用
	String[] list = ftp.listNames();
	System.out.println(list.length);
	FTPFile[] files = ftp.listFiles();
	if (files == null || files.length == 0) {
		ftp.changeToParentDirectory();
		return filePathList;
	}
	log.info("文件長度:"+files.length);
	for (int i = 0; i < files.length; i++) {
		PathVo vo = new PathVo();
		if (files[i].isFile()) {
			vo.setType("file");
			vo.setFullPath(pathName+files[i].getName());
			vo.setSize(formatSize(files[i].getSize()));
			vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis()));
			vo.setLabel(files[i].getName());
			vo.setExtension(files[i].getName().substring(files[i].getName().lastIndexOf(".")+1));
			vo.setChildren(null);
			filePathList.add(vo);
			
		} else if (files[i].isDirectory()) {
			vo.setType("folder");
			vo.setFullPath(pathName+files[i].getName());
			vo.setLabel(files[i].getName());
			vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis()));
			vo.setChildren(getNextDirectory(ftp,pathName + files[i].getName() + "/"));
			filePathList.add(vo);
		}
	}
	log.info("filePathList.size():"+filePathList.size());
	return filePathList;
}

8、獲取文件最后編輯時間

/**
 * 獲取文件最后編輯時間
 * @param filename
 * @return
 */
public static String getFileLastModified(long timeInMillis) {
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
	Calendar cal = Calendar.getInstance();
	cal.setTimeInMillis(timeInMillis);
	return sdf.format(cal.getTime());
}

9、其他

FTPClient ftp = new FTPClient();

ftp.logout();	// 關閉ftp連接

ftp.setFileType(fileType);	// 設置ftp的文件傳輸類型

ftp.changeWorkingDirectory(path);	// 改變ftp的工作目錄

ftp.removeDirectory(path);	// 刪除一個FTP服務器上的目錄(如果為空)

ftp.deleteFile(pathName);	// 刪除文件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM