Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP上傳下載管理模塊實(shí)現(xiàn)(11)
本文為大家分享了FTP上傳下載管理模塊的實(shí)現(xiàn)方法,供大家參考,具體內(nèi)容如下
1、上傳本地文件或文件夾到遠(yuǎn)程FTP服務(wù)器端的功能。
當(dāng)用戶在本地文件列表中選擇想要上傳的文件后,點(diǎn)擊上傳按鈕,將本機(jī)上指定的文件上傳到FTP服務(wù)器當(dāng)前展現(xiàn)的目錄,下圖為上傳子模塊流程圖
選擇好要上傳的文件或文件夾,點(diǎn)擊“上傳”按鈕,會(huì)觸發(fā)com.oyp.ftp.panel.local.UploadAction類(lèi)的actionPerformed(ActionEvent e)方法,其主要代碼如下
/** * 上傳文件動(dòng)作的事件處理方法 */ public void actionPerformed(java.awt.event.ActionEvent evt) { // 獲取用戶選擇的多個(gè)文件或文件夾 int[] selRows = this.localPanel.localDiskTable.getSelectedRows(); if (selRows.length < 1) { JOptionPane.showMessageDialog(this.localPanel, "請(qǐng)選擇上傳的文件或文件夾"); return; } // 獲取FTP服務(wù)器的當(dāng)前路徑 String pwd = this.localPanel.frame.getFtpPanel().getPwd(); // 創(chuàng)建FTP當(dāng)前路徑的文件夾對(duì)象 FtpFile ftpFile = new FtpFile("", pwd, true); // 遍歷本地資源的表格 for (int i = 0; i < selRows.length; i++) { Object valueAt = this.localPanel.localDiskTable.getValueAt( selRows[i], 0); // 獲取表格選擇行的第一列數(shù)據(jù) if (valueAt instanceof DiskFile) { final DiskFile file = (DiskFile) valueAt; // 獲取本地面板類(lèi)中的隊(duì)列,該隊(duì)列是LinkedList類(lèi)的實(shí)例對(duì)象 Queue<Object[]> queue = this.localPanel.queue; queue.offer(new Object[] { file, ftpFile });// 執(zhí)行offer方法向隊(duì)列尾添加對(duì)象 } } }
在com.oyp.ftp.panel.local.UploadThread線程類(lèi)的run()方法,會(huì)判斷上傳隊(duì)列是否有對(duì)象,如果有則調(diào)用其copyFile(File file, FtpFile ftpFile)方法實(shí)現(xiàn)上傳文件的功能,上傳完后刷新遠(yuǎn)程FTP文件管理的面板。其run()方法主要代碼如下
* 線程的主體方法 */ public void run() { // 線程的主體方法 while (conRun) { try { Thread.sleep(1000); // 線程休眠1秒 Queue<Object[]> queue = localPanel.queue; // 獲取本地面板的隊(duì)列對(duì)象 queueValues = queue.peek(); // 獲取隊(duì)列首的對(duì)象 if (queueValues == null) { // 如果該對(duì)象為空 continue; // 進(jìn)行下一次循環(huán) } File file = (File) queueValues[0]; // 獲取隊(duì)列中的本隊(duì)文件對(duì)象 FtpFile ftpFile = (FtpFile) queueValues[1]; // 獲取隊(duì)列中的FTP文件對(duì)象 if (file != null) { selPath = file.getParent(); copyFile(file, ftpFile); // 調(diào)用遞歸方法上傳文件 FtpPanel ftpPanel = localPanel.frame.getFtpPanel(); ftpPanel.refreshCurrentFolder(); // 刷新FTP面板中的資源 } Object[] args = queue.peek(); // 判斷隊(duì)列頂是否為處理的上一個(gè)任務(wù)。 if (queueValues == null || args == null || !queueValues[0].equals(args[0])) { continue; } queue.remove(); // 移除隊(duì)列首元素 } catch (Exception e) { e.printStackTrace(); } } }
其中調(diào)用的copyFile(File file, FtpFile ftpFile)方法代碼如下
/** * 上傳線程的遞歸方法,上傳文件夾的所有子文件夾和內(nèi)容 * @param file * - FTP文件對(duì)象 * @param localFolder * - 本地文件夾對(duì)象 */ private void copyFile(File file, FtpFile ftpFile) { // 遞歸遍歷文件夾的方法 // 判斷隊(duì)列面板是否執(zhí)行暫停命令 while (localPanel.frame.getQueuePanel().isStop()) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } Object[] args = localPanel.queue.peek(); // 判斷隊(duì)列頂是不是上一個(gè)處理的任務(wù)。 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(); // 遠(yuǎn)程FTP的文件名絕對(duì)路徑 // System.out.println("remoteFile:" + remoteFile); double fileLength = file.length() / Math.pow(1024, 2); ProgressArg progressArg = new ProgressArg( (int) (file.length() / 1024), 0, 0);//進(jìn)度參數(shù) 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); // 獲取服務(wù)器文件的輸出流 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); // 輸出到服務(wù)器 progressArg.setValue(progressArg.getValue() + 1);// 累加進(jìn)度條 } progressArg.setValue(progressArg.getMax()); // 結(jié)束進(jìn)度條 fis.close(); // 關(guān)閉文件輸入流 put.close(); // 關(guān)閉服務(wù)器輸出流 } else if (file.isDirectory()) { path = file.getPath().replace(selPath, ""); ftpFile.setName(path.replace("\\", "/")); // System.out.println("Dirpath:"+path); /**將目錄切換到當(dāng)前FTP服務(wù)器的當(dāng)前目錄*/ ftpClient.cd(this.localPanel.frame.getFtpPanel().getPwd()); // /media目錄 /** * 如果有創(chuàng)建文件夾的權(quán)限,則在當(dāng)前FTP服務(wù)器的當(dāng)前目錄下創(chuàng)建文件夾 * 必須要有創(chuàng)建文件夾的權(quán)限,否則會(huì)報(bào)錯(cuò) * path:audio ftpFile.getAbsolutePath():/media/audio remoteFile:/media/audio/梁靜茹-會(huì)呼吸的痛Live.mp3 */ ftpClient.sendServer("MKD " + path + "\r\n"); //創(chuàng)建 /media/audio 目錄 ftpClient.readServerResponse(); /*********************************************************** * 如果沒(méi)有有創(chuàng)建文件夾的權(quán)限,則創(chuàng)建文件夾,因此FTP服務(wù)器的當(dāng)前路徑下不存在 * 那么將文件上傳到此FTP服務(wù)器的當(dāng)前路徑下 * * 如要上傳C://audio目錄(目錄中有 梁靜茹-會(huì)呼吸的痛Live.mp3 和 林宥嘉-心酸.mp3 兩個(gè)文件) * 到 FTP服務(wù)器上的 /media/ 目錄下 * 因?yàn)镕TP服務(wù)器上沒(méi)有 /media/audio 目錄,并且FTP服務(wù)器當(dāng)前的目錄為 /media * 所以將 C://audio目錄下的文件上傳到了 /media目錄下 * ftpFile.getAbsolutePath():/media/audio remoteFile:/media/梁靜茹-會(huì)呼吸的痛Live.mp3 remoteFile:/media/林宥嘉-心酸.mp3 */ //創(chuàng)建一個(gè)文件夾對(duì)象,檢查該文件是否存在 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、下載遠(yuǎn)程FTP服務(wù)器端的文件或文件夾到本地
當(dāng)用戶在遠(yuǎn)程FTP服務(wù)器文件列表中選擇想要下載的文件后,點(diǎn)擊下載按鈕,將服務(wù)器上的文件下載至本機(jī),下圖為下載子模塊流程圖。
選擇好要下載的文件或文件夾,點(diǎn)擊“下載”按鈕,會(huì)觸發(fā)com.oyp.ftp.panel.ftp.DownAction類(lèi)的actionPerformed(ActionEvent e)方法,其主要代碼如下
/** * 下載按鈕的動(dòng)作處理器動(dòng)作的事件處理方法 */ @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++) { // 獲取每行的第一個(gè)單元值并轉(zhuǎn)換成FtpFile類(lèi)的對(duì)象 final FtpFile file = (FtpFile) ftpPanel.ftpDiskTable.getValueAt( selRows[i], 0); if (file != null) { // 獲取本地資源管理面板的當(dāng)前文件夾 File currentFolder = ftpPanel.frame.getLocalPanel() .getCurrentFolder(); // 把FTP文件對(duì)象和本地當(dāng)前文件夾對(duì)象定義成數(shù)組添加到下載隊(duì)列中 ftpPanel.queue.offer(new Object[] { file, currentFolder }); } } }
在com.oyp.ftp.panel.ftp.DownThread線程類(lèi)的run()方法,會(huì)判斷下載隊(duì)列是否有對(duì)象,如果有則調(diào)用其downFile(FtpFile file, File localFolder)方法實(shí)現(xiàn)上傳文件的功能,上傳完后刷新遠(yuǎn)程FTP文件管理的面板。其run()方法代碼如下
public void run() { // 線程業(yè)務(wù)方法 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(); // 判斷隊(duì)列頂是否為處理的上一個(gè)任務(wù)。 if (queueValues == null || args == null || !queueValues[0].equals(args[0])) continue; ftpPanel.queue.poll(); } catch (Exception e) { e.printStackTrace(); } } }
其中調(diào)用的downFile(FtpFile file, File localFolder)方法代碼如下
/** * 下載線程的遞歸方法,用戶探索FTP下載文件夾的所有子文件夾和內(nèi)容 * @param file FTP文件對(duì)象 * @param localFolder 本地文件夾對(duì)象 */ private void downFile(FtpFile file, File localFolder) { // 判斷隊(duì)列面板是否執(zhí)行暫停命令 while (ftpPanel.frame.getQueuePanel().isStop()) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } Object[] args = ftpPanel.queue.peek(); // 判斷隊(duì)列頂是否為處理的上一個(gè)任務(wù)。 if (queueValues == null || args == null || !queueValues[0].equals(args[0])) return; try { String ftpFileStr = file.getAbsolutePath().replaceFirst(path + "/", ""); if (file.isFile()) { // 獲取服務(wù)器指定文件的輸入流 TelnetInputStream ftpIs = ftpClient.get(file.getName()); if (ftpIs == null) { JOptionPane.showMessageDialog(this.ftpPanel, file.getName() + "無(wú)法下載"); return; } // 創(chuàng)建本地文件對(duì)象 File downFile = new File(localFolder, ftpFileStr); // 創(chuàng)建本地文件的輸出流 FileOutputStream fout = new FileOutputStream(downFile, true); // 計(jì)算文件大小 double fileLength = file.getLongSize() / Math.pow(1024, 2); ProgressArg progressArg = new ProgressArg((int) (file .getLongSize() / 1024), 0, 0); //進(jìn)度參數(shù) String size = String.format("%.4f MB", fileLength); //"文件名", "大小", "本地文件名","主機(jī)", "狀態(tài)" Object[] row = new Object[] { ftpFileStr, size, downFile.getAbsolutePath(), ftpClient.getServer(), progressArg }; DownloadPanel downloadPanel = ftpPanel.frame.getDownloadPanel(); //下載隊(duì)列面板 downloadPanel.addRow(row); //添加列 byte[] data = new byte[1024]; // 定義緩存 int read = -1; while ((read = ftpIs.read(data)) > 0) { // 讀取FTP文件內(nèi)容到緩存 Thread.sleep(0, 30); // 線程休眠 fout.write(data, 0, read); // 將緩存數(shù)據(jù)寫(xiě)入本地文件 // 累加進(jìn)度條 progressArg.setValue(progressArg.getValue() + 1); } progressArg.setValue(progressArg.getMax());// 結(jié)束進(jìn)度條 fout.close(); // 關(guān)閉文件輸出流 ftpIs.close(); // 關(guān)閉FTP文件輸入流 } else if (file.isDirectory()) { // 如果下載的是文件夾 // 創(chuàng)建本地文件夾對(duì)象 File directory = new File(localFolder, ftpFileStr); directory.mkdirs(); // 創(chuàng)建本地的文件夾 ftpClient.cd(file.getName()); // 改變FTP服務(wù)器的當(dāng)前路徑 // 獲取FTP服務(wù)器的文件列表信息 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,二進(jìn)制模式為13 // if (names[i]==10) { if (names[i]==13) { //獲取字符串 -rwx------ 1 user group 57344 Apr 18 05:32 騰訊電商2013實(shí)習(xí)生招聘TST推薦模板.xls //文件名在數(shù)據(jù)中開(kāi)始做坐標(biāo)為j,i-j為文件名的長(zhǎng)度,文件名在數(shù)據(jù)中的結(jié)束下標(biāo)為i-1 String fileMessage = new String(names,j,i-j); if(fileMessage.length() == 0){ System.out.println("fileMessage.length() == 0"); break; } //按照空格將fileMessage截為數(shù)組后獲取相關(guān)信息 // 正則表達(dá)式 \s表示空格,{1,}表示1一個(gè)以上 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文件對(duì)象中 ftpFile.setSize(sizeOrDir); ftpFile.setName(fileName); ftpFile.setPath(file.getAbsolutePath()); // 遞歸執(zhí)行子文件夾的下載 downFile(ftpFile, localFolder); } // j=i+1;//上一次位置為字符模式 j=i+2;//上一次位置為二進(jìn)制模式 } i=i+1; } ftpClient.cdUp(); // 返回FTP上級(jí)路徑 } } catch (Exception ex) { ex.printStackTrace(); } }
功能效果圖可以查看以下兩篇文章。
Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件------>FTP軟件效果圖預(yù)覽之上傳功能(三)
Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件------>FTP軟件效果圖預(yù)覽之下載功能(二)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解velocity模板使javaWeb的html+js實(shí)現(xiàn)模塊化
- Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 輔助功能模塊FTP站點(diǎn)管理實(shí)現(xiàn)(12)
- Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP遠(yuǎn)程文件管理模塊實(shí)現(xiàn)(10)
- Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP連接管理模塊實(shí)現(xiàn)(8)
- java網(wǎng)上圖書(shū)商城(1)User模塊
- java網(wǎng)上商城項(xiàng)目第1篇之用戶注冊(cè)模塊
- javaweb圖書(shū)商城設(shè)計(jì)之購(gòu)物車(chē)模塊(3)
- Java編程一個(gè)隨機(jī)數(shù)產(chǎn)生模塊代碼分享
相關(guān)文章
spring boot 實(shí)現(xiàn)阿里云視頻點(diǎn)播功能(刪除視頻)
這篇文章主要介紹了spring boot 實(shí)現(xiàn)阿里云視頻點(diǎn)播(刪除視頻功能),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Java8實(shí)現(xiàn)Stream流的合并的方法展示
本文介紹了Java8中Stream流的合并方法,包括concat()、flatMap()和reduce()三種方法。其中,concat()方法可以將兩個(gè)Stream流合并成一個(gè),flatMap()方法可以將一個(gè)Stream流中的元素映射成多個(gè)Stream流并合并成一個(gè),reduce()方法可以將Stream流中的元素逐個(gè)合并成一個(gè)結(jié)果2023-05-05Springboot詳解線程池與多線程及阻塞隊(duì)列的應(yīng)用詳解
本例應(yīng)用線程池、多線程、阻塞隊(duì)列處理一個(gè)流程任務(wù)。本例處理一個(gè)訂單流程,主要包括生成訂單、訂單處理、訂單入庫(kù),下面我們一起看看2022-06-06Java權(quán)重隨機(jī)的實(shí)現(xiàn)方法
這篇文章主要介紹了Java權(quán)重隨機(jī)的實(shí)現(xiàn)方法,實(shí)例分析了權(quán)重隨機(jī)算法的原理與完整實(shí)現(xiàn)方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01Java?Valhalla?Project項(xiàng)目介紹
這篇文章主要介紹了Java?Valhalla?Project項(xiàng)目介紹,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09java基本教程之java線程等待與java喚醒線程 java多線程教程
這篇文章主要介紹了對(duì)線程等待/喚醒方法,文中使用了多個(gè)示例,大家參考使用吧2014-01-01Maven中optional和scope元素的使用弄明白了嗎
這篇文章主要介紹了Maven中optional和scope元素的使用弄明白了嗎,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12