FTP上传功能的客户端实现

来源:互联网 发布:ubuntu删除文件夹 编辑:程序博客网 时间:2024/05/21 12:39
FTP的管理类:需要org.apache.commons.net jar包,方法是可行的,不需要的东西去掉即可,自己再下载一个服务端软件即可测试```public class FTPManager {    private static FTPManager instance;    public static final int STATE_UNUPLOAD = 0;                                    // 未上传    public static final int STATE_UPLOADING = 1;                                   // 上传中    public static final int STATE_PAUSEUPLOAD = 2;                                 // 暂停上传    public static final int STATE_WAITINGUPLOAD = 3;                               // 等待上传    public static final int STATE_UPLOADFAILED = 4;                                // 上传失败    public static final int STATE_UPLOADED = 5;                                    // 上传完成    public static final int STATE_CONNECTFAILED = 6;                               // 连接失败    public static final int STATE_CONNECTSUCCESS = 7;                              // 连接成功    public static final int STATE_PROGRESSING = 8;                                 // 正在传输,用于获取进度值    // 记录用户点击了下载按钮对应的UpLoadInfo    public Map<String, UpLoadInfo> mUpLoadInfoMap = new HashMap<String, UpLoadInfo>();    private FTPManager() {}    public static FTPManager getInstance() {//单例        if (instance == null) {            synchronized (FTPManager.class) {                if (instance == null) {                    instance = new FTPManager();                }            }        }        return instance;    }    public String ipAddr;    public int serverPort;    public String userName;    public String password;    public FTPClient ftpClient;    public void setFtpClient(Ftp f) {        this.ipAddr = f.getIpAddr();        this.serverPort = f.getPort();        this.userName = f.getUserName();        this.password = f.getPwd();        this.ftpClient = new FTPClient();    }    boolean isFtpConnectted;    /**     * 打开FTP服务.     */    public boolean openConnect() {        if (ftpClient.isConnected()) {            return true;        }        isFtpConnectted = false;        // 中文转码        ftpClient.setControlEncoding("UTF-8");        int reply; // 服务器响应值        // 连接至服务器        try {            ftpClient.setConnectTimeout(1500);//设置连接超时时间            ftpClient.connect(ipAddr, 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("login fail: " + reply);            } else {            /*// 获取登录信息            FTPClientConfig config = new FTPClientConfig(ftpClient                    .getSystemType().split(" ")[0]);            config.setServerLanguageCode("zh");            ftpClient.configure(config);*/                // 使用被动模式设为默认                //ftpClient.enterLocalPassiveMode();zzj注释,暂时无用,未出现卡死                // 二进制文件支持                ftpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);                // 设置模式                ftpClient.setFileTransferMode(org.apache.commons.net.ftp.FTP.STREAM_TRANSFER_MODE);                isFtpConnectted = true;            }        } catch (IOException e) {            LogUtils.i("连接失败!!");            e.printStackTrace();            isFtpConnectted = false;            return false;        }        return true;    }    public void pauseUpLoad(UpLoadInfo info) {        info.state = STATE_PAUSEUPLOAD;        notifyObservers(info);    }    public void cancelUpLoad(UpLoadInfo info) {        info.state = STATE_UNUPLOAD;        CarConnectionDao.getInstance().update(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");        notifyObservers(info);        ThreadFactory.getUpLoadPool().remove(info.task);    }    public void upLoad(UpLoadInfo info) {        mUpLoadInfoMap.put(info.fileName, info);        /*info.state = STATE_UNUPLOAD;        notifyObservers(info);*/        info.state = STATE_WAITINGUPLOAD;        CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");//下载前更新数据库信息,等待INg        notifyObservers(info);        UpLoadTask task = new UpLoadTask(info);        info.task = task;//把下载任务绑定到UpLoadInfo身上,便于进行取消任务        ThreadFactory.getUpLoadPool().execute(task);    }    class UpLoadTask implements Runnable {        private UpLoadInfo mInfo;        public UpLoadTask(UpLoadInfo info) {            mInfo = info;        }        @Override        public void run() {            try {                uploadSingleFile(new File(mInfo.locPath), mInfo.remotePath, mInfo);            } catch (IOException e) {                e.printStackTrace();            }        }    }    /**     * 上传单个文件.     */    public void uploadSingleFile(File singleFile, String remotePath, UpLoadInfo info) throws IOException {        // 上传之前初始化        this.uploadBeforeOperate(remotePath, info);        boolean flag = uploadingSingle(singleFile, info);        if(info.state == STATE_PAUSEUPLOAD||info.state == STATE_UNUPLOAD){            CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");        }else {            if (flag) {                info.state = STATE_UPLOADED;                CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");                notifyObservers(info);            } else {                info.state = STATE_UPLOADFAILED;                CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");                notifyObservers(info);            }        }        closeConnect();    }    /**     * 上传文件之前初始化相关参数     */    private void uploadBeforeOperate(String remotePath, UpLoadInfo info) {        if (this.openConnect()) {            changeWorkingDir(remotePath);            info.state = STATE_CONNECTSUCCESS;//如果走到这一步,说明openconnect没抛异常,连接成功,反之抛了任何异常都是连接失败            this.notifyObservers(info);        } else {            info.state = STATE_CONNECTFAILED;            notifyObservers(info);        }    }    /**     * 上传单个文件_流形式.     */    private boolean uploadingSingle(File localFile, UpLoadInfo info) {        boolean flag = false;        BufferedInputStream buffIn = null;        ProgressInputStream progressInput = null;        try {            buffIn = new BufferedInputStream(new FileInputStream(localFile));            progressInput = new ProgressInputStream(buffIn, localFile, info);            info.state = STATE_UPLOADING;            LogUtils.i(info.getFileName() + info.getState());            CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", info.getState() + "");            notifyObservers(info);//子线程中刷新,有可能本来想去更新STATE_UPLOADING的,结果走到下面更新了STATE_PROGRESSING,所以下面可以注释掉            //info.state = STATE_PROGRESSING;            CarConnectionDao.getInstance().add(info.getFileName(), info.getLocPath(), info.getRemotePath(), info.getProgress() + "", info.getMax() + "", 8 + "");            flag = ftpClient.storeFile(localFile.getName(), progressInput);//注意返回的结果,如果是真有两种情况,一个是暂停下载,一个是下载成功            //LogUtils.i("info.state:"+info.state+":"+flag);        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (buffIn != null) {                    buffIn.close();                }                if(progressInput != null){                    progressInput.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return flag;    }    public void closeConnect() {        if (ftpClient != null && ftpClient.isConnected()) {            // 退出FTP            try {                ftpClient.logout();                ftpClient.disconnect();            } catch (IOException e) {                e.printStackTrace();            }        }    }    //获取点击这个item的上传信息    public UpLoadInfo getUpLoadInfo(FtpBaseBean baseBean) {        //初始化UpLoadInfo        UpLoadInfo info = new UpLoadInfo();        info.setFileName(baseBean.getFileName());        info.setLocPath(baseBean.getLocPath());        info.setRemotePath(baseBean.getRemotePath());        //已上传        if (baseBean.getState() == STATE_UPLOADED) {            //LogUtils.i("文件已上传");            info.state = STATE_UPLOADED;            return info;        }        // 上传中        // 上传的进度        // 等待上传        // 上传失败 等其他情况        if (mUpLoadInfoMap.containsKey(info.getFileName())) {            return mUpLoadInfoMap.get(info.getFileName());        }        info.state = STATE_UNUPLOAD;//默认返回一个未上传的        return info;    }    /*// 检查远程是否存在文件    public boolean isFileExit(String locPath, String remotePath, String filename) {        LogUtils.i("进入isFileExit");        boolean b = false;        try {            //openConnect();            //ftpClient.makeDirectory(remotePath);            //ftpClient.changeWorkingDirectory(remotePath);            FTPFile[] files = ftpClient.listFiles(new String(filename.getBytes("utf-8"), "utf-8"));            LogUtils.i(files.length + "个" + files[0].getName());            if (files.length == 1) {                long remoteSize = files[0].getSize();                File f = new File(locPath);                long localSize = f.length();                if (remoteSize == localSize) {                    LogUtils.i("服务器中文件等于要上传文件,所以不上传");                    b = true;                } else {                    LogUtils.i("服务器中文件小于要上传文件,重新上传");                    b = false;                }            }        } catch (IOException e) {            e.printStackTrace();        }        return b;    }*/    /**     * 递归遍历出目录下面所有文件     *     * @param pathName 需要遍历的目录,必须以"/"开始和结束     * @throws IOException     */    public HashMap<String, Long> List(String pathName) {        HashMap<String, Long> remoteFiles = new HashMap<String, Long>();        if (pathName.startsWith("/") && pathName.endsWith("/")) {            changeWorkingDir(pathName);            FTPFile[] files = new FTPFile[0];            try {                files = this.ftpClient.listFiles();            } catch (IOException e) {                e.printStackTrace();            }            for (FTPFile file : files) {                if (file.isFile()) {                    remoteFiles.put(file.getName(), file.getSize());                    //LogUtils.i("file.getName():" + file.getName() + "file.getSize():" + file.getSize());                } else if (file.isDirectory()) {                    List(pathName + file.getName() + "/");                }            }        }        return remoteFiles;    }    //改变工作目录    private void changeWorkingDir(String pathName) {        //更换目录到当前目录        try {            if (!ftpClient.changeWorkingDirectory("/tecrollengine")) {                ftpClient.makeDirectory("/tecrollengine");                ftpClient.changeWorkingDirectory("/tecrollengine");            }            if (!ftpClient.changeWorkingDirectory(pathName)) {                ftpClient.makeDirectory(pathName);                ftpClient.changeWorkingDirectory(pathName);            }        } catch (IOException e) {            e.printStackTrace();            ShowToast.show(UIUtils.getContext(),"改变工作目录失败!");        }    }    //获取正在进行的任务的个数    public int getUpLoadingNum() {        int count = 0;        for (String s : mUpLoadInfoMap.keySet()) {            if (mUpLoadInfoMap.get(s).getState() == FTPManager.STATE_UPLOADING                    || mUpLoadInfoMap.get(s).getState() == FTPManager.STATE_WAITINGUPLOAD                    || mUpLoadInfoMap.get(s).getState() == FTPManager.STATE_PROGRESSING) {                count++;            }        }        return count;    }    //把所有正在进行和等待的任务变为未下载    public void changeTo_UNUPLOAD() {        for (String s : mUpLoadInfoMap.keySet()) {            switch(mUpLoadInfoMap.get(s).getState()){                case FTPManager.STATE_UPLOADING:                    mUpLoadInfoMap.get(s).setState(FTPManager.STATE_UNUPLOAD);                    notifyObservers(mUpLoadInfoMap.get(s));                    break;                case FTPManager.STATE_PROGRESSING:                    mUpLoadInfoMap.get(s).setState(FTPManager.STATE_UNUPLOAD);                    notifyObservers(mUpLoadInfoMap.get(s));                    break;                case FTPManager.STATE_WAITINGUPLOAD:                    cancelUpLoad(mUpLoadInfoMap.get(s));                    break;            }        }    }    /**     * 定义上传观察者     */    public interface UpLoadObserver {        void onUploadProgress(UpLoadInfo upLoadInfo);    }    List<UpLoadObserver> observers = new LinkedList<UpLoadObserver>();    public UpLoadObserver getObserver() {        if (observers.size() != 0) {            return observers.get(0);        }        return null;    }    public synchronized void addObserver(UpLoadObserver o) {        if (o == null)            throw new NullPointerException();        if (!observers.contains(o)) {            observers.add(o);        }    }    public synchronized void deleteObserver(UpLoadObserver o) {        observers.remove(o);    }    public void notifyObservers(UpLoadInfo upLoadInfo) {        for (UpLoadObserver o : observers) {            o.onUploadProgress(upLoadInfo);        }    }}```

ProgressInputStream :

public class ProgressInputStream extends InputStream {    private static final int TEN_KILOBYTES = 1024 * 200;  //每上传200K返回一次    private InputStream inputStream;    private long progress;    private long lastUpdate;    private boolean closed;    private File localFile;    private UpLoadInfo info;    public ProgressInputStream(InputStream inputStream,File localFile, UpLoadInfo info) {        this.inputStream = inputStream;        this.progress = 0;        this.lastUpdate = 0;        this.localFile = localFile;        this.info = info;        this.closed = false;    }    @Override    public int read() throws IOException {        LogUtils.i("read()");        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 {        if (closed) {            super.close();            throw new IOException("already closed");        }        closed = true;    }    private int incrementCounterAndUpdateDisplay(int count) {        if (count > 0)            progress += count;        lastUpdate = maybeUpdateDisplay(progress, lastUpdate);        if (info.state == FTPManager.STATE_PAUSEUPLOAD||info.state == FTPManager.STATE_UNUPLOAD) {//如果是暂停下载(或者未下载)的话就直接返回-1,停掉while循环            return -1;        } else {            return count;        }    }    private long maybeUpdateDisplay(long progress, long lastUpdate) {        if (progress - lastUpdate > TEN_KILOBYTES) {            lastUpdate = progress;            if(FTPManager.getInstance().getObserver()!=null){                info.setProgress(progress);                info.setMax(localFile.length());                info.setState(FTPManager.STATE_PROGRESSING);                FTPManager.getInstance().notifyObservers(this.info);            }        }        return lastUpdate;    }}



0 0
原创粉丝点击