您的位置:首页 > 编程语言 > PHP开发

使用comment.net的FTP工具后支持完美的断点上传和下载

2017-07-19 11:04 741 查看

使用comment.net的FTP工具后支持完美的断点上传和下载

首先,在查阅各种资料后,发现在Java或者Android上使用FTP的工具不明显,但不是不多,最后发现最明显也是最好用的就是Apache的comment-net这个FTP工具了,看了下Apache上的文档,貌似解释的不是特别多,接下来看了下网上的博友的文章,有了一些基础的使用方法的了解,接下来测试ftp是否可用,上代码:

. FTP连接

/**
* 连接并登陆ftp服务
*
* @return
*/
public boolean connectFTPServer() {
try {
FTPClientConfig ftpClientCfg = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
ftpClientCfg.setLenientFutureDates(true);
mFtpClient.configure(ftpClientCfg);
mFtpClient.setConnectTimeout(15000);
mFtpClient.connect(mConfig.ipAdress, mConfig.port);
login();
int replyCode = mFtpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
mFtpClient.disconnect();
return false;
}
} catch (SocketException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}


. FTP登录

/**
* 登陆ftp服务端
*
* @return
*/
public boolean login() {
try {
if (mFtpClient.isConnected()) {
boolean isLogin = mFtpClient.login(mConfig.user, mConfig.pwd);
if (!isLogin) {
return false;
}
mFtpClient.setControlEncoding("GBK");
mFtpClient.setFileType(FTPClient.FILE_STRUCTURE);
// mFtpClient.enterLocalActiveMode();
mFtpClient.enterLocalPassiveMode();// 被动模式保证每次主动点击可以触发
// mFtpClient.enterRemotePassiveMode();
// mFtpClient.enterRemoteActiveMode()
// InetAddress.getByName(mConfig.ipAdress), mConfig.port);
mFtpClient.setFileType(FTP.BINARY_FILE_TYPE);
System.out.println("FTP 已登录到\"" + mFtpClient.pwd() + "\"目录");
return isLogin;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}


. FTP下载(断点续传版,这里只演示了单文件)

/**
* 下载FTP上的文件
*
* @param remoteFileName
* @param localFileName
* @param currentSize
*/
public void downLoadFile(String remoteFileName, String localFileName, long currentSize) {
Log.i(TAG, "downloadFile fileName=" + remoteFileName + " currentSize=" + currentSize);
if (retrieveListener != null) {
retrieveListener.onStart();
}
byte[] buffer = new byte[mConfig.bufferSize];
// mFtpClient.enterLocalPassiveMode();
long serverSize = 0;
int len = -1;
long now = -1;
boolean append = false;

if (mFtpClient != null) {
InputStream ins = null;
FileOutputStream fos = null;
File localFile = new File(localFileName);
FTPFile[] remotefile;
try {
long localSize = localFile.length();
remotefile = mFtpClient.listFiles(remoteFileName);
if (localSize > 0) {
mFtpClient.setRestartOffset(localSize);
now = localSize;
append = true;
}
ins = getRemoteFileStream(remoteFileName);
fos = new FileOutputStream(localFile, append);
if (ins == null) {
throw new FileNotFoundException("remote file is not exist");
}
serverSize = remotefile[0].getSize(); // 获取远程文件的长度
while ((len = ins.read(buffer)) != -1) {
if (isStopDownload) {
break;
}
fos.write(buffer, 0, len);
now += len;
retrieveListener.onTrack(now, serverSize);
}
if (isStopDownload) {
retrieveListener.onCancel();
} else {
if (mFtpClient.completePendingCommand()) {
retrieveListener.onDone();
} else {
retrieveListener.onError(ERROR.DOWNLOAD_ERROR, "download fail");
}
}
// 主动调用一次getReply()把接下来的226消费掉. 这样做是可以解决这个返回null问题。这句话是别人写的,在这没有作用
//mFtpClient.getReply();
} catch (FileNotFoundException e) {
retrieveListener.onError(ERROR.FILE_NO_FOUNT, "download fail:" + e);
} catch (IOException e) {
retrieveListener.onError(ERROR.IO_ERROR, "download fail:" + e);
} finally {
try {
ins.close();
fos.close();
} catch (Exception e2) {
}
}
}
}


. FTP上传(断点续传版,这里只演示了单文件)

/**
* 带有断点续传的上传方法实现
* @param localPath 本地路径
* @param workDirectory 远程根目录默认用“/”
* @param desFileName 远程文件目录,写全目录可以成功,如/home/uftp/xxx.mp4
* @return
*/
public boolean uploadFileWithout(String localPath, String workDirectory, String desFileName) {
Log.i(TAG, "uploadFile localPath=" + localPath + " desFileName=" + desFileName);
if (retrieveListener != null) {
retrieveListener.onStart();
}
if (mFtpClient != null && mFtpClient.isConnected()) {
// 设置存储路径
try {
mFtpClient.makeDirectory(workDirectory);
mFtpClient.changeWorkingDirectory(workDirectory);
mFtpClient.setBufferSize(1024);
// 对远程目录的处理
String remoteFileName = desFileName;
// 检查远程是否存在文件
FTPFile[] files = mFtpClient.listFiles(desFileName);
long remoteSize = files[0].getSize();
// if (remoteSize > 0)
File f = new File(localPath);
long localSize = f.length();
if (remoteSize == localSize) {
System.out.println(UploadStatus.File_Exits);
return false;
} else if (remoteSize > localSize) {
System.out.println(UploadStatus.Remote_Bigger_Local);
return false;
}
// 显示进度的上传
long step = f.length() / 100;
long process = 0;
long localreadbytes = 0L;
RandomAccessFile raf = new RandomAccessFile(f, "r");
OutputStream out = mFtpClient.appendFileStream(remoteFileName);
// 断点续传
if (remoteSize > 0) {
mFtpClient.setRestartOffset(remoteSize);
process = remoteSize / step;
raf.seek(remoteSize);
localreadbytes = remoteSize;
}
byte[] bytes = new byte[1024];
int c;
while ((c = raf.read(bytes)) != -1) {
if (isStopUpload) {
break;
}
out.write(bytes, 0, c);
localreadbytes += c;
if (localreadbytes / step != process) {
process = localreadbytes / step;
System.out.println("上传进度:" + process);
// TODO 汇报上传状态
retrieveListener.onTrack(localreadbytes, localSize);
}
}
out.flush();
raf.close();
out.close();
if (isStopUpload) {
retrieveListener.onCancel();
return false;
} else {
boolean result = mFtpClient.completePendingCommand();
if (remoteSize > 0 && result == false) {
mFtpClient.deleteFile(remoteFileName);
System.out.println("远程文件已删除,请重新上传!");
}
return result;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (retrieveListener != null) {
retrieveListener.onError(ERROR.IO_ERROR, "upload error:" + e);
}
}
}

return false;
}


.后来发现其中还有一个问题,就是下载的时候,到99%的时候会卡住,多次暂停继续后,可以下载完成,这个原因目前还不明,后面有发现,再更新。

代码在这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  apache android java