Applet 大文件上传
生活随笔
收集整理的這篇文章主要介紹了
Applet 大文件上传
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
在項目中可能有時候上傳的文件比較大。如果用http方式來進行文件上傳的話,問題比較多。
所用可以采用ftp的方式,但是一般都是做的web項目,要在瀏覽器中嵌入,因為對于java的話,有applet的方式,當然applet用戶需要安裝JRE。一般的JRE大概在
10M多點。applet是在一個“沙箱”里運行,不能對用戶的文件進行讀取,如果要讀取本地的文件,就需要對其進行授權。需要用到java_home/bin目錄下的一些工具。
下面的網上找的一些關于文件上傳的代碼和操作方式,稍微修改了一下。
一、下面是applet的代碼,其他需要用到commons-net-3.0-src包,可以到apache的官網網站上下載。
之所以用src的包是因為需要把applet的代碼和commons-net的代碼都打成一個jar包。所以把commons-net-3.0-src下的源碼和applet的代碼放到同一個目錄下,
然后打成jar包。
package com.test.ftp;import java.applet.Applet; import java.io.File; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; /*** 說明:本APPLET只是測試大文件FTP上傳可行性* 至于其他功能比如FTP下載、刪除、FTP服務器文件列表可調用ContinueFTP相應功能。*/public class FileFtpApplet extends Applet {/*** Constructor of the applet.** @exception HeadlessException if GraphicsEnvironment.isHeadless()* returns true.*/ /* public FileFtpApplet() throws HeadlessException {super();}*//*** Called by the browser or applet viewer to inform* this applet that it is being reclaimed and that it should destroy* any resources that it has allocated. The <code>stop</code> method* will always be called before <code>destroy</code>. <p>** A subclass of <code>Applet</code> should override this method if* it has any operation that it wants to perform before it is* destroyed. For example, an applet with threads would use the* <code>init</code> method to create the threads and the* <code>destroy</code> method to kill them. <p>*/public void destroy() {// Put your code here}/*** Returns information about this applet. An applet should override* this method to return a <code>String</code> containing information* about the author, version, and copyright of the applet. <p>** @return a string containing information about the author, version, and* copyright of the applet.*/public String getAppletInfo() {return "This is my default applet created by Eclipse";}/*** Called by the browser or applet viewer to inform* this applet that it has been loaded into the system. It is always* called before the first time that the <code>start</code> method is* called. <p>** A subclass of <code>Applet</code> should override this method if* it has initialization to perform. For example, an applet with* threads would use the <code>init</code> method to create the* threads and the <code>destroy</code> method to kill them. <p>*/public void init() {// Put your code here}/*** Called by the browser or applet viewer to inform* this applet that it should start its execution. It is called after* the <code>init</code> method and each time the applet is revisited* in a Web page. <p>** A subclass of <code>Applet</code> should override this method if* it has any operation that it wants to perform each time the Web* page containing it is visited. For example, an applet with* animation might want to use the <code>start</code> method to* resume animation, and the <code>stop</code> method to suspend the* animation. <p>*/public void start() {// Put your code here}/*** Called by the browser or applet viewer to inform* this applet that it should stop its execution. It is called when* the Web page that contains this applet has been replaced by* another page, and also just before the applet is to be destroyed. <p>** A subclass of <code>Applet</code> should override this method if* it has any operation that it wants to perform each time the Web* page containing it is no longer visible. For example, an applet* with animation might want to use the <code>start</code> method to* resume animation, and the <code>stop</code> method to suspend the* animation. <p>*/public void stop() {// Put your code here}private static final long serialVersionUID = 1L;private FileFtpApplet jFrame = null;private JButton jFileButton = null;public FileFtpApplet() {// TODO Auto-generated constructor stubjFrame = this;this.setSize(496, 260);jFileButton = new JButton("打開文件");jFrame.add(jFileButton);jFileButton.addMouseListener(new java.awt.event.MouseAdapter() {public void mouseClicked(java.awt.event.MouseEvent e) {// System.out.println("mouseClicked()"); // TODO// Auto-generated Event stub mouseClicked()JFileChooser jfChooser = new JFileChooser("D:\\..\\..");jfChooser.setDialogTitle("打開并上傳文件");jfChooser.setFileFilter(new FileFilter() {@Overridepublic boolean accept(File f) {if (f.getName().endsWith("dat") || f.isDirectory())return true;return false;}@Overridepublic String getDescription() {// TODO Auto-generated method stubreturn "數據文件(*.dat)";}});int result = jfChooser.showOpenDialog(jFrame);if (result == JFileChooser.APPROVE_OPTION) { // 確認打開File fileIn = jfChooser.getSelectedFile();if (fileIn.exists()) {//JOptionPane.showMessageDialog(jFrame, "OPEN"); // 提示框ContinueFTP myFtp = new ContinueFTP(); try {long l1 = System.currentTimeMillis();System.out.println("begin:"+ l1);if (myFtp.connect("10.68.7.182", 21, "a", "a")) {String remotePath = "/";String remoteFile = myFtp.getRemoteFileName(fileIn.getName());if (remotePath == null || remotePath.trim().equals(""))remotePath = "/";//文件擴展名String kzNm = "";if (remoteFile.indexOf(".")>=0)kzNm = remoteFile.substring(remoteFile.indexOf("."));String cellCode = "yp";boolean isSaveFileName = false;//若不保留原文件,則重新組裝遠程文件名if (!isSaveFileName)remoteFile= cellCode+"_"+System.currentTimeMillis()+kzNm;//獲得遠程路徑最后一位String lastStr = remotePath.substring(remotePath.length()-1);if (lastStr.trim().equals("/"))remoteFile = remotePath + cellCode + "/" + remoteFile;else remoteFile = remotePath + "/" +cellCode + "/" + remoteFile;myFtp.upload(fileIn, remoteFile);myFtp.disconnect(); long l2 = System.currentTimeMillis();System.out.println("end:"+ l2);System.out.println("remaining:"+(l2-l1));}} catch (Exception e1) {System.out.println("連接FTP出錯:"+e1.getMessage());}} else {}} else if (result == JFileChooser.CANCEL_OPTION) {System.out.println("Cancel button is pushed.");} else if (result == JFileChooser.ERROR_OPTION) {System.err.println("Error when select file.");}}});} } package com.test.ftp;import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List;import org.apache.commons.net.PrintCommandListener; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply;/*** FTP上傳下載文件* 支持斷點續傳* @version: 2009-10-23 下午04:28:48*/ public class ContinueFTP{private File file=null;//是否完整保留原文件名private boolean isSaveFileName = true;//枚舉上傳狀態 public enum UploadStatus {Create_Directory_Fail, //遠程服務器相應目錄創建失敗 Create_Directory_Success, //遠程服務器創建目錄成功 Upload_New_File_Success, //上傳新文件成功 Upload_New_File_Failed, //上傳新文件失敗 File_Exits, //文件已經存在 Remote_Bigger_Local, //遠程文件大于本地文件 Upload_From_Break_Success, //斷點續傳成功 Upload_From_Break_Failed, //斷點續傳失敗 Delete_Remote_Faild; //刪除遠程文件失敗 }//枚舉下載狀態public enum DownloadStatus {Remote_File_Noexist, //遠程文件不存在 Local_Bigger_Remote, //本地文件大于遠程文件 Download_From_Break_Success, //斷點下載文件成功 Download_From_Break_Failed, //斷點下載文件失敗 Download_New_Success, //全新下載文件成功 Download_New_Failed; //全新下載文件失敗 }public void init(){}public FTPClient ftpClient = new FTPClient(); public ContinueFTP(){//設置將過程中使用到的命令輸出到控制臺 this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); }/*** 功能:通過本地文件名指定遠程文件名 * @param localFileName* @return* String* 范例:*/public String getRemoteFileName(String localFileName){String fileName ="";//分隔符String sepaRator="\\";if (localFileName.indexOf(sepaRator)<0)sepaRator="/";//最后分隔符位置int idx = localFileName.lastIndexOf(sepaRator)+1;fileName = localFileName.substring(idx);return fileName;}/*** 功能:檢查遠程是否存在文件 * @param remoteFileName 遠程文件名* @return* @throws IOException* boolean* 范例:*/public boolean isFileExist(String remoteFileName) throws IOException{boolean isFileExist = false; //檢查遠程是否存在文件 FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1")); if(files!=null && files.length >= 1){isFileExist = true;}return isFileExist;}/** * 連接到FTP服務器 * @param hostname 主機名 * @param port 端口 * @param username 用戶名 * @param password 密碼 * @return 是否連接成功 * @throws IOException */ public boolean connect(String hostname,int port,String username,String password) throws Exception{boolean bl = false;try{ftpClient.connect(hostname, port); }catch(Exception e){//可具體報錯到主機和端口號e.printStackTrace();// throw new BaseException("FTPConnError01",new String[]{"connect",e.getMessage()});}try{//ftpClient.setControlEncoding("GBK"); if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){if(ftpClient.login(username, password)){bl = true;}}}catch(Exception e){//可具體報錯到用戶和密碼// throw new BaseException("FTPConnError02",new String[]{"connect",e.getMessage()});e.printStackTrace();}return bl; }/** * 從FTP服務器上下載文件,支持斷點續傳,上傳百分比匯報 * @param remote 遠程文件路徑 * @param local 本地文件路徑 * @return 上傳的狀態 * @throws IOException */ public DownloadStatus download(String remote,String local) throws Exception{//設置被動模式 ftpClient.enterLocalPassiveMode();//設置以二進制方式傳輸ftpClient.setFileType(FTP.BINARY_FILE_TYPE);DownloadStatus result;//檢查遠程文件是否存在FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"),"iso-8859-1"));if(files.length != 1){// throw new BaseException("CellDataInputService",new String[]{"download","遠程文件"+remote+"不存在"});System.out.println("遠程文件"+remote+"不存在");}long lRemoteSize = files[0].getSize(); File f = new File(local); //本地存在文件,進行斷點下載if(f.exists()){long localSize = f.length(); //判斷本地文件大小是否大于遠程文件大小 if(localSize >= lRemoteSize){ System.out.println("本地文件大于遠程文件,下載中止"); return DownloadStatus.Local_Bigger_Remote; } //進行斷點續傳,并記錄狀態 FileOutputStream out = new FileOutputStream(f,true); ftpClient.setRestartOffset(localSize); InputStream in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1")); byte[] bytes = new byte[1024]; long step = lRemoteSize /100; long process=localSize /step; int c; while((c = in.read(bytes))!= -1){ out.write(bytes,0,c); localSize+=c; long nowProcess = localSize /step; if(nowProcess > process){ process = nowProcess; if(process % 10 == 0) System.out.println("下載進度:"+process); //TODO 更新文件下載進度,值存放在process變量中 } } in.close(); out.close(); boolean isDo = ftpClient.completePendingCommand(); if(isDo){ result = DownloadStatus.Download_From_Break_Success; }else { result = DownloadStatus.Download_From_Break_Failed; } }else { OutputStream out = new FileOutputStream(f); InputStream in= ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"),"iso-8859-1")); byte[] bytes = new byte[1024]; long step = lRemoteSize /100; long process=0; long localSize = 0L; int c; while((c = in.read(bytes))!= -1){ out.write(bytes, 0, c); localSize+=c; long nowProcess = localSize /step; if(nowProcess > process){ process = nowProcess; if(process % 10 == 0) System.out.println("下載進度:"+process); //TODO 更新文件下載進度,值存放在process變量中 } } in.close(); out.close(); boolean upNewStatus = ftpClient.completePendingCommand(); if(upNewStatus){ result = DownloadStatus.Download_New_Success; }else { result = DownloadStatus.Download_New_Failed; } } return result; } /** * 上傳文件到FTP服務器,支持斷點續傳 * @param local 本地文件名稱,絕對路徑 * @param remote 遠程文件路徑,使用/home/directory1/subdirectory/file.ext 按照Linux上的路徑指定方式,支持多級目錄嵌套,支持遞歸創建不存在的目錄結構 * @return 上傳結果 * @throws IOException */ public UploadStatus upload(File localFile,String remote) throws IOException{ //設置PassiveMode傳輸 ftpClient.enterLocalPassiveMode(); //設置以二進制流的方式傳輸 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); //ftpClient.setControlEncoding("GBK"); UploadStatus result; //對遠程目錄的處理 String remoteFileName = remote; if(remote.contains("/")){ remoteFileName = remote.substring(remote.lastIndexOf("/")+1); //創建服務器遠程目錄結構,創建失敗直接返回 if(CreateDirecroty(remote, ftpClient)==UploadStatus.Create_Directory_Fail){ return UploadStatus.Create_Directory_Fail; } } //檢查遠程是否存在文件 FTPFile[] files = ftpClient.listFiles(new String(remoteFileName.getBytes("GBK"),"iso-8859-1")); if(files!=null && files.length == 1){ long remoteSize = files[0].getSize(); //File f = new File(local); long localSize = localFile.length(); if(remoteSize==localSize){ return UploadStatus.File_Exits; }else if(remoteSize > localSize){ return UploadStatus.Remote_Bigger_Local; } //嘗試移動文件內讀取指針,實現斷點續傳 result = uploadFile(remoteFileName, localFile, ftpClient, remoteSize); //如果斷點續傳沒有成功,則刪除服務器上文件,重新上傳 if(result == UploadStatus.Upload_From_Break_Failed){ if(!ftpClient.deleteFile(remoteFileName)){ return UploadStatus.Delete_Remote_Faild; } result = uploadFile(remoteFileName, localFile, ftpClient, 0); } }else { result = uploadFile(remoteFileName, localFile, ftpClient, 0); } return result; } /** * 斷開與遠程服務器的連接 * @throws IOException */ public void disconnect() throws IOException{ if(this.ftpClient.isConnected()){ this.ftpClient.disconnect(); } } /*** 功能:創建目錄* 若傳入路徑已經存在,則返回該路徑,否則創建 * 目前暫不支持中文列名* @param remoteDir* @return* @throws IOException* String* 范例:*/public String CreateDirecroty(String remoteDir)throws IOException{ String fillDir = "";UploadStatus st = CreateDirecroty(remoteDir,this.ftpClient);if (st == UploadStatus.Create_Directory_Success)fillDir = remoteDir;elsefillDir = "";return fillDir;}/** * 遞歸創建遠程服務器目錄 * @param remote 遠程服務器文件絕對路徑 * @param ftpClient FTPClient對象 * @return 目錄創建是否成功 * @throws IOException */ public UploadStatus CreateDirecroty(String remote,FTPClient ftpClient) throws IOException{ UploadStatus status = UploadStatus.Create_Directory_Success; String directory = remote.substring(0,remote.lastIndexOf("/")+1); if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"),"iso-8859-1"))){//如果遠程目錄不存在,則遞歸創建遠程服務器目錄 int start=0; int end = 0; if(directory.startsWith("/")){start = 1; }else{start = 0; }end = directory.indexOf("/",start); while(true){String subDirectory = new String(remote.substring(start,end).getBytes("GBK"),"iso-8859-1"); if(!ftpClient.changeWorkingDirectory(subDirectory)){if(ftpClient.makeDirectory(subDirectory)){ ftpClient.changeWorkingDirectory(subDirectory); }else {System.out.println("創建目錄失敗"); return UploadStatus.Create_Directory_Fail; }} start = end + 1; end = directory.indexOf("/",start); //檢查所有目錄是否創建完畢 if(end <= start){break; }}} return status; } /** * 上傳文件到服務器,新上傳和斷點續傳 * @param remoteFile 遠程文件名,在上傳之前已經將服務器工作目錄做了改變 * @param localFile 本地文件File句柄,絕對路徑 * @param processStep 需要顯示的處理進度步進值 * @param ftpClient FTPClient引用 * @return * @throws IOException */ public UploadStatus uploadFile(String remoteFile,File localFile,FTPClient ftpClient,long remoteSize) throws IOException{UploadStatus status; //顯示進度的上傳 long step = localFile.length() / 100; long process = 0; long localreadbytes = 0L; RandomAccessFile raf = new RandomAccessFile(localFile,"r"); OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes("GBK"),"iso-8859-1"));//斷點續傳 if(remoteSize>0){ftpClient.setRestartOffset(remoteSize); process = remoteSize /step; raf.seek(remoteSize); localreadbytes = remoteSize; }byte[] bytes = new byte[1024]; int c; while((c = raf.read(bytes))!= -1){out.write(bytes,0,c); localreadbytes+=c;//TODO 匯報上傳狀態 if(localreadbytes / step != process){process = localreadbytes / step; System.out.println("上傳進度:" + process); }} out.flush(); raf.close(); out.close(); boolean result =ftpClient.completePendingCommand(); if(remoteSize > 0){ status = result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed; }else { status = result?UploadStatus.Upload_New_File_Success:UploadStatus.Upload_New_File_Failed; } return status; } /*** 功能:獲得遠程文件列表 * @param remoteDir 遠程路徑* @return* List<String>* 范例:*/public List<String> getRemoteFileList(String remoteDir){List<String> list = new ArrayList<String>();FTPFile[] files;try {files = ftpClient.listFiles(remoteDir);for (int i = 0; i < files.length; i++) {list.add(files[i].getName());}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}/*** 功能:刪除指定遠程文件 * @param fillFileName 包括路徑的完整文件名* @return* @throws Exception* boolean* 范例:*/public boolean deleteFile(String fillFileName) throws Exception {boolean bl = false;this.ftpClient.deleteFile(fillFileName);int status = this.ftpClient.getReplyCode();if(status == 250){bl = true;System.out.println("成功刪除FTP服務器中文件:" + fillFileName); } return bl;} /*** 功能:刪除指定遠程路徑 * @param remoteDir* @return* @throws Exception* boolean* 范例:*/public boolean deleteDir(String remoteDir)throws Exception {boolean isDel = false;this.ftpClient.removeDirectory(remoteDir);int status = this.ftpClient.getReplyCode();if(status == 250){isDel = true;System.out.println("成功刪除FTP服務器中目錄:" + remoteDir); } return isDel;}public static void main(String[] args) throws Exception {ContinueFTP myFtp = new ContinueFTP(); try { long l1 = System.currentTimeMillis();System.out.println("begin:"+ l1);if (myFtp.connect("192.168.1.101", 21, "cfd", "123456")) {String mkDir = myFtp.CreateDirecroty("TTT/ccc/");if (mkDir != null && !mkDir.trim().equals(""))System.out.println("mkDir success:"+mkDir);//myFtp.download( "/XA01B03H05/5.mp3",file,"0");//myFtp.upload("/XA01B03H05/5.mp3", "/云臺山.mpg");//myFtp.delete_file("/tmp.txt");//String str = new String("電視劇"); //myFtp.ftpClient.removeDirectory("/kkk/jk/");//myFtp.ftpClient.makeDirectory(new String(str.getBytes("GBK"),"iso-8859-1")); myFtp.disconnect(); long l2 = System.currentTimeMillis();System.out.println("end:"+ l2);System.out.println("remaining:"+(l2-l1));} } catch (IOException e) { System.out.println("連接FTP出錯:"+e.getMessage()); }}public File getFile() {return file;}public void setFile(File file) {this.file = file;}public boolean isSaveFileName() {return isSaveFileName;}public void setSaveFileName(boolean isSaveFileName) {this.isSaveFileName = isSaveFileName;}}
二、下面是數字簽名的方法和html內容
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>My applet 'FileFtpApplet' starting page</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="this is my page"><meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <applet codebase="." code="com.test.ftp.FileFtpApplet.class" name="FileFtpApplet"width="320"archive="FileFtpApplet.jar"height="240"></applet><!-- archive:存放applet的jar包的名稱 code:要運行的applet的名稱(包括包名) --></body> </html>
簽名方法:
<1>、生成密匙證書(key certificate),該證書將存儲在你的.keystore文件中。Validity指的是密匙的有效期,默認是180,但是這里我們需要一年的時間,所以我們設置為365 keytool -genkey -alias FileFtpApplet -validity 365 -keystore FileFtpApplet.keystore <2>、用我們的密匙來設計我們的APPLET jarsigner -keystore FileFtpApplet.keystore FileFtpApplet.jar FileFtpApplet <3>、導出證書 keytool -export -keystore FileFtpApplet.keystore -alias FileFtpApplet -file FileFtpApplet.cer簽名的時候把上面applet打成的jar包放到cmd當前的目錄下。
轉載于:https://my.oschina.net/laigous/blog/106607
總結
以上是生活随笔為你收集整理的Applet 大文件上传的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.01 与 37.8
- 下一篇: man thread_join