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;
}

}

  • 1
  • 2
  • 下一页

相关内容