linux 配置ftp服务

需求:定时远程上传文件,windows->linux

linux是一个云服务器,centos7

1:安装vsftpd

yum install vsftpd

2:设置开机启动服务
chkconfig vsftpd on

3:启动服务 
 service vsftpd start

4:防火墙端口打开

打开/etc/sysconfig/iptables文件

vi /etc/sysconfig/iptables

在REJECT行之前添加如下代码

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

保存和关闭文件,重启防火墙

service iptables restart

5:配置vsftpd 服务器

vi /etc/vsftpd/vsftpd.conf

将匿名登录关闭 anonymous_enable=NO

chroot_list_enable=YES //限制访问自身目录
# (default follows)
chroot_list_file=/etc/vsftpd/vsftpd.chroot_list

编辑 vsftpd.chroot_list文件,将受限制的用户添加进去,每个用户名一行,(但实际上加了这个会很麻烦,所以没加),比如出现 500 OOPS: vsftpd: refusing to run with writable root inside chroot() 

参考这个link:https://zhidao.baidu.com/question/1732079113433285347.html

6:添加ftp用户

useradd -d /home/test test

passwd oneuser

如果加错了,可以删掉这个用户

userdel test

7:修改文件夹所有者

chown test /home/test -R

如果还是不好使,改一下权限

chmod -R 777 /home/test

8:最后,别忘了重启服务

service vsftpd restart

9:查看用户默认路径:  cat /etc/passwd  

通过java的FTPClient去连接时会出现各种错误,首先,用户名和密码,端口别搞错了,FTPClient的jar包可以选最高的版本

网上有FTPutil的代码,我也是拿来主义了,但是发现有bug,下面是自己测试过的代码,传单个文件,如果要传文件夹的话也很简单。

补充:如果出现下载文件ftpClient.listFiles()为null的错误,用以下方法解决

执行ftpClient.listFiles()前加上一句:

ftpClient.enterLocalPassiveMode();

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 java.net.MalformedURLException;
 
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;


public class FtpUtils {
        //ftp服务器地址
        public String hostname = "XXXX";
        //ftp服务器端口号默认为21
        public Integer port = 21 ;
        //ftp登录账号
        public String username = "XXX";
        //ftp登录密码
        public String password = "XXX";
        
        public FTPClient ftpClient = null;
        
        /**
         * 初始化ftp服务器
         */
        public void initFtpClient() {
            ftpClient = new FTPClient();
            ftpClient.setControlEncoding("utf-8");
            try {
                System.out.println("connecting...ftp服务器:"+this.hostname+":"+this.port); 
                ftpClient.connect(hostname, port); //连接ftp服务器
                ftpClient.login(username, password); //登录ftp服务器
                int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
                if(!FTPReply.isPositiveCompletion(replyCode)){
                    System.out.println("connect failed...ftp服务器:"+this.hostname+":"+this.port); 
                }else{
                    System.out.println("connect successfu...ftp服务器:"+this.hostname+":"+this.port);    
                }
                 
            }catch (MalformedURLException e) { 
               e.printStackTrace(); 
            }catch (IOException e) { 
               e.printStackTrace(); 
            } 
        }

        /**
        * 上传文件
        * @param pathname ftp服务保存地址
        * @param fileName 上传到ftp的文件名
        *  @param originfilename 待上传文件的名称(绝对地址) * 
        * @return
        */
        public boolean uploadFile( String pathname, String fileName,String originfilename){
            boolean flag = false;
            InputStream inputStream = null;
            try{
                System.out.println("开始上传文件");
                inputStream = new FileInputStream(new File(originfilename));
                initFtpClient();
                ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
                ftpClient.setDataTimeout(60000);       //设置传输超时时间为60秒 
                ftpClient.setConnectTimeout(60000);       //连接超时为60秒
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                flag = true;
                System.out.println("上传文件成功");
            }catch (Exception e) {
                System.out.println("上传文件失败");
                e.printStackTrace();
            }finally{
                if(ftpClient.isConnected()){ 
                    try{
                        ftpClient.disconnect();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                } 
                if(null != inputStream){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                } 
            }
            return true;
        }
        /**
         * 上传文件
         * @param pathname ftp服务保存地址
         * @param fileName 上传到ftp的文件名
         * @param inputStream 输入文件流 
         * @return
         */
        public boolean uploadFile( String pathname, String fileName,InputStream inputStream){
            boolean flag = false;
            try{
                System.out.println("开始上传文件");
                initFtpClient();
                ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
                CreateDirecroty(pathname);
                ftpClient.makeDirectory(pathname);
                ftpClient.changeWorkingDirectory(pathname);
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                flag = true;
                System.out.println("上传文件成功");
            }catch (Exception e) {
                System.out.println("上传文件失败");
                e.printStackTrace();
            }finally{
                if(ftpClient.isConnected()){ 
                    try{
                        ftpClient.disconnect();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                } 
                if(null != inputStream){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                } 
            }
            return true;
        }
        //改变目录路径
         public boolean changeWorkingDirectory(String directory) {
                boolean flag = true;
                try {
                    flag = ftpClient.changeWorkingDirectory(directory);
                    if (flag) {
                      System.out.println("进入文件夹" + directory + " 成功!");

                    } else {
                        System.out.println("进入文件夹" + directory + " 失败!开始创建文件夹");
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
                return flag;
            }

        //创建多层目录文件,如果有ftp服务器已存在该文件,则不创建,如果无,则创建
        public boolean CreateDirecroty(String remote) throws IOException {
            boolean success = true;
            String directory = remote + "/";
            // 如果远程目录不存在,则递归创建远程服务器目录
            if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
                int start = 0;
                int end = 0;
                if (directory.startsWith("/")) {
                    start = 1;
                } else {
                    start = 0;
                }
                end = directory.indexOf("/", start);
                String path = "";
                String paths = "";
                while (true) {
                    String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                    path = path + "/" + subDirectory;
                    if (!existFile(path)) {
                        if (makeDirectory(subDirectory)) {
                            changeWorkingDirectory(subDirectory);
                        } else {
                            System.out.println("创建目录[" + subDirectory + "]失败");
                            changeWorkingDirectory(subDirectory);
                        }
                    } else {
                        changeWorkingDirectory(subDirectory);
                    }

                    paths = paths + "/" + subDirectory;
                    start = end + 1;
                    end = directory.indexOf("/", start);
                    // 检查所有目录是否创建完毕
                    if (end <= start) {
                        break;
                    }
                }
            }
            return success;
        }

      //判断ftp服务器文件是否存在    
        public boolean existFile(String path) throws IOException {
                boolean flag = false;
                FTPFile[] ftpFileArr = ftpClient.listFiles(path);
                if (ftpFileArr.length > 0) {
                    flag = true;
                }
                return flag;
            }
        //创建目录
        public boolean makeDirectory(String dir) {
            boolean flag = true;
            try {
                flag = ftpClient.makeDirectory(dir);
                if (flag) {
                    System.out.println("创建文件夹" + dir + " 成功!");

                } else {
                    System.out.println("创建文件夹" + dir + " 失败!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
        }
        
        /** * 下载文件 * 
        * @param pathname FTP服务器文件目录 * 
        * @param filename 文件名称 * 
        * @param localpath 下载后的文件路径 * 
        * @return */
        public  boolean downloadFile(String pathname, String filename, String localpath){ 
            boolean flag = false; 
            OutputStream os=null;
            try { 
                System.out.println("开始下载文件");
                initFtpClient();
                //切换FTP目录 
                ftpClient.changeWorkingDirectory(pathname); 
                FTPFile[] ftpFiles = ftpClient.listFiles(); 
                for(FTPFile file : ftpFiles){ 
                    if(filename.equalsIgnoreCase(file.getName())){ 
                        File localFile = new File(localpath + "/" + file.getName()); 
                        os = new FileOutputStream(localFile); 
                        ftpClient.retrieveFile(file.getName(), os); 
                        os.close(); 
                    } 
                } 
                ftpClient.logout(); 
                flag = true; 
                System.out.println("下载文件成功");
            } catch (Exception e) { 
                System.out.println("下载文件失败");
                e.printStackTrace(); 
            } finally{ 
                if(ftpClient.isConnected()){ 
                    try{
                        ftpClient.disconnect();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                } 
                if(null != os){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                } 
            } 
            return flag; 
        }
        
        /** * 删除文件 * 
        * @param pathname FTP服务器保存目录 * 
        * @param filename 要删除的文件名称 * 
        * @return */ 
        public boolean deleteFile(String pathname, String filename){ 
            boolean flag = false; 
            try { 
                System.out.println("开始删除文件");
                initFtpClient();
                //切换FTP目录 
                ftpClient.changeWorkingDirectory(pathname); 
                ftpClient.dele(filename); 
                ftpClient.logout();
                flag = true; 
                System.out.println("删除文件成功");
            } catch (Exception e) { 
                System.out.println("删除文件失败");
                e.printStackTrace(); 
            } finally {
                if(ftpClient.isConnected()){ 
                    try{
                        ftpClient.disconnect();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                } 
            }
            return flag; 
        }
        
        public static void main(String[] args) {
            FtpUtils ftp =new FtpUtils(); 
            ftp.uploadFile("XXX", "XXX", "XXX");
            //ftp.downloadFile("ftpFile/data", "123.docx", "F://");
//            ftp.deleteFile("ftpFile/data", "123.docx");
            System.out.println("ok");
        }
}

 2019-4-28 update

添加了C#的版本,下面是核心的两个方法,注意,C#出了一个很诡异的问题(553) 不允许此文件名,原来是拼接linux路径的时候,不要把默认路径带进去!

 private void DownFile()
        {
            string FtpFilePath = ServerPath.Text.Trim();   //远程路径
            string LocalPath = downloadPath.Text.Trim()+"\\my.txt"; //下载到的本地路径
            if (File.Exists(LocalPath))
            {
                File.Delete(LocalPath);
            }
            string FTPPath = FTPAddress + FtpFilePath;
            //建立ftp连接
            FtpWebRequest reqFtp = (FtpWebRequest)FtpWebRequest.Create(new Uri(FTPPath));
            reqFtp.Method = WebRequestMethods.Ftp.DownloadFile;
            reqFtp.UseBinary = true;
            reqFtp.UsePassive = true;
            reqFtp.ReadWriteTimeout = 10000;
            reqFtp.KeepAlive = true;
            reqFtp.Credentials = new NetworkCredential(FTPUsername, FTPPwd);
            
            FtpWebResponse response = (FtpWebResponse)reqFtp.GetResponse();
            Stream ftpStream = response.GetResponseStream();
            long cl = response.ContentLength;
            int buffersize = 2048;
            int readCount;
            byte[] buffer = new byte[buffersize];
            readCount = ftpStream.Read(buffer, 0, buffersize);
            //创建并写入文件
            FileStream OutputStream = new FileStream(LocalPath, FileMode.Create);
            while (readCount > 0)
            {
                OutputStream.Write(buffer, 0, buffersize);
                readCount = ftpStream.Read(buffer, 0, buffersize);
            }
            ftpStream.Close();
            OutputStream.Close();
            response.Close();
            if (File.Exists(LocalPath)) {
                MessageBox.Show("download OK!");
            }
        }

private void UpFile()
        {
            string LocalPath = "D:\\test.txt"; //待上传文件
            FileInfo f = new FileInfo(LocalPath);
            string FileName = f.Name;
            string ftpRemotePath = "/";
            string FTPPath = FTPAddress + ftpRemotePath + FileName; //上传到ftp路径,如ftp://***.***.***.**:21/home/test/test.txt
            //实现文件传输协议 (FTP) 客户端
            FtpWebRequest reqFtp = (FtpWebRequest)FtpWebRequest.Create(new Uri(FTPPath));
            reqFtp.UseBinary = true;
            reqFtp.Credentials = new NetworkCredential(FTPUsername, FTPPwd); //设置通信凭据
            reqFtp.KeepAlive = false; //请求完成后关闭ftp连接
            reqFtp.Method = WebRequestMethods.Ftp.UploadFile;
            reqFtp.ContentLength = f.Length;
            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;
            //读本地文件数据并上传
            FileStream fs = f.OpenRead();
            try
            {
                Stream strm = reqFtp.GetRequestStream();
                contentLen = fs.Read(buff, 0, buffLength);
                while (contentLen != 0)
                {
                    strm.Write(buff, 0, contentLen);
                    contentLen = fs.Read(buff, 0, buffLength);
                }
                strm.Close();
                fs.Close();
                MessageBox.Show("upload OK!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("upload fail!");
            }
        }

 

posted @ 2019-04-23 23:11  谷子弟  阅读(510)  评论(0编辑  收藏  举报