本文為大家分享了FTP上傳下載管理模塊的實現方法,供大家參考,具體內容如下
1、上傳本地文件或文件夾到遠程FTP服務器端的功能。
當用戶在本地文件列表中選擇想要上傳的文件后,點擊上傳按鈕,將本機上指定的文件上傳到FTP服務器當前展現的目錄,下圖為上傳子模塊流程圖
選擇好要上傳的文件或文件夾,點擊“上傳”按鈕,會觸發com.oyp.ftp.panel.local.UploadAction類的actionPerformed(ActionEvent e)方法,其主要代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/** * 上傳文件動作的事件處理方法 */ public void actionPerformed(java.awt.event.ActionEvent evt) { // 獲取用戶選擇的多個文件或文件夾 int [] selRows = this .localPanel.localDiskTable.getSelectedRows(); if (selRows.length < 1 ) { JOptionPane.showMessageDialog( this .localPanel, "請選擇上傳的文件或文件夾" ); return ; } // 獲取FTP服務器的當前路徑 String pwd = this .localPanel.frame.getFtpPanel().getPwd(); // 創建FTP當前路徑的文件夾對象 FtpFile ftpFile = new FtpFile( "" , pwd, true ); // 遍歷本地資源的表格 for ( int i = 0 ; i < selRows.length; i++) { Object valueAt = this .localPanel.localDiskTable.getValueAt( selRows[i], 0 ); // 獲取表格選擇行的第一列數據 if (valueAt instanceof DiskFile) { final DiskFile file = (DiskFile) valueAt; // 獲取本地面板類中的隊列,該隊列是LinkedList類的實例對象 Queue<Object[]> queue = this .localPanel.queue; queue.offer( new Object[] { file, ftpFile }); // 執行offer方法向隊列尾添加對象 } } } |
在com.oyp.ftp.panel.local.UploadThread線程類的run()方法,會判斷上傳隊列是否有對象,如果有則調用其copyFile(File file, FtpFile ftpFile)方法實現上傳文件的功能,上傳完后刷新遠程FTP文件管理的面板。其run()方法主要代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
* 線程的主體方法 */ public void run() { // 線程的主體方法 while (conRun) { try { Thread.sleep( 1000 ); // 線程休眠1秒 Queue<Object[]> queue = localPanel.queue; // 獲取本地面板的隊列對象 queueValues = queue.peek(); // 獲取隊列首的對象 if (queueValues == null ) { // 如果該對象為空 continue ; // 進行下一次循環 } File file = (File) queueValues[ 0 ]; // 獲取隊列中的本隊文件對象 FtpFile ftpFile = (FtpFile) queueValues[ 1 ]; // 獲取隊列中的FTP文件對象 if (file != null ) { selPath = file.getParent(); copyFile(file, ftpFile); // 調用遞歸方法上傳文件 FtpPanel ftpPanel = localPanel.frame.getFtpPanel(); ftpPanel.refreshCurrentFolder(); // 刷新FTP面板中的資源 } Object[] args = queue.peek(); // 判斷隊列頂是否為處理的上一個任務。 if (queueValues == null || args == null || !queueValues[ 0 ].equals(args[ 0 ])) { continue ; } queue.remove(); // 移除隊列首元素 } catch (Exception e) { e.printStackTrace(); } } } |
其中調用的copyFile(File file, FtpFile ftpFile)方法代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/** * 上傳線程的遞歸方法,上傳文件夾的所有子文件夾和內容 * @param file * - FTP文件對象 * @param localFolder * - 本地文件夾對象 */ private void copyFile(File file, FtpFile ftpFile) { // 遞歸遍歷文件夾的方法 // 判斷隊列面板是否執行暫停命令 while (localPanel.frame.getQueuePanel().isStop()) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { e.printStackTrace(); } } Object[] args = localPanel.queue.peek(); // 判斷隊列頂是不是上一個處理的任務。 if (queueValues == null || args == null || !queueValues[ 0 ].equals(args[ 0 ])) return ; try { // System.out.println("selPath:"+selPath); path = file.getParentFile().getPath().replace(selPath, "" ); // System.out.println("path:"+path); ftpFile.setName(path.replace( "\\" , "/" )); path = ftpFile.getAbsolutePath(); // System.out.println("ftpFile.getAbsolutePath():"+path); if (file.isFile()) { UploadPanel uploadPanel = localPanel.frame.getUploadPanel(); //上傳面板 String remoteFile = path + "/" + file.getName(); // 遠程FTP的文件名絕對路徑 // System.out.println("remoteFile:" + remoteFile); double fileLength = file.length() / Math.pow( 1024 , 2 ); ProgressArg progressArg = new ProgressArg( ( int ) (file.length() / 1024 ), 0 , 0 ); //進度參數 String size = String.format( "%.4f MB" , fileLength); Object[] row = new Object[] { file.getAbsoluteFile(), size, remoteFile, ftpClient.getServer(), progressArg }; uploadPanel.addRow(row); //添加列 OutputStream put = ftpClient.put(remoteFile); // 獲取服務器文件的輸出流 FileInputStream fis = null ; // 本地文件的輸入流 try { fis = new FileInputStream(file); // 初始化文件的輸入流 } catch (Exception e) { e.printStackTrace(); return ; } int readNum = 0 ; byte [] data = new byte [ 1024 ]; // 緩存大小 while ((readNum = fis.read(data)) > 0 ) { // 讀取本地文件到緩存 Thread.sleep( 0 , 30 ); // 線程休眠 put.write(data, 0 , readNum); // 輸出到服務器 progressArg.setValue(progressArg.getValue() + 1 ); // 累加進度條 } progressArg.setValue(progressArg.getMax()); // 結束進度條 fis.close(); // 關閉文件輸入流 put.close(); // 關閉服務器輸出流 } else if (file.isDirectory()) { path = file.getPath().replace(selPath, "" ); ftpFile.setName(path.replace( "\\" , "/" )); // System.out.println("Dirpath:"+path); /**將目錄切換到當前FTP服務器的當前目錄*/ ftpClient.cd( this .localPanel.frame.getFtpPanel().getPwd()); // /media目錄 /** * 如果有創建文件夾的權限,則在當前FTP服務器的當前目錄下創建文件夾 * 必須要有創建文件夾的權限,否則會報錯 * path:audio ftpFile.getAbsolutePath():/media/audio remoteFile:/media/audio/梁靜茹-會呼吸的痛Live.mp3 */ ftpClient.sendServer( "MKD " + path + "\r\n" ); //創建 /media/audio 目錄 ftpClient.readServerResponse(); /*********************************************************** * 如果沒有有創建文件夾的權限,則創建文件夾,因此FTP服務器的當前路徑下不存在 * 那么將文件上傳到此FTP服務器的當前路徑下 * * 如要上傳C://audio目錄(目錄中有 梁靜茹-會呼吸的痛Live.mp3 和 林宥嘉-心酸.mp3 兩個文件) * 到 FTP服務器上的 /media/ 目錄下 * 因為FTP服務器上沒有 /media/audio 目錄,并且FTP服務器當前的目錄為 /media * 所以將 C://audio目錄下的文件上傳到了 /media目錄下 * ftpFile.getAbsolutePath():/media/audio remoteFile:/media/梁靜茹-會呼吸的痛Live.mp3 remoteFile:/media/林宥嘉-心酸.mp3 */ //創建一個文件夾對象,檢查該文件是否存在 File fileRemote= new File( this .localPanel.frame.getFtpPanel().getPwd()+path); //path:audio //該目錄不存在 if (!fileRemote.exists()) { path= this .localPanel.frame.getFtpPanel().getPwd(); } /***********************************************************/ File[] listFiles = file.listFiles(); for (File subFile : listFiles) { Thread.sleep( 0 , 50 ); copyFile(subFile, ftpFile); } } } catch (FileNotFoundException e1) { e1.printStackTrace(); System.exit( 0 ); // JOptionPane.showMessageDialog(localPanel, e1.getMessage()); } catch (Exception ex) { ex.printStackTrace(); } } |
2、下載遠程FTP服務器端的文件或文件夾到本地
當用戶在遠程FTP服務器文件列表中選擇想要下載的文件后,點擊下載按鈕,將服務器上的文件下載至本機,下圖為下載子模塊流程圖。
選擇好要下載的文件或文件夾,點擊“下載”按鈕,會觸發com.oyp.ftp.panel.ftp.DownAction類的actionPerformed(ActionEvent e)方法,其主要代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * 下載按鈕的動作處理器動作的事件處理方法 */ @Override public void actionPerformed(ActionEvent e) { // 獲取FTP資源表格的所有選擇行 final int [] selRows = ftpPanel.ftpDiskTable.getSelectedRows(); if (selRows.length < 1 ) return ; // 遍歷表格的所有選擇行 for ( int i = 0 ; i < selRows.length; i++) { // 獲取每行的第一個單元值并轉換成FtpFile類的對象 final FtpFile file = (FtpFile) ftpPanel.ftpDiskTable.getValueAt( selRows[i], 0 ); if (file != null ) { // 獲取本地資源管理面板的當前文件夾 File currentFolder = ftpPanel.frame.getLocalPanel() .getCurrentFolder(); // 把FTP文件對象和本地當前文件夾對象定義成數組添加到下載隊列中 ftpPanel.queue.offer( new Object[] { file, currentFolder }); } } } |
在com.oyp.ftp.panel.ftp.DownThread線程類的run()方法,會判斷下載隊列是否有對象,如果有則調用其downFile(FtpFile file, File localFolder)方法實現上傳文件的功能,上傳完后刷新遠程FTP文件管理的面板。其run()方法代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public void run() { // 線程業務方法 while (conRun) { try { Thread.sleep( 1000 ); ftpClient.noop(); queueValues = ftpPanel.queue.peek(); if (queueValues == null ) { continue ; } FtpFile file = (FtpFile) queueValues[ 0 ]; File localFolder = (File) queueValues[ 1 ]; if (file != null ) { path = file.getPath(); ftpClient.cd(path); downFile(file, localFolder); path = null ; ftpPanel.frame.getLocalPanel().refreshCurrentFolder(); } Object[] args = ftpPanel.queue.peek(); // 判斷隊列頂是否為處理的上一個任務。 if (queueValues == null || args == null || !queueValues[ 0 ].equals(args[ 0 ])) continue ; ftpPanel.queue.poll(); } catch (Exception e) { e.printStackTrace(); } } } |
其中調用的downFile(FtpFile file, File localFolder)方法代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
/** * 下載線程的遞歸方法,用戶探索FTP下載文件夾的所有子文件夾和內容 * @param file FTP文件對象 * @param localFolder 本地文件夾對象 */ private void downFile(FtpFile file, File localFolder) { // 判斷隊列面板是否執行暫停命令 while (ftpPanel.frame.getQueuePanel().isStop()) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { e.printStackTrace(); } } Object[] args = ftpPanel.queue.peek(); // 判斷隊列頂是否為處理的上一個任務。 if (queueValues == null || args == null || !queueValues[ 0 ].equals(args[ 0 ])) return ; try { String ftpFileStr = file.getAbsolutePath().replaceFirst(path + "/" , "" ); if (file.isFile()) { // 獲取服務器指定文件的輸入流 TelnetInputStream ftpIs = ftpClient.get(file.getName()); if (ftpIs == null ) { JOptionPane.showMessageDialog( this .ftpPanel, file.getName() + "無法下載" ); return ; } // 創建本地文件對象 File downFile = new File(localFolder, ftpFileStr); // 創建本地文件的輸出流 FileOutputStream fout = new FileOutputStream(downFile, true ); // 計算文件大小 double fileLength = file.getLongSize() / Math.pow( 1024 , 2 ); ProgressArg progressArg = new ProgressArg(( int ) (file .getLongSize() / 1024 ), 0 , 0 ); //進度參數 String size = String.format( "%.4f MB" , fileLength); //"文件名", "大小", "本地文件名","主機", "狀態" Object[] row = new Object[] { ftpFileStr, size, downFile.getAbsolutePath(), ftpClient.getServer(), progressArg }; DownloadPanel downloadPanel = ftpPanel.frame.getDownloadPanel(); //下載隊列面板 downloadPanel.addRow(row); //添加列 byte [] data = new byte [ 1024 ]; // 定義緩存 int read = - 1 ; while ((read = ftpIs.read(data)) > 0 ) { // 讀取FTP文件內容到緩存 Thread.sleep( 0 , 30 ); // 線程休眠 fout.write(data, 0 , read); // 將緩存數據寫入本地文件 // 累加進度條 progressArg.setValue(progressArg.getValue() + 1 ); } progressArg.setValue(progressArg.getMax()); // 結束進度條 fout.close(); // 關閉文件輸出流 ftpIs.close(); // 關閉FTP文件輸入流 } else if (file.isDirectory()) { // 如果下載的是文件夾 // 創建本地文件夾對象 File directory = new File(localFolder, ftpFileStr); directory.mkdirs(); // 創建本地的文件夾 ftpClient.cd(file.getName()); // 改變FTP服務器的當前路徑 // 獲取FTP服務器的文件列表信息 TelnetInputStream telnetInputStream=ftpClient.list(); byte []names= new byte [ 2048 ]; int bufsize= 0 ; bufsize=telnetInputStream.read(names, 0 , names.length); int i= 0 ,j= 0 ; while (i<bufsize){ //字符模式為10,二進制模式為13 // if (names[i]==10) { if (names[i]== 13 ) { //獲取字符串 -rwx------ 1 user group 57344 Apr 18 05:32 騰訊電商2013實習生招聘TST推薦模板.xls //文件名在數據中開始做坐標為j,i-j為文件名的長度,文件名在數據中的結束下標為i-1 String fileMessage = new String(names,j,i-j); if (fileMessage.length() == 0 ){ System.out.println( "fileMessage.length() == 0" ); break ; } //按照空格將fileMessage截為數組后獲取相關信息 // 正則表達式 \s表示空格,{1,}表示1一個以上 if (!fileMessage.split( "\\s+" )[ 8 ].equals( "." ) && !fileMessage.split( "\\s+" )[ 8 ].equals( ".." )){ /**文件大小*/ String sizeOrDir= "" ; if (fileMessage.startsWith( "d" )) { //如果是目錄 sizeOrDir= "<DIR>" ; } else if (fileMessage.startsWith( "-" )) { //如果是文件 sizeOrDir=fileMessage.split( "\\s+" )[ 4 ]; } /**文件名*/ String fileName=fileMessage.split( "\\s+" )[ 8 ]; FtpFile ftpFile = new FtpFile(); // 將FTP目錄信息初始化到FTP文件對象中 ftpFile.setSize(sizeOrDir); ftpFile.setName(fileName); ftpFile.setPath(file.getAbsolutePath()); // 遞歸執行子文件夾的下載 downFile(ftpFile, localFolder); } // j=i+1;//上一次位置為字符模式 j=i+ 2 ; //上一次位置為二進制模式 } i=i+ 1 ; } ftpClient.cdUp(); // 返回FTP上級路徑 } } catch (Exception ex) { ex.printStackTrace(); } } |
功能效果圖可以查看以下兩篇文章。
Java語言實現簡單FTP軟件------>FTP軟件效果圖預覽之上傳功能(三)
Java語言實現簡單FTP軟件------>FTP軟件效果圖預覽之下載功能(二)
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/ouyang_peng/article/details/9970603