我爱编程

FTP协议实现上传和下载

2018-06-21  本文已影响161人  Showdy

FTP协议上传下载

tags: java

简介

FTPFile Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)。"下载"文件就是从远程主机拷贝文件至自己的计算机上;"上传"文件就是将文件从自己的计算机中拷贝至远程主机上.

FTP的传输方式有两种: ASCII传输方式和二进制传输方式

FTP支持两种模式: Standard(PORT主动方式)和Passive(PSV被动方式)

Apache Commons Net来下载文件的API

org.apache.commons.net.ftp.FTPClient类提供两个方法来从FTP服务器下载文件:

那么该选择何种方法来下载了?

此外, 当使用retrieveFile() and retrieveFileStream()方法时,下面的两个方法必须要调用:

下载单文件的步骤

代码示例:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
 
/**
 * A program demonstrates how to upload files from local computer to a remote
 * FTP server using Apache Commons Net API.
 * @author www.codejava.net
 */
public class FTPDownloadFileDemo {

    public static void main(String[] args) {
        String server = "www.myserver.com";
        int port = 21;
        String user = "user";
        String pass = "pass";
 
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 
            // APPROACH #1: using retrieveFile(String, OutputStream)
            String remoteFile1 = "/test/video.mp4";
            File downloadFile1 = new File("D:/Downloads/video.mp4");
            OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
            boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
            outputStream1.close();
 
            if (success) {
                System.out.println("File #1 has been downloaded successfully.");
            }
 
            // APPROACH #2: using InputStream retrieveFileStream(String)
            String remoteFile2 = "/test/song.mp3";
            File downloadFile2 = new File("D:/Downloads/song.mp3");
            OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
            InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
            byte[] bytesArray = new byte[4096];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(bytesArray)) != -1) {
                outputStream2.write(bytesArray, 0, bytesRead);
            }
 
            success = ftpClient.completePendingCommand();
            if (success) {
                System.out.println("File #2 has been downloaded successfully.");
            }
            outputStream2.close();
            inputStream.close();
 
        } catch (IOException ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

FTP上传

Apache Commons Net提供上传的方式为

代码示例:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
 
/**
 * A program that demonstrates how to upload files from local computer
 * to a remote FTP server using Apache Commons Net API.
 * @author www.codejava.net
 */
public class FTPUploadFileDemo {
 
    public static void main(String[] args) {
        String server = "www.myserver.com";
        int port = 21;
        String user = "user";
        String pass = "pass";
 
        FTPClient ftpClient = new FTPClient();
        try {
 
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
            ftpClient.enterLocalPassiveMode();
 
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
 
            // APPROACH #1: uploads first file using an InputStream
            File firstLocalFile = new File("D:/Test/Projects.zip");
 
            String firstRemoteFile = "Projects.zip";
            InputStream inputStream = new FileInputStream(firstLocalFile);
 
            System.out.println("Start uploading first file");
            boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
            inputStream.close();
            if (done) {
                System.out.println("The first file is uploaded successfully.");
            }
 
            // APPROACH #2: uploads second file using an OutputStream
            File secondLocalFile = new File("E:/Test/Report.doc");
            String secondRemoteFile = "test/Report.doc";
            inputStream = new FileInputStream(secondLocalFile);
 
            System.out.println("Start uploading second file");
            OutputStream outputStream = ftpClient.storeFileStream(secondRemoteFile);
            byte[] bytesIn = new byte[4096];
            int read = 0;
 
            while ((read = inputStream.read(bytesIn)) != -1) {
                outputStream.write(bytesIn, 0, read);
            }
            inputStream.close();
            outputStream.close();
 
            boolean completed = ftpClient.completePendingCommand();
            if (completed) {
                System.out.println("The second file is uploaded successfully.");
            }
 
        } catch (IOException ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
 }

文件夹上传

FTP文件夹上传,简单点说,就如同拷贝一个文件夹一样,首先利用递归遍历文件夹目录, 然后再服务器上创建相应目录的文件夹,然后将文件一个一个上传.具体步骤

代码示例

/**
 * Upload a whole directory (including its nested sub directories and files)
 * to a FTP server.
 *
 * @param ftpClient
 *            an instance of org.apache.commons.net.ftp.FTPClient class.
 * @param remoteDirPath
 *            Path of the destination directory on the server.
 * @param localParentDir
 *            Path of the local directory being uploaded.
 * @param remoteParentDir
 *            Path of the parent directory of the current directory on the
 *            server (used by recursive calls).
 * @throws IOException
 *             if any network or IO error occurred.
 */
public static void uploadDirectory(FTPClient ftpClient,
        String remoteDirPath, String localParentDir, String remoteParentDir)
        throws IOException {
 
    System.out.println("LISTING directory: " + localParentDir);
 
    File localDir = new File(localParentDir);
    File[] subFiles = localDir.listFiles();
    if (subFiles != null && subFiles.length > 0) {
        for (File item : subFiles) {
            String remoteFilePath = remoteDirPath + "/" + remoteParentDir
                    + "/" + item.getName();
            if (remoteParentDir.equals("")) {
                remoteFilePath = remoteDirPath + "/" + item.getName();
            }
 
 
            if (item.isFile()) {
                // upload the file
                String localFilePath = item.getAbsolutePath();
                System.out.println("About to upload the file: " + localFilePath);
                boolean uploaded = uploadSingleFile(ftpClient,
                        localFilePath, remoteFilePath);
                if (uploaded) {
                    System.out.println("UPLOADED a file to: "
                            + remoteFilePath);
                } else {
                    System.out.println("COULD NOT upload the file: "
                            + localFilePath);
                }
            } else {
                // create directory on the server
                boolean created = ftpClient.makeDirectory(remoteFilePath);
                if (created) {
                    System.out.println("CREATED the directory: "
                            + remoteFilePath);
                } else {
                    System.out.println("COULD NOT create the directory: "
                            + remoteFilePath);
                }
 
                // upload the sub directory
                String parent = remoteParentDir + "/" + item.getName();
                if (remoteParentDir.equals("")) {
                    parent = item.getName();
                }
 
                localParentDir = item.getAbsolutePath();
                uploadDirectory(ftpClient, remoteDirPath, localParentDir,
                        parent);
            }
        }
    }
}

/**
 * Upload a single file to the FTP server.
 *
 * @param ftpClient
 *            an instance of org.apache.commons.net.ftp.FTPClient class.
 * @param localFilePath
 *            Path of the file on local computer
 * @param remoteFilePath
 *            Path of the file on remote the server
 * @return true if the file was uploaded successfully, false otherwise
 * @throws IOException
 *             if any network or IO error occurred.
 */
public static boolean uploadSingleFile(FTPClient ftpClient,
        String localFilePath, String remoteFilePath) throws IOException {
    File localFile = new File(localFilePath);
 
    InputStream inputStream = new FileInputStream(localFile);
    try {
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        return ftpClient.storeFile(remoteFilePath, inputStream);
    } finally {
        inputStream.close();
    }
}

import java.io.IOException;
 
import org.apache.commons.net.ftp.FTPClient;
 
/**
 * This test program illustrates how to utilize the FTPUtil class in order
 * to upload a whole directory to a FTP server.
 * @author www.codejava.net
 *
 */
public class FTPUploadDirectoryTest {
 
    public static void main(String[] args) {
        String server = "www.codejava.net";
        int port = 21;
        String user = "username";
        String pass = "password";
 
        FTPClient ftpClient = new FTPClient();
 
        try {
            // connect and login to the server
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
 
            // use local passive mode to pass firewall
            ftpClient.enterLocalPassiveMode();
 
            System.out.println("Connected");
 
            String remoteDirPath = "/Upload";
            String localDirPath = "E:/Test/Download/FTP/Test";
 
            FTPUtil.uploadDirectory(ftpClient, remoteDirPath, localDirPath, "");
 
            // log out and disconnect from the server
            ftpClient.logout();
            ftpClient.disconnect();
 
            System.out.println("Disconnected");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

FTP下载文件夹

/**
 * Download a single file from the FTP server
 * @param ftpClient an instance of org.apache.commons.net.ftp.FTPClient class.
 * @param remoteFilePath path of the file on the server
 * @param savePath path of directory where the file will be stored
 * @return true if the file was downloaded successfully, false otherwise
 * @throws IOException if any network or IO error occurred.
 */
public static boolean downloadSingleFile(FTPClient ftpClient,
        String remoteFilePath, String savePath) throws IOException {
    File downloadFile = new File(savePath);
     
    File parentDir = downloadFile.getParentFile();
    if (!parentDir.exists()) {
        parentDir.mkdir();
    }
         
    OutputStream outputStream = new BufferedOutputStream(
            new FileOutputStream(downloadFile));
    try {
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        return ftpClient.retrieveFile(remoteFilePath, outputStream);
    } catch (IOException ex) {
        throw ex;
    } finally {
        if (outputStream != null) {
            outputStream.close();
        }
    }
}

/**
 * Download a whole directory from a FTP server.
 * @param ftpClient an instance of org.apache.commons.net.ftp.FTPClient class.
 * @param parentDir Path of the parent directory of the current directory being
 * downloaded.
 * @param currentDir Path of the current directory being downloaded.
 * @param saveDir path of directory where the whole remote directory will be
 * downloaded and saved.
 * @throws IOException if any network or IO error occurred.
 */
public static void downloadDirectory(FTPClient ftpClient, String parentDir,
        String currentDir, String saveDir) throws IOException {
    String dirToList = parentDir;
    if (!currentDir.equals("")) {
        dirToList += "/" + currentDir;
    }
 
    FTPFile[] subFiles = ftpClient.listFiles(dirToList);
 
    if (subFiles != null && subFiles.length > 0) {
        for (FTPFile aFile : subFiles) {
            String currentFileName = aFile.getName();
            if (currentFileName.equals(".") || currentFileName.equals("..")) {
                // skip parent directory and the directory itself
                continue;
            }
            String filePath = parentDir + "/" + currentDir + "/"
                    + currentFileName;
            if (currentDir.equals("")) {
                filePath = parentDir + "/" + currentFileName;
            }
 
            String newDirPath = saveDir + parentDir + File.separator
                    + currentDir + File.separator + currentFileName;
            if (currentDir.equals("")) {
                newDirPath = saveDir + parentDir + File.separator
                          + currentFileName;
            }
 
            if (aFile.isDirectory()) {
                // create the directory in saveDir
                File newDir = new File(newDirPath);
                boolean created = newDir.mkdirs();
                if (created) {
                    System.out.println("CREATED the directory: " + newDirPath);
                } else {
                    System.out.println("COULD NOT create the directory: " + newDirPath);
                }
 
                // download the sub directory
                downloadDirectory(ftpClient, dirToList, currentFileName,
                        saveDir);
            } else {
                // download the file
                boolean success = downloadSingleFile(ftpClient, filePath,
                        newDirPath);
                if (success) {
                    System.out.println("DOWNLOADED the file: " + filePath);
                } else {
                    System.out.println("COULD NOT download the file: "
                            + filePath);
                }
            }
        }
    }
}

import java.io.IOException;
 
import org.apache.commons.net.ftp.FTPClient;
 
public class FTPDownloadDirectoryTest {
 
    public static void main(String[] args) {
        String server = "www.codejava.net";
        int port = 21;
        String user = "username";
        String pass = "password";
 
        FTPClient ftpClient = new FTPClient();
 
        try {
            // connect and login to the server
            ftpClient.connect(server, port);
            ftpClient.login(user, pass);
 
            // use local passive mode to pass firewall
            ftpClient.enterLocalPassiveMode();
 
            System.out.println("Connected");
 
            String remoteDirPath = "/Test";
            String saveDirPath = "E:/Test/Download/FTP";
 
            FTPUtil.downloadDirectory(ftpClient, remoteDirPath, "", saveDirPath);
 
            // log out and disconnect from the server
            ftpClient.logout();
            ftpClient.disconnect();
 
            System.out.println("Disconnected");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读