这段代码是一个Java类,名为FtpUtils
,用于实现FTP文件上传和下载的功能。以下是代码的主要组成部分和功能的简要说明:
-
类变量定义:
ip
、username
、password
:FTP服务器的IP地址、用户名和密码。port
:FTP服务器的端口号,默认为-1,表示使用FTP默认端口(21)。path
:FTP服务器上的路径。ftpClient
:用于FTP操作的客户端对象。os
、is
:输出和输入流,用于文件传输。
-
构造函数:
- 两个构造函数,一个用于指定FTP服务器的IP、端口、用户名和密码,另一个只指定IP、用户名和密码。
-
连接和断开连接:
connectServer()
:连接到FTP服务器。closeServer()
:断开与FTP服务器的连接。
-
目录操作:
isDirExist(String dir)
:检查指定目录是否存在。createDir(String dir)
:在FTP服务器上创建目录。
-
文件上传:
upload(String filename)
:上传文件或文件夹到FTP服务器。upload(String fileName, String newName)
:上传文件或文件夹,并可以指定在服务器上的新名称。uploadFile(String filename, String newname)
:实际执行上传操作的方法。
-
文件下载:
downloadFile(String realfileName, String excelFilePath)
:从FTP服务器下载文件到本地。downloadFileForPage(OutputStream os, String filename)
:从FTP服务器下载文件,并通过输出流返回,通常用于直接在网页上显示文件内容。
-
辅助方法:
upload(String fileName, String newName, String path)
:递归上传文件夹和文件。
代码中使用了sun.net
包中的FtpClient
、TelnetInputStream
和TelnetOutputStream
类,这些类不是Java标准库的一部分,而是Sun公司提供的扩展库。在实际使用中,可能需要替换为更通用的FTP库,如Apache Commons Net。
此外,代码中存在一些潜在的问题,例如:
- 使用了硬编码的字符集转换,这可能在不同环境中导致问题。
- 异常处理主要是打印堆栈跟踪,没有进行适当的错误处理或恢复。
- 代码中的注释是中文的,对于非中文环境可能需要翻译。
整体而言,这段代码提供了基本的FTP文件操作功能,但在实际应用中可能需要进一步的改进和错误处理。
package com.starit.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.StringTokenizer;
import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;
/**
* ftp上传,下载
*
*/
public class FtpUtils {
private String ip = "";
private String username = "";
private String password = "";
private int port = -1;
private String path = "";
public FtpClient ftpClient = null;
OutputStream os = null;
FileInputStream is = null;
public FtpUtils(String serverIP, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
}
public FtpUtils(String serverIP, int port, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
this.port = port;
}
/**
* 连接ftp服务器
*
* @throws IOException
*/
public boolean connectServer(){
ftpClient = new FtpClient();
try {
if(this.port != -1){
ftpClient.openServer(this.ip,this.port);
}else{
ftpClient.openServer(this.ip);
}
ftpClient.login(this.username, this.password);
if (this.path.length() != 0){
ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
}
ftpClient.binary();// 用2进制上传、下载
System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
return true;
}catch (IOException e){
e.printStackTrace();
return false;
}
}
/**
* 断开与ftp服务器连接
*
* @throws IOException
*/
public boolean closeServer(){
try{
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
if (ftpClient != null) {
ftpClient.closeServer();
}
System.out.println("已从服务器断开");
return true;
}catch(IOException e){
e.printStackTrace();
return false;
}
}
/**
* 检查文件夹在当前目录下是否存在
* @param dir
* @return
*/
private boolean isDirExist(String dir){
String pwd = "";
try {
pwd = ftpClient.pwd();
ftpClient.cd(dir);
ftpClient.cd(pwd);
}catch(Exception e){
return false;
}
return true;
}
/**
* 在当前目录下创建文件夹
* @param dir
* @return
* @throws Exception
*/
private boolean createDir(String dir){
try{
ftpClient.ascii();
StringTokenizer s = new StringTokenizer(dir, "/"); //sign
s.countTokens();
String pathName = ftpClient.pwd();
while(s.hasMoreElements()){
pathName = pathName + "/" + (String) s.nextElement();
try {
ftpClient.sendServer("MKD " + pathName + "\r\n");
} catch (Exception e) {
e = null;
return false;
}
ftpClient.readServerResponse();
}
ftpClient.binary();
return true;
}catch (IOException e1){
e1.printStackTrace();
return false;
}
}
/**
* ftp上传
* 如果服务器段已存在名为filename的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
*
* @param filename 要上传的文件(或文件夹)名
* @return
* @throws Exception
*/
public boolean upload(String filename){
String newname = "";
if(filename.indexOf("/") > -1){
newname = filename.substring(filename.lastIndexOf("/") + 1);
}else{
newname = filename;
}
return upload(filename, newname);
}
/**
* ftp上传
* 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
*
* @param fileName 要上传的文件(或文件夹)名
* @param newName 服务器段要生成的文件(或文件夹)名
* @return
*/
public boolean upload(String fileName, String newName){
try{
String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
File file_in = new File(savefilename);//打开本地待长传的文件
String path=file_in.getPath();
System.out.println("pwd="+ftpClient.pwd());
System.out.println("path="+path);
if(!file_in.exists()){
throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
}
if(file_in.isDirectory()){
upload(path,newName,ftpClient.pwd());
}else{
uploadFile(path,newName);
}
if(is != null){
is.close();
}
if(os != null){
os.close();
}
return true;
}catch(Exception e){
e.printStackTrace();
System.err.println("Exception e in Ftp upload(): " + e.toString());
return false;
}finally{
try{
if(is != null){
is.close();
}
if(os != null){
os.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
/**
* 真正用于上传的方法
* @param fileName
* @param newName
* @param path
* @throws Exception
*/
private void upload(String fileName, String newName,String path) throws Exception{
String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
File file_in = new File(savefilename);//打开本地待长传的文件
if(!file_in.exists()){
throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
}
if(file_in.isDirectory()){
if(!isDirExist(newName)){
createDir(newName);
}
ftpClient.cd(newName);
File sourceFile[] = file_in.listFiles();
for(int i = 0; i < sourceFile.length; i++){
if(!sourceFile[i].exists()){
continue;
}
if(sourceFile[i].isDirectory()){
this.upload(sourceFile[i].getPath(),sourceFile[i].getName(),path+"/"+newName);
}else{
this.uploadFile(sourceFile[i].getPath(),sourceFile[i].getName());
}
}
}else{
uploadFile(file_in.getPath(),newName);
}
ftpClient.cd(path);
}
/**
* upload 上传文件
*
* @param filename 要上传的文件名
* @param newname 上传后的新文件名
* @return -1 文件不存在 >=0 成功上传,返回文件的大小
* @throws Exception
*/
public long uploadFile(String filename, String newname) throws Exception{
long result = 0;
TelnetOutputStream os = null;
FileInputStream is = null;
try {
java.io.File file_in = new java.io.File(filename);
if(!file_in.exists())
return -1;
os = ftpClient.put(newname);
result = file_in.length();
is = new FileInputStream(file_in);
byte[] bytes = new byte[1024];
int c;
while((c = is.read(bytes)) != -1){
os.write(bytes, 0, c);
}
}finally{
if(is != null){
is.close();
}
if(os != null){
os.close();
}
}
return result;
}
/**
* 从ftp下载文件到本地
*
* @param filename 服务器上的文件名
* @param newfilename 本地生成的文件名
* @return
* @throws Exception
*/
public long downloadFile(String realfileName, String excelFilePath){
long result = 0;
TelnetInputStream is = null;
FileOutputStream os = null;
try{
is = ftpClient.get(realfileName);
java.io.File outfile = new java.io.File(excelFilePath);
os = new FileOutputStream(outfile);
byte[] bytes = new byte[1024];
int c;
while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
result = result + c;
}
}catch (IOException e){
e.printStackTrace();
}finally{
try {
if(is != null){
is.close();
}
if(os != null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 从ftp下载文件,通过流输出到页面
* @param filename 服务器上的文件名
* @param newfilename 本地生成的文件名
* @return
* @throws Exception
*/
public long downloadFileForPage(OutputStream os,String filename){
long result = 0;
TelnetInputStream is = null;
try{
is = ftpClient.get(filename);
byte[] bytes = new byte[1024];
int c;
while ((c = is.read(bytes)) != -1) {
os.write(bytes, 0, c);
result = result + c;
}
}catch (IOException e){
e.printStackTrace();
}finally{
try {
if(is != null){
is.close();
}
if(os != null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}