简介:

  要想从本地上传文件到远程服务器,必须要在远程服务器上搭建FTP服务器(要现在远程服务器上安装虚拟机,比如Windows Server 2008 R2等等),

然后提供FTP服务器的IP地址、端口号、用户名、密码等信息,在系统中调用Java程序,将本地文件通过FTP上传到远程服务器

  下面是在本地计算机上搭建FTP服务器(也是在本机上搭建,这里没有服务器,所以只是用于模拟远程服务器)以及简单地从本地传输文件到服务器。

 

搭建FTP服务器:
  ======================= 如果使用的是本机的用户就可以省略【下面】的步骤 =======================

  一、首先我们创建一个用户账户用于登录FTP进行操作。右键我的电脑-->管理-->本地用户和组-->用户,我们可以看到已经创建好的用户列表

  

将文件上传hadoop 将文件上传到ftp服务器_远程服务器

  然后右键用户选项,在下拉菜单中选择新用户,开始建立我们的用户,填写用户名称以及密码。描述可以不填。然后点击创建。创建完成在右边的用户列表中就可以看到我们创建的用户了。

   

将文件上传hadoop 将文件上传到ftp服务器_将文件上传hadoop_02

======================= 如果使用的是本机的用户就可以省略【上面】的步骤 =======================

  二、创建用户完成后我们开始添加IIS程序服务。打开电脑的【开始】菜单找到【控制面板】选项,打开进入,找到【程序】,进入到程序和功能选项栏目,我们可以看到左上方的菜单栏中有一个打开或关闭Windows功能选项,点击进入:

  

将文件上传hadoop 将文件上传到ftp服务器_上传_03

  进入到打开或关闭Windows功能界面,我们在好到Internet信息服务,然后点击打开在FTP服务器前面打勾,也就是把其子菜单的FTP服务和FTP扩展性打勾,然后点击下方的确定按钮。【备注:如果这里失败了,那么请看路径“c:\windows\system32\inetsrv”确认‘inetsrv’文件夹里是否有‘iis.msc’文件。如果没有,说明IIS相关的windows功能未启用。】

  

将文件上传hadoop 将文件上传到ftp服务器_远程服务器_04

  添加完成 IIS服务之后,开始创建我们的FTP站点,右键点击我的电脑选择管理,然后找到服务和应用程序选项点击打开,接着点击Internet信息服务管理--此时我们可以看到右边出现了一个连接框。

  

将文件上传hadoop 将文件上传到ftp服务器_服务器_05

三、添加站点。

  右键【网站】-->【添加FTP站点】

  

将文件上传hadoop 将文件上传到ftp服务器_上传_06

  

将文件上传hadoop 将文件上传到ftp服务器_将文件上传hadoop_07

下一步,输入本地IP地址【同理, 如果是远程服务器,那么就输入远程服务器的IP地址,端口号默认为21,可修改】,SSL下选中“允许”,

  

将文件上传hadoop 将文件上传到ftp服务器_服务器_08

下一步,按照需要设置好,点【完成】

  

将文件上传hadoop 将文件上传到ftp服务器_远程服务器_09

回到下面的页面,右键刷新,就可以看到新创建的站点,注意:这个站点是隶属于ZNZZ040(JG\zoumingqiao)这个用户下面的

   

将文件上传hadoop 将文件上传到ftp服务器_上传_10

四、测试:

  如果站点没有启动,则右键WebFTP站点-->【管理FTP站点】-->【启动】,打开DOS窗口,输入netstat -an,回车,看到21端口正在运行:

  

将文件上传hadoop 将文件上传到ftp服务器_上传_11

  说明站点成功运行,可以进行文件传输了,

  初步测试:

  拷贝本地文件到上面步骤中设置的FTP的物理路径E:\FTPLocalDirectory下(这个路径相当于远程服务器的存放文件的目录),

然后在浏览器的地址栏中输入:ftp://本机(远程服务器)地址IP/,回车,就会看到FTP服务器的目录下有上传的文件,说明FTP服务器搭建成功!

  

将文件上传hadoop 将文件上传到ftp服务器_上传_12

====================================================================

五、下面是使用JAVA代码上传本地文件到FTP服务器的物理目录[此方法是获取到客户端要上传文件的全路径的情况下才能用]

如果不能获取到这个全路径,就使用:

  1、 创建class类:FTPUtils.java

package com.wangzhixuan.commons.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
 * 使用FTP进行文件传输
 * @author zoumingqiao
 */
public class FTPUtils {
	// 这是日志记录
	private static final Logger logger = Logger.getLogger(FTPUtils.class);  
	
    //private static String encoding = System.getProperty("file.encoding"); 
    private static String encoding = "UTF-8"; 	// 这里要从配置文件读进来
    
    // FTPClient对象,操作FTP服务器和上传文件的对象,在下面的方法中会被初始化
    private FTPClient client;  
    
    // FTP服务器地址
    private String host;  
    // FTP端口号 默认21
    private int port;  
    // FTP服务器用户名
    private String username;  
    // FTP服务器密码
    private String password;  
    // FTP远程目录
    private String remoteDir;  
    // 本地存储目录
    private String localDir;  
    // 文件路径通配符 默认列出所有
    private String regEx = "*";  
    // 指定要下载的文件名
    private String downloadFileName;  
    
    /**
     * 设置连接属性
     * @param host			FTP服务器地址
     * @param username		FTP服务器用户名
     * @param password		FTP服务器密码
     * @return
     */
    public FTPUtils setConfig(String host, String username, String password) {  
        this.host = host;  
        this.username = username;  
        this.password = password;  
        return this;  
    }  
    
    /**
     * 设置连接属性 
     * @param host			FTP服务器地址
     * @param port			FTP端口号默认21
     * @param username		FTP服务器用户名
     * @param password		FTP服务器密码
     * @return
     */
    public FTPUtils setConfig(String host, int port, String username, String password) {  
        this.host = host;  
        this.port = port;  
        this.username = username;  
        this.password = password;  
        return this;  
    }  
    
    /** 
     * 连接FTP服务器 
     */  
    public FTPUtils connectServer() {  
    	// 创建一个FPTClient对象
        client = new FTPClient();  
        // 设置超时时间  
        client.setConnectTimeout(30000);  
        try {  
            // 1. 连接服务器  
            if(!client.isConnected()){  
                // 如果采用默认端口,可以使用client.connect(host)的方式直接连接FTP服务器  
                client.connect(host, port);  
                // 登录  
                client.login(username, password);  
                // 获取FTP登录应答码  
                int reply = client.getReplyCode();  
                // 验证是否登陆成功  
                if (!FTPReply.isPositiveCompletion(reply)) {  
                    logger.info("未连接到FTP,用户名或密码错误。");  
                    client.disconnect();  
                    throw new RuntimeException("未连接到FTP,用户名或密码错误。");  
                } else {  
                    logger.info("FTP连接成功。IP:"+host +"PORT:" +port);  
                }  
                // 2. 设置连接属性  
                client.setControlEncoding(encoding);  
                // 设置以二进制方式传输  
                client.setFileType(FTPClient.BINARY_FILE_TYPE);    
                client.enterLocalPassiveMode();  
            }  
        } catch (SocketException e) {  
            try {  
                client.disconnect();  
            } catch (IOException e1) {  
            }  
            logger.error("连接FTP服务器失败" + e.getMessage());  
            throw new RuntimeException("连接FTP服务器失败" + e.getMessage());  
        } catch (IOException e) {  
        }  
        return this;  
    }  
    
    /** 
     * 上传文件 
     * @param files 	要上传的文件List集合
     */  
    public void upload(List<File> files){  
          
        OutputStream os = null;  
        try {  
            // 2. 取本地文件  
            if(files == null || files.size()==0) {  
                logger.warn("文件数为0,没有找到可上传的文件");  
                return;  
            }  
            logger.info("准备上传" + files.size() + "个文件");  
            // 3. 上传到FTP服务器  
            for(File file : files){  
                this.connectServer();  
                // 1、设置远程FTP目录  
                client.changeWorkingDirectory(remoteDir);  
                logger.info("切换至工作目录【" + remoteDir + "】");  
                os = client.storeFileStream(file.getName());  
                if(os== null) throw new RuntimeException("上传失败,请检查是否有上传权限");  
                IOUtils.copy(new FileInputStream(file), os);  
                IOUtils.closeQuietly(os);  
            }  
            logger.info("文件上传成功,上传文件路径:" + remoteDir);  
        } catch (IOException e) {  
            logger.error("上传文件失败" + e.getMessage());  
            throw new RuntimeException("上传文件失败" + e.getMessage());  
        }  
    }  
    
    /**
     * 获取文件输出流
     * @param fileName	文件名
     * @return
     */
    public OutputStream getOutputStream(String fileName){  
        OutputStream os = null;  
        this.connectServer();  
        // 1. 设置远程FTP目录  
        try {  
            client.changeWorkingDirectory(remoteDir);  
            logger.info("切换至工作目录【" + remoteDir + "】");  
            os = client.storeFileStream(fileName);  
            if(os== null) throw new RuntimeException("服务器上创建文件对象失败");  
            return os;  
        } catch (IOException e) {  
            logger.error("服务器上创建文件对象失败" + e.getMessage());  
            throw new RuntimeException("服务器上创建文件对象失败" + e.getMessage());  
        }  
    }  
    /** 
     * 上传文件 
     * @param files 		上传的文件的List集合
     * @param remoteDir 	远程FTP目录
     */  
    public void upload(List<File> files,String remoteDir){  
        this.remoteDir = remoteDir;  
        this.upload(files);  
    }  
      
    /** 
     * 上传文件 
     * @param file 文件对象
     */  
    public void upload(File file){  
        List<File> files = new ArrayList<File>();  
        files.add(file);  
        upload(files);  
    } 
    
    /** 
     * 判断文件在FTP上是否存在 
     * @param fileName 		文件名
     * @return 
     */  
    public boolean isFileExist(String fileName) {  
          
        boolean result = false;  
        this.connectServer();  
        try {  
            // 1.设置远程FTP目录  
            client.changeWorkingDirectory(remoteDir);  
            logger.info("切换至工作目录【" + remoteDir + "】");  
            // 2.读取远程文件  
            FTPFile[] ftpFiles = client.listFiles(regEx);  
            if(ftpFiles.length==0) {  
                logger.warn("文件数为0,没有可下载的文件!");  
                return result;  
            }  
            // 3.检查文件是否存在  
            for (FTPFile file : ftpFiles) {  
                if(file.getName().equals(fileName)){  
                    result = true;  
                    break;  
                }  
            }  
        } catch (Exception e) {  
            logger.error("检查文件是否存在失败" + e.getMessage());  
            throw new RuntimeException("检查文件是否存在失败" + e.getMessage());  
        }  
          
        return result;  
    }  
    
    /* ============================= 文件下载 ========================================
    // 下载文件   
    public List<File> download(){  
          
        List<File> files = null;  
          
        this.connectServer();  
        InputStream is = null;  
        File downloadFile = null;  
        try {  
            // 1、设置远程FTP目录  
            client.changeWorkingDirectory(remoteDir);  
            logger.info("切换至工作目录【" + remoteDir + "】");  
            // 2、读取远程文件  
            FTPFile[] ftpFiles = client.listFiles(regEx);  
            if(ftpFiles.length==0) {  
                logger.warn("文件数为0,没有可下载的文件!");  
                return null;  
            }  
            logger.info("准备下载" + ftpFiles.length + "个文件");  
            // 3、保存文件到本地  
            for (FTPFile file : ftpFiles) {  
                //如果有指定下载的文件  
                if(StringUtils.isNotBlank(downloadFileName) && !file.getName().equals(downloadFileName)){  
                    continue;  
                }  
                if(files == null) files = new ArrayList<File>();  
                is = client.retrieveFileStream(file.getName());  
                if(is==null) throw new RuntimeException("下载失败,检查文件是否存在");  
                downloadFile = new File(localDir + file.getName());  
                FileOutputStream fos = FileUtils.openOutputStream(downloadFile);  
                IOUtils.copy(is, fos);  
                client.completePendingCommand();  
                IOUtils.closeQuietly(is);  
                IOUtils.closeQuietly(fos);  
                  
                //另外一种方式,供参考 
                //OutputStream is = new FileOutputStream(localFile); 
                //ftpClient.retrieveFile(ff.getName(), is); 
                //is.close(); 
                  
                files.add(downloadFile);  
            }  
            logger.info("文件下载成功,下载文件路径:" + localDir);  
            return files;  
        } catch (IOException e) {  
            logger.error("下载文件失败" + e.getMessage());  
            throw new RuntimeException("下载文件失败" + e.getMessage());  
        }  
    }  
      
    // 下载文件  
    public List<File> download(String remoteDir,String localDir){  
        this.remoteDir = remoteDir;  
        this.localDir = localDir;  
        return this.download();  
    }  
   
	// 下载文件 
	// @param remoteDir 
	// @param regEx 文件通配符 
	// @param localDir 
	// @return 
    public List<File> download(String remoteDir,String regEx,String localDir){  
        this.remoteDir = remoteDir;  
        this.localDir = localDir;  
        this.regEx = regEx;  
        return this.download();  
    }  
      
	// 下载文件 
	// @param downloadFileName 指定要下载的文件名称 
	// @return 
    public List<File> download(String downloadFileName){  
        this.downloadFileName = downloadFileName;  
        return this.download();  
    } 
    * ============================= 文件下载 ========================================
    */
  
     /** 
     * 关闭连接 
     */  
    public void closeConnect() {  
        try {  
            client.disconnect();  
            logger.info(" 关闭FTP连接!!! ");  
        } catch (IOException e) {  
            logger.warn(" 关闭FTP连接失败!!! ",e);  
        }  
    }  
    public String getRemoteDir() {  
        return remoteDir;  
    }  
  
    public void setRemoteDir(String remoteDir) {  
        this.remoteDir = remoteDir;  
    }  
  
    public String getLocalPath() {  
        return localDir;  
    }  
  
    public void setLocalPath(String localPath) {  
        this.localDir = localPath;  
    }  
  
    public String getDownloadFileName() {  
        return downloadFileName;  
    }  
  
    public void setDownloadFileName(String downloadFileName) {  
        this.downloadFileName = downloadFileName;  
    }  
      
    @Override  
    public String toString() {  
        return "FTPUtil [host=" + host + ", port=" + port + ", username="  
                + username + ", password=" + password + "]";  
    }  
}

2、创建一个测试类:FTPUtilsTest.java

package com.zmq.test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.wangzhixuan.commons.utils.FTPUtils;

public class FTPUtilsTest {

	/**
	 * FTPUtils工具类测试
	 * @param args
	 */
	public static void main(String[] args) {
		FTPUtils ftpUtils = new FTPUtils();
          // FTP的用户名/密码:如果是本地,那就是本机的创建FTP站点的对应的用户的用户名和密码
		ftpUtils.setConfig("FTP服务器的IP地址", 端口号, "FTP的用户名", "FTP的密码");
		ftpUtils.connectServer();
		List<File> fileList = new ArrayList<File>();
		File file1 = new File("F:\\testDirectory\\pic1.jpg");
		File file2 = new File("F:\\testDirectory\\pic2.jpg");
		File file3 = new File("F:\\testDirectory\\pic3.jpg");
		fileList.add(file1);
		fileList.add(file2);
		fileList.add(file3);
		ftpUtils.upload(fileList);
	}

}

3、运行测试:

后台打印:因为没有设置FTP服务器的存放文件的目录,所以这里打印null,可以看到上传成功!

2017-06-01 15:59:22,744 INFO  [FTPUtils.java:99] : FTP连接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,746 INFO  [FTPUtils.java:132] : 准备上传3个文件
2017-06-01 15:59:22,749 INFO  [FTPUtils.java:99] : FTP连接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,749 INFO  [FTPUtils.java:138] : 切换至工作目录【null】
2017-06-01 15:59:22,754 INFO  [FTPUtils.java:99] : FTP连接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,756 INFO  [FTPUtils.java:138] : 切换至工作目录【null】
2017-06-01 15:59:22,759 INFO  [FTPUtils.java:99] : FTP连接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,761 INFO  [FTPUtils.java:138] : 切换至工作目录【null】
2017-06-01 15:59:22,854 INFO  [FTPUtils.java:144] : 文件上传成功,上传文件路径:null

 查看FTP的物理路径,多了一些文件:

  

将文件上传hadoop 将文件上传到ftp服务器_将文件上传hadoop_13

  

将文件上传hadoop 将文件上传到ftp服务器_上传_14

===================================================================

至此,FTP服务器搭建成功,可以进行其他的操作了【比如在jsp页面上传文件,访问action,调用工具类进行处理】