CentOS6.5下搭建FTP服务器 + Java上传文件
来源:互联网 发布:算法书籍经典 编辑:程序博客网 时间:2024/05/16 11:49
项目中开始使用http协议进行传输文件,但是终端提出传输的字节超过限度,要使用FTP文件服务器进行断点续传,每次1k的进行传输. 老大让我在开发环境中搭建vsftp服务器,一起没操作过,现在记录下来留做以后的回顾学习;
vsftp简介
vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序。特点是小巧轻快,安全易用。ftp作为文件服务器,断点续传是和http传输的一个区别;
CentOS6.5安装vsftp
以管理员(root)身份进行一下操作:
1.检测是否安装了vsftp
[root@dev04 ~]# rpm -qa |grep vsftpdvsftpd-2.2.2-14.el6.x86_64我是安装过的, 命令下方返回的是我的vsftp版本
检测到安装过后如果想卸载执行:
rpm -e vsftpd再执行
rpm -qa |grep vsftpd
2.安装vsftp
yum install vsftpd* -y
3.设置开机自启vsftp ftp服务
chkconfig vsftpd on
4.启动ftp服务
[root@dev04 vsftpd]# service vsftpd start关闭服务:
[root@dev04 vsftpd]# service vsftpd stop重启服务:
[root@dev04 vsftpd]# service vsftpd restart
5.配置vsftp的配置文件vsftpd.conf
在 /etc/vsftpd目录下有三个文件和一个执行命令?-rw------- 1 root root 125 Jul 24 2015 ftpusers-rw------- 1 root root 371 Apr 6 14:11 user_list-rw------- 1 root root 4737 Apr 1 15:51 vsftpd.conf-rwxr--r-- 1 root root 338 Jul 24 2015 vsftpd_conf_migrate.sh
要修改的配置信息都在vsftpd.conf配置文件中,修改配置文件之前最好进行备份
[root@dev04 vsftpd]# cp vsftpd.conf vsftpd.conf.bak
再进行编辑修改配置文件
[root@dev04 vsftpd]# vim /etc/vsftpd/vsftpd.conf
主要的就是匿名用户的访问权限和 新增本地用户设置访问权限
因为要提供给终端使用FTP服务器映射的公网进行访问,又不行暴露服务器文件所在的目录,
必须支持匿名用户的访问, ftp匿名用户默认目录为 /var/ftp/pub目录下
vsftpd.conf配置文件主要修改
anonymous_enable=YES // 支持匿名登录,如果改为NO不支持匿名登录
write_enable=YES//支持读
anon_upload_enable=YES//支持匿名改写
anon_mkdir_write_enable=YES//支持匿名用户创建子目录
6.创建用户ftpuser,指定目录/home/ftpuser,禁止SSH登录权限
useradd -d /home/ftpuser -g ftp -s /sbin/nologin ftpuser给帐号设置密码
passwd ftpuer注意: 在设置密码时会提示什么密码过于简单,或者密码为单词词组等等,不用管,它已经进行设置了,要确认两次输入的密码都相同;输入两次密码后出现successful.....就代表设置密码成功了;
创建用户时遇到的问题:
1.我开始是关闭匿名用户的登录权限的,设置了ftpuser, 终端访问时必须要输入 ftp://username:password@IP地址:port/访问路径 这样会暴露文件存放的路径,不合理(我觉得可能是我设置ftpuser用户时没有在配置文件中配置默认目录什么的,因为按照前面这样访问时候默认进入默认目录/ftpuser的,这点没怎么清楚==)
2.项目中上传文件原本是使用fastDFS文件服务器的,现在改为FTP,将固件上传到匿名用户目录下,提供终端下载
新建了anon用户将默认目录设置为匿名访问的目录 /var/ftp/pub
useradd -d /var/ftp -g ftp -s /sbin/nologin anon在使用java进行上传文件时发现anon用户不能连接上该目录,查资料说是没有对目录进行设置权限
LINUX下搭建FTP服务器--非宁静无以致远
注意的事项是的:
1、pub目录的权限不能全开,全开会报错,chmod 755 -R pub
2、但是这样也会带来一个问题,当匿名用户登录后,在pub下的newftp目录下想上传一个文件,会报错,因为匿名用户(ftp)无法在该目录下(该目录属于root用户)创建一个新文件的,因为该目录下他没有权限,所以要加入其他用户(o)的写权限,chmod o+w /var/ftp/pub/.
现在权限变为:
drwxr-xrwx 2 root root 4096 06-20 16:55 pub
其实就是757的权限,此时匿名用户(ftp)就可以在该目录下上传文件了。
最后重启服务: service vsftpd restart
附上MultipartFile使用ftp上传文件
1.maven项目中添加pom文件
<!-- https://mvnrepository.com/artifact/commons-net/commons-net --><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.6</version></dependency>
2.ftp配置文件 ftp_client.properties
#公网IP映射地址: 218.205.115.XXX 2121
ftp_public_network_add = 218.205.115.XXX#FTP公网端口ftp_public_network_port = 2121#FTP服务器地址172.23.28.XXXftp_host = 172.23.28.XXX#21ftp_port = 21##匿名用户 anonymous 创建一个用户名为ftpuser,目录在pub下,具有增删改查/新建子目录权限ftp_user_name = ftpuserftp_user_pwd = ftpuser#匿名登录上传目录 /var/ftp/pubremoteFile_addr = /var/ftp/pub/
3.自定义配置文件的pojo类,提高代码扩展性
@Componentpublic class FTPConfig { /** FTP服务器IP地址 */ @Value("#{configProperties['ftp_host']}") private String fTPhost = "localhost"; /** FTP服务器端口 */ @Value("#{configProperties['ftp_port']}") private int ftpPort = 21; /** FTP服务器用户名 */ @Value("#{configProperties['ftp_user_name']}") private String ftpUserName; /** FTP用户密码 */ @Value("#{configProperties['ftp_user_pwd']}") private String ftpUserPasswd; /** 用户远程上传文件存储目录 */ @Value("#{configProperties['remoteFile_addr']}") private String remoteFileAddr; /** FTP公网映射地址 */ @Value("#{configProperties['ftp_public_network_add']}") private String ftpNetAdd; /** FTP公网端口 */ @Value("#{configProperties['ftp_public_network_port']}") private int ftpNetPort = 2121;
}
4.FTP上传下载的工具类FTPFileManager
/** * @Type ftpClientFileManager.java * @Desc * @author 123 * @date 2017年3月31日 下午2:50:58 * @version */@Servicepublic class FTPFileManager { private static final Logger logger = LoggerFactory.getLogger(FTPFileManager.class); private FTPClient ftpClient = new FTPClient(); /** 路径分隔符 */ private static final String SEPARATOR = "/"; /** FTP访问路径前缀 */ private static final String FTP_PREFIX = "ftp://"; @Autowired private FTPConfig config; /** * @Title: upload * * @Description: 文件上传 * * @param uploadFile * MultipartFile * @return * 返回保存路径 + 文件名 * @throws Exception * */ public String upload(MultipartFile uploadFile) throws Exception { ftpClient = new FTPClient(); ftpClient.connect(config.getfTPhost(), config.getFtpPort()); ftpClient.login(config.getFtpUserName(), config.getFtpUserPasswd()); //设置ftp字节流 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); int reply; reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return null; } ftpClient.enterLocalPassiveMode(); String basePath = config.getRemoteFileAddr(); ftpClient.changeWorkingDirectory(basePath); //为当天日期文件创建追加目录 Date today = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); String appendFile = sdf.format(today); //切换到上传目录 if (!ftpClient.changeWorkingDirectory(basePath + appendFile)) { //如果目录不存在创建目录 String[] dirs = appendFile.split(SEPARATOR); String tempTargetPath = basePath; for (String dir : dirs) { if (null == dir || "".equals(dir)) continue; tempTargetPath += SEPARATOR + dir; if (!ftpClient.changeWorkingDirectory(tempTargetPath)) { if (!ftpClient.makeDirectory(tempTargetPath)) { logger.error("ftp文件目录创建失败!"); return null; } else { ftpClient.changeWorkingDirectory(tempTargetPath); } } } } String fileName = new String(uploadFile.getOriginalFilename().getBytes("utf-8"), "iso-8859-1"); /** * 避免文件过多后出现重名,设置30位随机数为文件名称 */ // 获取文件扩展名 形如: .txt String fileExt = fileName.substring(fileName.lastIndexOf(".")); String newFileName = RandomUtils.randomAlphanumericStrictly(30) + fileExt; InputStream is = uploadFile.getInputStream(); if (!ftpClient.storeFile(newFileName, is)) { logger.error("文件{}存储过程出错", fileName); return null; } is.close(); ftpClient.disconnect(); /* String finalFile = basePath + SEPARATOR + appendFile + SEPARATOR + fileName;*/ //直接存储为匿名用户可直接访问下载的地址 String finalFile = FTP_PREFIX + config.getFtpNetAdd() + ":" + config.getFtpNetPort() + SEPARATOR + "pub" + SEPARATOR + appendFile + SEPARATOR + newFileName; logger.info("文件上传FTP服务器成功, 访问文件路径为 : " + finalFile); return finalFile; } /** * 从FTP服务器上下载文件 * @param remote 远程文件路径 * @param local 本地文件路径 * @return 是否成功 * @throws Exception */ public boolean download(String remote, String local) throws Exception { ftpClient = new FTPClient(); ftpClient.connect(config.getfTPhost(), config.getFtpPort()); ftpClient.login(config.getFtpUserName(), config.getFtpUserPasswd()); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); int reply; reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return false; } ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); boolean result; File f = new File(local); FTPFile[] files = ftpClient.listFiles(remote); if (files.length != 1) { System.out.println("远程文件不唯一"); ftpClient.disconnect(); return false; } long lRemoteSize = files[0].getSize(); if (f.exists()) { OutputStream out = new FileOutputStream(f, true); System.out.println("本地文件大小为:" + f.length()); if (f.length() >= lRemoteSize) { logger.error("本地文件大小大于远程文件大小,下载中止"); out.close(); ftpClient.disconnect(); return false; } ftpClient.setRestartOffset(f.length()); result = ftpClient.retrieveFile(remote, out); out.close(); } else { OutputStream out = new FileOutputStream(f); result = ftpClient.retrieveFile(remote, out); out.close(); } ftpClient.disconnect(); return result; }}/** * Revision history * ------------------------------------------------------------------------- * * Date Author Note * ------------------------------------------------------------------------- * 2017年3月31日 123 creat */
由于项目中没使用到文件下载,我只在本地进行了简单的下载centOS中FTP文件测试.
简单的记录.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
支持断点续传的上传方法
/** * 上传文件到FTP服务器,支持断点续传 * @param local 本地文件名称,绝对路径 * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构 * @return 上传结果 * @throws IOException */ public String upload(String local, String remote) throws IOException { //设置PassiveMode传输 ftpClient.enterLocalPassiveMode(); //设置以二进制流的方式传输 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); String uploadStatus; //对远程目录的处理 String remoteFileName = remote; if (remote.contains("/")) { remoteFileName = remote.substring(remote.lastIndexOf("/") + 1); String directory = remote.substring(0, remote.lastIndexOf("/") + 1); if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory)) { //如果远程目录不存在,则递归创建远程服务器目录 int start = 0; int end = 0; if (directory.startsWith("/")) { start = 1; } else { start = 0; } end = directory.indexOf("/", start); while (true) { String subDirectory = remote.substring(start, end); if (!ftpClient.changeWorkingDirectory(subDirectory)) { if (ftpClient.makeDirectory(subDirectory)) { ftpClient.changeWorkingDirectory(subDirectory); } else { System.out.println("创建目录失败"); return UploadStatus.Create_Directory_Fail; } } start = end + 1; end = directory.indexOf("/", start); //检查所有目录是否创建完毕 if (end <= start) { break; } } } } //检查远程是否存在文件 FTPFile[] files = ftpClient.listFiles(remoteFileName); if (files.length == 1) { long remoteSize = files[0].getSize(); File f = new File(local); long localSize = f.length(); if (remoteSize == localSize) { return UploadStatus.File_Exits; } else if (remoteSize > localSize) { return UploadStatus.Remote_Bigger_Local; } //尝试移动文件内读取指针,实现断点续传 InputStream is = new FileInputStream(f); if (is.skip(remoteSize) == remoteSize) { //设置文件开始 ftpClient.setRestartOffset(remoteSize); if (ftpClient.storeFile(remote, is)) { is.close(); return UploadStatus.Upload_From_Break_Success; } } //如果断点续传没有成功,则删除服务器上文件,重新上传 if (!ftpClient.deleteFile(remoteFileName)) { return UploadStatus.Delete_Remote_Faild; } is = new FileInputStream(f); if (ftpClient.storeFile(remote, is)) { uploadStatus = UploadStatus.Upload_New_File_Success; } else { uploadStatus = UploadStatus.Upload_New_File_Failed; } is.close(); } else { InputStream is = new FileInputStream(local); if (ftpClient.storeFile(remoteFileName, is)) { uploadStatus = UploadStatus.Upload_New_File_Success; } else { uploadStatus = UploadStatus.Upload_New_File_Failed; } is.close(); } return uploadStatus; }
0 0
- CentOS6.5下搭建FTP服务器 + Java上传文件
- centos6.5搭建FTP服务器
- centos6.5搭建FTP服务器
- centos6.5 搭建FTP服务器
- java上传文件到ftp服务器和ftp服务器的搭建
- centos6.5 64位 搭建FTP服务器
- centos6.5 64位 搭建FTP服务器
- centos6.5 FTP服务器的搭建
- CentOs6.5上快速搭建ftp服务器
- Centos6.5 (64位) 搭建FTP服务器
- Centos6.5(64位) 搭建FTP服务器
- centos6.5下安全架设FTP服务器
- centos6.4搭建ftp服务器
- CentOS6.5创建FTP服务器和用PSFTP进行文件上传
- centos6.5下如何搭建一个ftp服务器和使用客户端
- java FTP上传文件到服务器
- java上传文件到FTP服务器
- java将文件上传到ftp服务器
- Tomcat_性能调优方案
- mac下安装安卓开发环境
- android布局
- Java_常见格式的文件Java读写插件
- Android多媒体学习一:Android中Im…
- CentOS6.5下搭建FTP服务器 + Java上传文件
- 关于访问Android项目中assets中的…
- Android LinearLayout与Relat…
- Java_final,finally,finalize
- Android Bitmap详细介绍
- 避免滑动tableView时对NSTimer的干…
- 视图控制对象生命周期-init、viewD…
- CP vs SP
- iOS开发中touchesBegan和touchesEn…