linux搭建ftp服務器


FTP,即:文件傳輸協議(File Transfer Protocol),基於客戶端/服務器模式,默認使用20、21端口號,其
中端口20(數據端口)用於進行數據傳輸,端口21(命令端口)用於接受客戶端發出的相關FTP命令與參
數。FTP服務器普遍部署於局域網中,具有容易搭建、方便管理的特點。而且有些FTP客戶端工具還可以支
持文件的多點下載以及斷點續傳技術,因此FTP服務得到了廣大用戶的青睞。


FTP協議有以下兩種工作模式:
主動模式(PORT):FTP服務器主動向客戶端發起連接請求。
被動模式(PASV):FTP服務器等待客戶端發起連接請求(FTP的默認工作模式)。
vsftpd是一款運行在Linux操作系統上的FTP服務程序,具有很高的安全性和傳輸速度。


vsftpd有以下三種認證模式:
匿名開放模式:是一種最不安全的認證模式,任何人都可以無需密碼驗證而直接登陸。
本地用戶模式:是通過Linux系統本地的賬戶密碼信息進行認證的模式,相較於匿名開放模式更安全,而且
配置起來簡單。
虛擬用戶模式:是這三種模式中最安全的一種認證模式,它需要為FTP服務單獨建立用戶數據庫文件,虛
擬出用來進行口令驗證的賬戶信息,而這些賬戶信息在服務器系統中實際上是不存在的,僅供FTP服務程
序進行認證使用。

 

下面以虛擬用戶模式配置講解

1.輸入圖中命令,若輸出圖中信息表示已安裝vsftpd,否則輸入命令:yum install -y vsftpd 進行安裝

 

2.安裝完成后

vsftpd缺省安裝在/etc/vsftpd/目錄中,進入該目錄后如下所示

 

1.vsftpd.conf:為核心配置文件

2.user_list:指定允許使用vsftpd 的用戶列表文件,即白名單

3.ftpusers:指定哪些用戶不能訪問FTP服務器,即黑名單

4.如需去掉配置文件里的注釋行輸入以下命令即可

mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
grep -v "#" /etc/vsftpd/vsftpd.conf.bak > /etc/vsftpd/vsftpd.conf

5.vsftpd.conf常用配置參數講解

listen=<YES/NO>  # YES: 服務以獨立運行方式運行; NO: 運行在 xinetd 內。 默認為 YES

listen_address=<ip address> # 服務監聽地址, 如果有多個網卡, 需要將服務綁定到指定 IP 地址

listen_port=<port> # 服務監聽端口, 默認為 21

anonymous_enable=<YES/NO> # 是否允許匿名用戶訪問, 默認 NO

anon_mkdir_write_enable=<YES/NO> # 是否允許匿名用戶創建文件夾, 默認 NO

anon_other_write_enable=<YES/NO> # 是否允許匿名用戶其他的寫權限, 創建文件、重命名、刪除文件等權限 默認為 NO

anon_upload_enable=<YES/NO> # 是否允許匿名用戶上傳, 默認 NO

anon_umask=<nnn> # 匿名用戶上傳的文件的生成掩碼, 默認為077

anon_max_rate=<n> # 匿名用戶的最大傳輸速率, 單位為 Byte/s, 值為 0 表示不限制

anon_world_readable_only=<YES/NO> # 是否允許匿名用戶只讀瀏覽

local_enable=<YES/NO> # 是否支持本地用戶帳號訪問

write_enable=<YES/NO> # 是否開放本地用戶的寫權限

local_umask=<nnn> # 本地用戶上傳的文件的生成掩碼, 默認為077

local_max_rate=<n> # 本地用戶最大的傳輸速率, 單位為 Byte/s,值為0表示不限制

local_root=<file> # 本地用戶登陸后的目錄,默認為本地用戶的主目錄

chroot_local_user=<YES/NO> # 本地用戶是否可以執行 chroot, 默認為 NO

chroot_list_enable=<YES/NO> # 是否只有指定的用戶才能執行 chroot, 默認為 NO

chroot_list_file=<filename> # 當 chroot_local_user=NO 且 chroot_list_enable=YES 時,

                     # 只有 filename 文件內指定的用戶(每行一個用戶名)可以執行 chroot,

                # 默認值為 /etc/vsftpd.chroot_list

userlist_enable=<YES/NO> # 是否啟用 userlist_file 白/黑名單用戶列表, 默認為 NO

userlist_deny=<YES/NO> # 當 userlist_enable=YES(即啟用 userlist_file )時, 則該字段才有效。

userlist_deny=YES: userlist_file 為 黑名單, 即在該文件內的用戶均不可登錄, 其他用戶可以登錄

userlist_deny=NO: userlist_file 為 白名單, 即在該文件內的用戶才可以登錄, 其他用戶均不可登錄

userlist_file=<filename> # 黑/白名單用戶列表文件(每行一個用戶名)

             # 是黑名單還是白名單, 根據 userlist_deny 的值決定

               # 默認值為 /etc/vsftpd.user_list

ftpd_banner=<message> # 客戶端連接服務器后顯示的歡迎信息

connect_timeout=<n> # 遠程客戶端響應端口數據連接超時時間, 單位為秒, 默認 60

accept_connection_timeout=<n> # 空閑的數據連接超時時間, 單位為秒, 默認 120

data_connection_timeout=<n> # 空閑的用戶會話超時時間, 單位為秒, 默認 300

max_clients=<n> # 在獨立模式運行時, 最大連接數, 0 表示無限制

max_per_ip=<n> # 在獨立模式運行時, 每 IP 的最大連接數, 0表示無限制

pasv_min_port=45000 # PASV模式最小端口

pasv_max_port=49999  # PASV模式最大端口

 

3.配置防火牆開放vsftpd命令端口與PASV模式下的端口

firewall-cmd --zone=public --add-port=21/tcp --permanent

firewall-cmd --zone=public --add-port=45000-49000/tcp --permanent

firewall-cmd --reload

 

4.創建用於FTP認證的用戶數據庫文件

vim /etc/vsftpd/vuser.txt

其中奇數行為用戶名,偶數行為密碼

如:

xuyuanyuan

123456

chendanting

123456

明文信息不安全,需要使用db_load命令用哈希(hash)算法將明文信息轉換成數據文件,然后將明文信息文件刪除

db_load -T -t hash -f /etc/vsftpd/vuser.txt /etc/vsftpd/vuser.db
chmod 600 /etc/vsftpd/vuser.db
rm -f /etc/vsftpd/vuser.txt

 

5.創建虛擬用戶映射的系統本地用戶和FTP根目錄

輸入命令:

useradd -d /ftp_data -s /sbin/nologin virtual

chmod -Rf 755 /ftp_data

 

6.建立用於支持虛擬用戶的PAM文件

PAM(可插拔認證模塊)是一種認證機制,通過一些動態鏈接庫和統一的API把系統提供的服務與認證方式分
開,使得系統管理員可以根據需求靈活調整服務程序的不同認證方式。PAM采用了分層設計(應用程序層、
應用接口層、鑒別模塊層)的思想,其結構如下圖所示。

vim /etc/pam.d/vsftpd.vu

添加以下信息
auth         required    pam_userdb.so    db=/etc/vsftpd/vuser
account   required    pam_userdb.so    db=/etc/vsftpd/vuser

 

6.為vuser.txt里的用戶配置相關參數

(1) 創建存放用戶的目錄

mkdir /etc/vsftpd/vusers_dir

(2) 為各用戶創建文件,文件名即為用戶名

vim /etc/vsftpd/vusers_dir/xuyuanyuan

vim /etc/vsftpd/vusers_dir/chendanting

 

(3) 按各用戶需要加入參數配置

local_root=/ftp_data/xuyuanyuan

anon_upload_enable=YES

anon_mkdir_write_enable=YES

anon_other_write_enable=YES

anon_world_readable_only=YES

 

6.修改核心配置文件vsftpd.conf為以下內容

anonymous_enable=NO

local_enable=YES

# 開啟虛擬用戶模式
guest_enable=YES

# 指定虛擬用戶對應的系統用戶
guest_username=virtual

# 允許對ftp根目錄執行寫入操作
allow_writeable_chroot=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connect_from_port_20=YES

xferlog_std_format=YES

listen_port=21

listen=NO

listen_ipv6=YES

#PAM文件

pam_service_name=vsftpd.vu

userlist_enable=YES

tcp_wrappers=YES

# 虛擬用戶配置文件目錄
user_config_dir=/etc/vsftpd/vuser_dir

# 被動模式端口范圍
pasv_min_port=45000

pasv_max_port=49000

chroot_local_user=YES

 

7.最后啟動服務即可訪問

systemctl start vsftpd.serivce 啟動服務

systemctl stop vsftpd.serivce 停止服務

systemctl status vsftpd.serivce 查看服務狀態

systemctl restart vsftpd.serivce 查看服務狀態

在瀏覽器輸入 ftp://ip:21 就可訪問了

 

最后配上操作ftp的工具類

maven依賴

<dependency>
  <groupId>commons-net</groupId>
  <artifactId>commons-net</artifactId>
  <version>3.6</version>
</dependency>

  1 /**
  2  * @author Medusa
  3  * @Date 12-14-19
  4  * @Description ftp工具類
  5  */
  6 public class FtpUtil {
  7 
  8     /**
  9      * ftp服務器的ip
 10      */
 11     private String ip;
 12 
 13     /**
 14      * ftp服務器的端口,缺省為21
 15      */
 16     private int port;
 17 
 18     /**
 19      * 連接ftp服務器的用戶名
 20      */
 21     private String userName;
 22 
 23     /**
 24      * 用戶名對應通行證
 25      */
 26     private String password;
 27 
 28     /**
 29      * 客戶端編碼
 30      */
 31     private String clientCharset = "GBK";
 32 
 33     /**
 34      * 服務端編碼,缺省為ISO8859-1
 35      */
 36     private String serverCharset = "ISO8859-1";
 37 
 38     private FTPClient ftpClient;
 39 
 40     public FtpUtil(String ip, int port, String userName, String password) {
 41         this.ip = ip;
 42         this.port = port;
 43         this.userName = userName;
 44         this.password = password;
 45     }
 46 
 47     /**
 48      * 建立連接並登陸服務器
 49      */
 50     public boolean connectFtp() {
 51         ftpClient = new FTPClient();
 52 
 53         try {
 54             ftpClient.connect(ip, port);
 55 
 56             // 是否連接成功
 57             if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
 58                 System.out.println("create connect fail");
 59                 ftpClient.disconnect();
 60                 return false;
 61             }
 62 
 63             if (!ftpClient.login(userName, password)) {
 64                 System.out.println("login server fail");
 65                 ftpClient.disconnect();
 66                 return false;
 67             }
 68 
 69             // 開啟服務器對UTF-8的支持,如果服務器支持就用UTF-8編碼,否則使用本地編碼
 70             if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
 71                 clientCharset = "UTF-8";
 72             }
 73             ftpClient.setControlEncoding(clientCharset);
 74             ftpClient.enterLocalPassiveMode(); // 設置被動模式
 75             ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 設置文件傳輸類型
 76         } catch (IOException e) {
 77             System.out.println("create connect or close connect error");
 78             return false;
 79         }
 80         return true;
 81     }
 82 
 83     /**
 84      * 退出登陸並關閉連接
 85      */
 86     public boolean closeFtp() {
 87         if (ftpClient != null && ftpClient.isConnected()) {
 88             try {
 89                 ftpClient.logout();
 90                 ftpClient.disconnect();
 91                 return true;
 92             } catch (IOException e) {
 93                 System.out.println("logout or close connect error");
 94                 return false;
 95             }
 96         }
 97         return false;
 98     }
 99 
100     /**
101      * 客戶端轉服務端編碼
102      */
103     private String clientCharsetToServer(String path) {
104         try {
105             return new String(path.getBytes(clientCharset), serverCharset);
106         } catch (UnsupportedEncodingException e) {
107             System.out.println("client to server encode error");
108             return null;
109         }
110     }
111 
112     /**
113      * 服務端轉客戶端編碼
114      */
115     private String serverCharsetToClient(String path) {
116         try {
117             return new String(path.getBytes(serverCharset), clientCharset);
118         } catch (UnsupportedEncodingException e) {
119             System.out.println("server to client encode error");
120             return null;
121         }
122     }
123 
124     /**
125      * 獲取當前工作目錄
126      */
127     private String getWorkDirectory() {
128         try {
129             return serverCharsetToClient(ftpClient.printWorkingDirectory());
130         } catch (IOException e) {
131             System.out.println("get work directory error");
132             return null;
133         }
134     }
135 
136     /**
137      * 獲取當前工作目錄下的所有文件名
138      */
139     private String[] getWorkDirectoryFileNames() {
140         try {
141             FTPFile[] ftpFiles = ftpClient.listFiles();
142             if (ftpFiles.length > 0) {
143                 String[] fileNames = new String[ftpFiles.length];
144                 int i = 0;
145 
146                 for (FTPFile ftpFile: ftpFiles) fileNames[i++] = ftpFile.getName();
147 
148                 return fileNames;
149             }
150             return null;
151         } catch (IOException e) {
152             System.out.println("get work directory files error");
153             return null;
154         }
155     }
156 
157     /**
158      * 根據從根目錄開始的完整文件路徑,切換工作目錄
159      */
160     private boolean changeWorkDirectory(String path) {
161         try {
162             return ftpClient.changeWorkingDirectory(clientCharsetToServer(path));
163         } catch (IOException e) {
164             System.out.println("change directory error");
165             return false;
166         }
167     }
168 
169     /**
170      * 當前工作目錄下是否有查詢的文件
171      */
172     private boolean isWorkDirectoryHasFile(String fileName) {
173         try {
174             FTPFile[] ftpFiles = ftpClient.listFiles();
175 
176             for (FTPFile ftpFile : ftpFiles) {
177                 if (ftpFile.getName().equals(fileName)) return true;
178             }
179 
180             return false;
181         } catch (IOException e) {
182             System.out.println("get work directory files error");
183             return false;
184         }
185     }
186 
187     /**
188      *獲取對應路徑下的文件(根目錄除外),並切換工作目錄至此文件的父目錄
189      */
190     private FTPFile getFTPFile(String path) {
191         if (path.equals("/")) {
192             System.out.println("invalid root directory");
193             return null;
194         }
195 
196         String fileName = path;
197         if (!path.equals("/") && path.indexOf("/") != -1) {
198             String[] split = path.split("/");
199             fileName = split[split.length - 1];
200         }
201         if (changeWorkDirectory(path.substring(0, path.length() - fileName.length()))) {
202             try {
203                 for (FTPFile ftpFile : ftpClient.listFiles()) {
204                     if (ftpFile.getName().equals(fileName)) return ftpFile;
205                 }
206             } catch (IOException e) {
207                 System.out.println("get work directory files error");
208                 return null;
209             }
210         }
211         return null;
212     }
213 
214     /**
215      * 獲取服務端文件夾下所有文件路徑
216      */
217     public List<List<String>> getDirectoryUnderAllFile(String path) throws IOException {
218         // 存放目錄和文件的路徑
219         List<List<String>> directoryAndFilePaths = new ArrayList<>();
220         // 存放目錄的路徑
221         List<String> directoryPaths = new ArrayList<>();
222         // 存放文件的路徑
223         List<String> filePaths = new ArrayList<>();
224         // 待遍歷處理的文件夾路徑
225         Queue<String> ergodicDirPaths = new LinkedList<>();
226         ergodicDirPaths.offer(path);
227         directoryPaths.add(path);
228         
229         while (ergodicDirPaths.size() > 0) {
230             String entry = ergodicDirPaths.poll();
231             if (changeWorkDirectory(entry)) {
232                 entry = "/".endsWith(entry) ? "" : entry;
233                 FTPFile[] ftpFiles = ftpClient.listFiles();
234                 for (FTPFile ftpFile : ftpFiles) {
235                     if (ftpFile.isFile()) {
236                         filePaths.add(entry + "/" + ftpFile.getName());
237                     } else {
238                         directoryPaths.add(entry + "/" + ftpFile.getName());
239                         ergodicDirPaths.offer(entry + "/" + ftpFile.getName());
240                     }
241                 }
242             } else {
243                 System.out.println("切換目錄失敗");
244                 return null;
245             }
246         }
247 
248         directoryAndFilePaths.add(directoryPaths);
249         directoryAndFilePaths.add(filePaths);
250         return directoryAndFilePaths;
251     }
252 
253     /**
254      * 獲取客戶端文件夾下所有文件路徑
255      */
256     public List<List<String>> getDirectoryUnderAllFile1(String path) {
257         // 存放目錄和文件的路徑
258         List<List<String>> directoryAndFilePaths = new ArrayList<>();
259         // 存放目錄的路徑
260         List<String> directoryPaths = new ArrayList<>();
261         // 存放文件的路徑
262         List<String> filePaths = new ArrayList<>();
263         // 待遍歷處理的文件夾路徑
264         Queue<String> ergodicDirPaths = new LinkedList<>();
265         ergodicDirPaths.offer(path);
266         directoryPaths.add(path);
267 
268         while (ergodicDirPaths.size() > 0) {
269             String entry = ergodicDirPaths.poll();
270 
271             File dir = new File(entry);
272             for (File file : dir.listFiles()) {
273                 if (file.isFile()) {
274                     filePaths.add(entry + "/" + file.getName());
275                 } else {
276                     directoryPaths.add(entry + "/" + file.getName());
277                     ergodicDirPaths.offer(entry + "/" + file.getName());
278                 }
279             }
280         }
281 
282         directoryAndFilePaths.add(directoryPaths);
283         directoryAndFilePaths.add(filePaths);
284         return directoryAndFilePaths;
285     }
286 
287     /**
288      * 下載文件,若客戶端已存在則覆蓋它
289      */
290     public boolean download(String serverPath, String clientPath) {
291         // 判斷服務端文件是否存在
292         FTPFile ftpFile = getFTPFile(serverPath);
293         if (ftpFile == null) {
294             System.out.println("server file not exist");
295             return false;
296         }
297 
298         // 若客戶端目錄不存在,就創建它,否則清空目錄
299         File clientDirectory = new File(clientPath);
300         if (!clientDirectory.exists()) {
301             if (!clientDirectory.mkdirs()) {
302                 System.out.println("client create directory fail");
303                 return false;
304             }
305         } else {
306             if (!clientDirectory.isDirectory()) {
307                 System.out.println("clientPath is not directory");
308                 return false;
309             } else {
310                 if (!emptyDirectory(clientDirectory)) {
311                     System.out.println("empty client directory fail");
312                     return false;
313                 }
314             }
315         }
316 
317         if (ftpFile.isFile()) {
318             executeDownload(serverPath, clientPath + serverPath.substring(serverPath.lastIndexOf("/")));
319         } else {
320             try {
321                 List<List<String>> allFile = getDirectoryUnderAllFile(serverPath);
322                 // 獲取所有目錄路徑
323                 List<String> directoryPaths = allFile.get(0);
324                 if (directoryPaths.size() > 0) {
325                     directoryPaths.forEach(path -> new File(clientPath + path).mkdir());
326                 } else {
327                     System.out.println("get all directory fail");
328                     return false;
329                 }
330 
331                 // 獲取所有文件路徑
332                 List<String> filePaths = allFile.get(1);
333                 for (String path : filePaths) {
334                     executeDownload(path, clientPath + path);
335                 }
336             } catch (IOException e) {
337                 System.out.println("error getting all files under this path");
338                 return false;
339             }
340         }
341         return true;
342     }
343 
344     /**
345      * 執行下載文件
346      */
347     private void executeDownload(String serverPath, String clientPath) {
348         InputStream is = null;
349         OutputStream os = null;
350         try {
351             is = ftpClient.retrieveFileStream(clientCharsetToServer(serverPath));
352             File file = new File(clientPath);
353             if (!file.createNewFile()) {
354                 System.out.println("client create file fail");
355                 return;
356             }
357             os = new FileOutputStream(file);
358             byte[] by = new byte[1024];
359             int len = 0;
360             while ((len = is.read(by)) != -1) os.write(by, 0, len);
361         } catch (IOException e) {
362             System.out.println("stream handle file fail");
363             return;
364         } finally {
365             try {
366                 if (is != null) {
367                     is.close();
368                     // 必須調用此方法,否則第二次調用retrieveFileStream()方法時,返回null
369                     ftpClient.completePendingCommand();
370                 }
371                 if (os != null) os.close();
372             } catch (IOException e) {
373                 e.printStackTrace();
374             }
375         }
376     }
377 
378     /**
379      * 執行上傳文件
380      */
381     private void executeUpload(String serverPath, String clientPath) {
382         InputStream is = null;
383         OutputStream os = null;
384         try {
385             is = new FileInputStream(clientPath);
386             os = ftpClient.storeFileStream(clientCharsetToServer(serverPath));
387 
388             byte[] by = new byte[1024];
389             int len = 0;
390             while ((len = is.read(by)) != -1) os.write(by, 0, len);
391         } catch (FileNotFoundException e) {
392             System.out.println("client file not found");
393             return;
394         } catch (IOException e) {
395             System.out.println("stream handle file fail");
396             return;
397         } finally {
398             try {
399                 if (is != null) is.close();
400                 if (os != null) {
401                     os.close();
402                     ftpClient.completePendingCommand();
403                 }
404             } catch (IOException e) {
405                 e.printStackTrace();
406             }
407         }
408     }
409 
410     /**
411      * 上傳文件,若服務端已存在則覆蓋它
412      */
413     public boolean upload(String serverPath, String clientPath) {
414         File clientFile = new File(clientPath);
415         if (!clientFile.exists()) {
416             System.out.println("client file not exist");
417             return false;
418         }
419 
420         if (!"/".equals(serverPath)) {
421             FTPFile ftpFile = getFTPFile(serverPath);
422             if (ftpFile == null) {
423                 String[] split = serverPath.split("/");
424                 changeWorkDirectory("/");
425                 try {
426                     for (int i = 1; i < split.length; i++) {
427                         ftpClient.makeDirectory(clientCharsetToServer(split[i]));
428                         changeWorkDirectory(getWorkDirectory() + "/" + split[i]);
429                     }
430                 } catch (IOException e) {
431                     System.out.println("create server directory error");
432                     return false;
433                 }
434             }
435         }
436 
437         serverPath = "/".endsWith(serverPath) ? "" : serverPath;
438         if (clientFile.isFile()) {
439             try {
440                 String filePath = serverPath + clientPath.substring(clientPath.lastIndexOf("/"));
441                 ftpClient.deleteFile(filePath);
442                 executeUpload(filePath, clientPath);
443             } catch (IOException e) {
444                 System.out.println("delete server file error");
445                 return false;
446             }
447         } else {
448             List<List<String>> allFile = getDirectoryUnderAllFile1(clientPath);
449             List<String> directoryPaths = allFile.get(0);
450             String path2;
451             if (directoryPaths.size() > 0) {
452                 try {
453                     String firstDir = directoryPaths.get(0);
454                     String path1 = firstDir.substring(firstDir.lastIndexOf("/"));
455                     path2 = firstDir.substring(0, firstDir.lastIndexOf("/"));
456                     ftpClient.makeDirectory(clientCharsetToServer(serverPath + path1));
457                     for (int i = 1; i < directoryPaths.size(); i++) {
458                         String tempPath = directoryPaths.get(i).substring(path2.length());
459                         ftpClient.makeDirectory(clientCharsetToServer(serverPath + tempPath));
460                     }
461                 } catch (IOException e) {
462                     System.out.println("create server directory error");
463                     return false;
464                 }
465             } else {
466                 System.out.println("get all directory fail");
467                 return false;
468             }
469             List<String> filePaths = allFile.get(1);
470             for (String path : filePaths) {
471                 String tempPath = path.substring(path2.length());
472                 executeUpload(serverPath + tempPath, path);
473             }
474         }
475         return true;
476     }
477 
478     /**
479      * 清空目錄
480      */
481     private boolean emptyDirectory(File dir) {
482         File[] oneLevelFile = dir.listFiles();
483         if (oneLevelFile.length > 0) {
484             Stack<File> willDeleteFile = new Stack<>();
485             for (int i = 0; i < oneLevelFile.length; i++) {
486                 willDeleteFile.push(oneLevelFile[i]);
487             }
488 
489             while (willDeleteFile.size() > 0) {
490                 File entry = willDeleteFile.pop();
491                 if (entry.isFile()) {
492                     if (!entry.delete()) return false;
493                 } else {
494                     File[] lowerLevelFile = entry.listFiles();
495                     if (lowerLevelFile.length > 0) {
496                         willDeleteFile.push(entry);
497                         for (int i = 0; i < lowerLevelFile.length; i++) {
498                             willDeleteFile.push(lowerLevelFile[i]);
499                         }
500                     } else {
501                         if (!entry.delete()) return false;
502                     }
503                 }
504             }
505         }
506         return true;
507     }
508 
509     /**
510      * web端上傳
511      */
512     public boolean webUpload(MultipartFile file, String serverPath) {
513         if (!"/".equals(serverPath)) {
514             FTPFile ftpFile = getFTPFile(serverPath);
515             if (ftpFile == null) {
516                 String[] split = serverPath.split("/");
517                 changeWorkDirectory("/");
518                 try {
519                     for (int i = 1; i < split.length; i++) {
520                         ftpClient.makeDirectory(clientCharsetToServer(split[i]));
521                         changeWorkDirectory(getWorkDirectory() + "/" + split[i]);
522                     }
523                 } catch (IOException e) {
524                     System.out.println("create server directory error");
525                     return false;
526                 }
527             }
528         }
529         String filePath;
530         try {
531             serverPath = "/".endsWith(serverPath) ? "" : serverPath;
532             filePath = serverPath + "/" + file.getOriginalFilename();
533             ftpClient.deleteFile(filePath);
534         } catch (IOException e) {
535             System.out.println("delete server file error");
536             return false;
537         }
538 
539         InputStream is = null;
540         OutputStream os = null;
541         try {
542             is = file.getInputStream();
543             os = ftpClient.storeFileStream(clientCharsetToServer(filePath));
544 
545             byte[] by = new byte[1024];
546             int len = 0;
547             while ((len = is.read(by)) != -1) os.write(by, 0, len);
548         } catch (FileNotFoundException e) {
549             System.out.println("client file not found");
550             return false;
551         } catch (IOException e) {
552             System.out.println("stream handle file fail");
553             return false;
554         } finally {
555             try {
556                 if (is != null) is.close();
557                 if (os != null) {
558                     os.close();
559                     ftpClient.completePendingCommand();
560                 }
561             } catch (IOException e) {
562                 e.printStackTrace();
563             }
564         }
565         return true;
566     }
567 
568     /**
569      * web端下載
570      */
571     public boolean webDownload(HttpServletResponse response, String serverPath) {
572         FTPFile ftpFile = getFTPFile(serverPath);
573         if (ftpFile == null) {
574             System.out.println("server file not exist");
575             return false;
576         }
577 
578         InputStream is = null;
579         try {
580             is = ftpClient.retrieveFileStream(clientCharsetToServer(serverPath));
581             ServletOutputStream sos = response.getOutputStream();
582             byte[] by = new byte[1024];
583             int len = 0;
584             while ((len = is.read(by)) != -1) sos.write(by, 0, len);
585         } catch (IOException e) {
586             System.out.println("stream handle file fail");
587             return false;
588         } finally {
589             try {
590                 if (is != null) {
591                     is.close();
592                     ftpClient.completePendingCommand();
593                 }
594             } catch (IOException e) {
595                 e.printStackTrace();
596             }
597         }
598 
599         return true;
600     }
601 
602 }
View Code


免責聲明!

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



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