系统结构
Step1 引入jar包
下载地址: commons-net-3.7.jar
Step2 FTP.java
public class FTP {
//服务器名
private String hostName;
//端口号
private int serverPort;
//用户名
private String userName;
//密码
private String password;
//连接FTP服务器
private FTPClient ftpClient;
public FTP() {
this.hostName = "xxx.xxx.xx.xx";
this.serverPort = xxxx;
this.userName = "xxx";
this.password = "xxx";
this.ftpClient = new FTPClient();
}
}
1. 传单个文件
/**
* 上传单个文件.
*
* @param singleFile 本地文件
* @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, listener);
if (flag) {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_SUCCESS, 0,
singleFile);
} else {
listener.onUploadProgress(MainActivity.FTP_UPLOAD_FAIL, 0,
singleFile);
}
// 上传完成之后关闭连接
this.uploadAfterOperate(listener);
}
/**
* 上传单个文件.
*
* @param localFile 本地文件
* @return true上传成功, false上传失败
* @throws IOException
*/
private boolean uploadingSingle(File localFile,
UploadProgressListener listener) throws IOException {
boolean flag = true;
// 不带进度的方式
// // 创建输入流
// InputStream inputStream = new FileInputStream(localFile);
// // 上传单个文件
// flag = ftpClient.storeFile(localFile.getName(), inputStream);
// // 关闭文件流
// inputStream.close();
// 带有进度的方式
BufferedInputStream buffIn = new BufferedInputStream(
new FileInputStream(localFile));
ProgressInputStream progressInput = new ProgressInputStream(buffIn,
listener, localFile);
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(MainActivity.FTP_CONNECT_SUCCESSS, 0,
null);
} catch (IOException e1) {
e1.printStackTrace();
listener.onUploadProgress(MainActivity.FTP_CONNECT_FAIL, 0, null);
return;
}
// 设置模式
ftpClient.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);
// FTP下创建文件夹
ftpClient.makeDirectory(remotePath);
// 改变FTP目录
ftpClient.changeWorkingDirectory(remotePath);
// 上传单个文件
}
上传完成一定要关闭链接
/**
* 上传完成之后关闭连接
*
* @param listener
* @throws IOException
*/
private void uploadAfterOperate(UploadProgressListener listener)
throws IOException {
this.closeConnect();
listener.onUploadProgress(MainActivity.FTP_DISCONNECT_SUCCESS, 0, null);
}
2. FTP服务相关
打开FTP服务
/**
* 打开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服务
/**
* 关闭FTP服务.
*
* @throws IOException
*/
public void closeConnect() throws IOException {
if (ftpClient != null) {
// 退出FTP
ftpClient.logout();
// 断开连接
ftpClient.disconnect();
}
}
3.相关接口
/*
* 上传进度监听
*/
interface UploadProgressListener {
void onUploadProgress(String currentStep, long uploadSize, File file);
}
Step3 ProgressInputStream.java
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 UploadProgressListener listener;
private File localFile;
public ProgressInputStream(InputStream inputStream, 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(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(MainActivity.FTP_UPLOAD_LOADING, progress, this.localFile);
}
return lastUpdate;
}
}
Step4 MainActivity.java
1. 添加权限 —>AndroidManifest.xml + 动态申请权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
2. 代码添加
public class MainActivity extends AppCompatActivity {
private Button mBtnUpload;
private static final String TAG = "MainActivity";
public static final String FTP_CONNECT_SUCCESSS = "ftp连接成功";
public static final String FTP_CONNECT_FAIL = "ftp连接失败";
public static final String FTP_DISCONNECT_SUCCESS = "ftp断开连接";
public static final String FTP_UPLOAD_SUCCESS = "ftp文件上传成功";
public static final String FTP_UPLOAD_FAIL = "ftp文件上传失败";
public static final String FTP_UPLOAD_LOADING = "ftp文件正在上传";
public static String[] PERMISSION_STORAGE = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"};
public final static int REQUEST_EXTERNAL_STORAGE = 1;
public final static int PERMISSION_REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkpermission();
mBtnUpload = findViewById(R.id.btn_upload);
mBtnUpload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
// 上传
File file = new File("/storage/emulated/0/aft/FP-AFT-123456");
try {
//单文件上传
new FTP().uploadSingleFile(file, "/storage/emulated/0/aft", new UploadProgressListener() {
@Override
public void onUploadProgress(String currentStep, long uploadSize, File file) {
// TODO Auto-generated method stub
Log.d(TAG, currentStep);
if (currentStep.equals(MainActivity.FTP_UPLOAD_SUCCESS)) {
Log.d(TAG, "-----upload successful-----");
} else if (currentStep.equals(MainActivity.FTP_UPLOAD_LOADING)) {
long fize = file.length();
float num = (float) uploadSize / (float) fize;
int result = (int) (num * 100);
Log.d(TAG, "-----uploading---" + result + "%");
}
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
}
public void checkpermission(){
Log.d(TAG, "checkPermission");
int permission = ActivityCompat.checkSelfPermission(this,
PERMISSION_STORAGE[REQUEST_EXTERNAL_STORAGE]);
if(permission != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, PERMISSION_STORAGE, PERMISSION_REQUEST_CODE);// requestCode Application specific request code to match with a result
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == PERMISSION_REQUEST_CODE) {
for (int i = 0; i < permissions.length; i++) {
if(grantResults[i] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "PERMISSION" + permissions[i] + "GRANTED!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "PERMISSION" + permissions[i] + "DENIED!", Toast.LENGTH_SHORT).show();
}
}
}
}
}