需求:定时远程上传文件,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 = ;
reqFtp.KeepAlive = true;
reqFtp.Credentials = new NetworkCredential(FTPUsername, FTPPwd); FtpWebResponse response = (FtpWebResponse)reqFtp.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int buffersize = ;
int readCount;
byte[] buffer = new byte[buffersize];
readCount = ftpStream.Read(buffer, , buffersize);
//创建并写入文件
FileStream OutputStream = new FileStream(LocalPath, FileMode.Create);
while (readCount > )
{
OutputStream.Write(buffer, , buffersize);
readCount = ftpStream.Read(buffer, , 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 = ;
byte[] buff = new byte[buffLength];
int contentLen;
//读本地文件数据并上传
FileStream fs = f.OpenRead();
try
{
Stream strm = reqFtp.GetRequestStream();
contentLen = fs.Read(buff, , buffLength);
while (contentLen != )
{
strm.Write(buff, , contentLen);
contentLen = fs.Read(buff, , buffLength);
}
strm.Close();
fs.Close();
MessageBox.Show("upload OK!");
}
catch (Exception ex)
{
MessageBox.Show("upload fail!");
}
}

最新文章

  1. iOS绘制收益柱状图
  2. IplImage, CvMat, Mat 的关系和相互转换(转)
  3. django template
  4. MySQL高可用基础之keepalived+双主复制【转】
  5. nginx access log logrotate配置
  6. POJ 3307 Smart Sister
  7. ace_tree总结。各类问题解决办法汇集
  8. tomcat启动后产生的日志
  9. 实战Asp.Net Core:部署应用
  10. 面试官让你讲讲acks参数对消息持久化的影响
  11. 转:总结const、readonly、static三者的区别
  12. zw版【转发&#183;台湾nvp系列Delphi例程】HALCON SetComprise2
  13. hdu2069-2071
  14. Java子父类中的构造函数实例化过程
  15. window消息机制二
  16. 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
  17. HBase核心功能模块--读书笔记
  18. springCloud3---ribbon
  19. 查看ubuntu 各系统的内核版本
  20. Python一行代码搞定的事情

热门文章

  1. Python3.0科学计算学习之函数
  2. Docker入门详解(转载)
  3. UBUNTU安装 SSH 服务
  4. 在深谈TCP/IP三步握手&amp;四步挥手原理及衍生问题—长文解剖IP
  5. Javascript学习-简单测试环境
  6. Java输出流FileOutputStream使用详解
  7. JAVA课堂测试之查找字母和单词出现次数、频率
  8. jquery serializeArray()、serialize()增加数据
  9. Java笔记 #06# 自定义简易参数校验框架——EasyValidator
  10. windows eclipse直接访问远程linux hadoop开发环境配置(符合实际开发的做法)