歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Applet FTP 上傳

在項目中可能有時候上傳的文件比較大。如果用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 FileFtpAppletextends 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 finallong serialVersionUID= 1L;

private FileFtpApplet jFrame= null;

private JButton jFileButton= null;

public FileFtpApplet() {
// TODO Auto-generated constructor stub
jFrame =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() {
@Override
public boolean accept(File f) {
if (f.getName().endsWith("dat")|| f.isDirectory())
return true;
return false;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return"數據文件(*.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;
//是否完整保留原文件名
privateboolean isSaveFileName= true;
//枚舉上傳狀態
publicenum 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; //刪除遠程文件失敗
}

//枚舉下載狀態
publicenum 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= newbyte[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= newbyte[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;
else
fillDir = "";

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= newbyte[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 block
e.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;
}

}

Copyright © Linux教程網 All Rights Reserved