1、FTP上传工具类:
import com.uniubi.smartfrontdesk.util.UniUbiConsts;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import uniubi.generictools.LogUtil;
public class FTP {
/**
* 服务器名.
*/
private String hostName;
/**
* 端口号
*/
private int serverPort;
/**
* 用户名.
*/
private String userName;
/**
* 密码.
*/
private String password;
/**
* FTP连接.
*/
private FTPClient ftpClient;
public FTP() {
this.hostName = UniUbiConsts.FTP_URL;
this.serverPort = UniUbiConsts.FTP_PORT;
this.userName = UniUbiConsts.FTP_USERNAME;
this.password = UniUbiConsts.FTP_PASSWORD;
this.ftpClient = new FTPClient();
}
// -------------------------------------------------------文件上传方法------------------------------------------------
/**
* 上传单个文件.
*
* @param remotePath FTP目录
* @param listener 监听器
* @throws IOException
*/
public void uploadSingleFile(File singleFile, String remotePath,
UploadProgressListener listener) throws IOException {
// 上传之前初始化
this.uploadBeforeOperate(remotePath, listener);
boolean flag;
flag = uploadingSingle(singleFile, remotePath, listener);
if (flag) {
listener.onUploadProgress(2, 0, singleFile);
} else {
listener.onUploadProgress(3, 0, singleFile);
}
// 上传完成之后关闭连接
this.uploadAfterOperate(listener);
}
/**
* 上传单个文件.
*
* @param localFile 本地文件
* @return true上传成功, false上传失败
* @throws IOException
*/
private boolean uploadingSingle(File localFile, String remotePath,
UploadProgressListener listener) throws IOException {
boolean flag;
// 带有进度的方式
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(localFile));
ProgressInputStream progressInput = new ProgressInputStream(buffIn,
listener, localFile);
// 先判断服务器文件是否存在
LogUtil.d("该文件地址:" + remotePath + "/" + localFile.getName());
FTPFile[] files = ftpClient.listFiles(remotePath + "/"
+ localFile.getName());
LogUtil.d("服务器上是否有该文件:" + files.length);
if (files.length > 0) {
// 尝试移动文件内读取指针,实现断点续传
long remoteSize = files[0].getSize();
if (remoteSize > 0) {
if (progressInput.skip(remoteSize) == remoteSize) {
ftpClient.setRestartOffset(remoteSize);
}
}
}
flag = ftpClient.storeFile(localFile.getName(), progressInput);
buffIn.close();
return flag;
}
/**
* 上传文件之前初始化相关参数
*
* @param remotePath FTP目录
* @param listener 监听器
* @throws IOException
*/
private void uploadBeforeOperate(String remotePath,
UploadProgressListener listener) throws IOException {
// 打开FTP连接
try {
this.openConnect();
listener.onUploadProgress(0, 0, null);
} catch (IOException e1) {
e1.printStackTrace();
listener.onUploadProgress(1, 0, null);
return;
}
// 设置模式
ftpClient
.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);
// FTP下创建多级文件夹
String dirs[] = remotePath.split("/");
for (int i = 0; i < dirs.length; i++) {
if (!ftpClient.changeWorkingDirectory(dirs[i])) {
if (!ftpClient.makeDirectory(dirs[i])) {
LogUtil.d("创建目录失败,没有权限!");
}
ftpClient.changeWorkingDirectory(dirs[i]);
}
}
// ftpClient.makeDirectory(remotePath);
// // 改变FTP目录
// ftpClient.changeWorkingDirectory(remotePath);
// // 上传单个文件
}
/**
* 上传完成之后关闭连接
*/
public void uploadAfterOperate(UploadProgressListener listener) {
try {
this.closeConnect();
listener.onUploadProgress(4, 0, null);
} catch (IOException e) {
listener.onUploadProgress(5, 0, null);
e.printStackTrace();
}
}
/**
* 上传完成之后关闭连接
*/
public void uploadFailed() {
try {
this.closeConnect();
} catch (IOException e) {
e.printStackTrace();
}
}
// -------------------------------------------------------打开关闭连接------------------------------------------------
/**
* 打开FTP服务.
*
* @throws IOException
*/
public void openConnect() throws IOException {
// 中文转码
ftpClient.setControlEncoding("UTF-8");
int reply; // 服务器响应值
// 连接至服务器
ftpClient.connect(hostName, serverPort);
// 获取响应值
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
// 断开连接
ftpClient.disconnect();
throw new IOException("connect fail: " + reply);
}
// 登录到服务器
ftpClient.login(userName, password);
// 获取响应值
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
// 断开连接
ftpClient.disconnect();
throw new IOException("connect fail: " + reply);
} else {
// 获取登录信息
FTPClientConfig config = new FTPClientConfig(ftpClient
.getSystemType().split(" ")[0]);
config.setServerLanguageCode("zh");
ftpClient.configure(config);
// 使用被动模式设为默认
// ftpClient.enterLocalPassiveMode();
// 二进制文件支持
ftpClient
.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
}
}
/**
* 关闭FTP服务.
*
* @throws IOException
*/
public void closeConnect() throws IOException {
if (ftpClient != null) {
// 退出FTP
ftpClient.logout();
// 断开连接
ftpClient.disconnect();
}
}
// ---------------------------------------------------上传、下载、删除监听---------------------------------------------
/*
* 上传进度监听
*/
public interface UploadProgressListener {
void onUploadProgress(int status, long uploadSize,
File file);
}
}
2、进度条显示工具类;
import android.support.annotation.NonNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ProgressInputStream extends InputStream {
private static final int TEN_KILOBYTES = 1024 * 10; // 每上传10K返回一次
private InputStream inputStream;
private long progress;
private long lastUpdate;
private boolean closed;
private FTP.UploadProgressListener listener;
private File localFile;
public ProgressInputStream(InputStream inputStream,
FTP.UploadProgressListener listener, File localFile) {
this.inputStream = inputStream;
this.progress = 0;
this.lastUpdate = 0;
this.listener = listener;
this.localFile = localFile;
this.closed = false;
}
@Override
public int read() throws IOException {
int count = inputStream.read();
return incrementCounterAndUpdateDisplay(count);
}
@Override
public int read(@NonNull byte[] b, int off, int len) throws IOException {
int count = inputStream.read(b, off, len);
return incrementCounterAndUpdateDisplay(count);
}
@Override
public void close() throws IOException {
super.close();
if (closed)
throw new IOException("already closed");
closed = true;
}
private int incrementCounterAndUpdateDisplay(int count) {
if (count > 0)
progress += count;
lastUpdate = maybeUpdateDisplay(progress, lastUpdate);
return count;
}
private long maybeUpdateDisplay(long progress, long lastUpdate) {
if (progress - lastUpdate > TEN_KILOBYTES) {
lastUpdate = progress;
this.listener.onUploadProgress(6, progress, this.localFile);
}
return lastUpdate;
}
}
3、使用FTP工具类上传文件:
new FTP().uploadSingleFile(file, remote_path,new FTP.UploadProgressListener() {…}