Linux中的文件使用FTP进行文件备份
注意!!! 本文是在linux中进行ftp备份(备份到另一个linux服务器)
上传思路:
1.每次上传文件时, 后台接收文件, 使用transferTo上传到Linux服务器
2.把文件路径 + File.separator + 文件名, 放入redis, 如果redis中已存在, 则用逗号(,)进行拼接, 代码在例1
3.每天凌晨1点, 从redis中取出文件路径进行ftp备份, 代码在例2
注意事项:
1.ftp上传时, 如果有相同文件名, 则必须判断(ftp不会自动覆盖文件), 否则会返回false
2.使用java代码进行切换目录时(ftpClient.changeWorkingDirectory("/")), 子目录名一定不能和父目录名重名, 否则进入父目录时, 会自动进入到子目录.
例:
现在有目录/home/test/, test下有2个文件夹:test,test1
我现在使用changeWorkingDirectory进入/home/test/test1, 程序会自动进入到/home/test/test, 然后进入test1, 这时就会报错
例:
例1:
String uppath = baseDir + File.separator + file.getOriginalFilename();
Object filePath = redisCache.getCacheObject("filePath");
if (filePath != null ) {
redisCache.setCacheObject("filePath", filePath + "," + uppath);
}else {
redisCache.setCacheObject("filePath", uppath);
}
例2:
@Scheduled(cron = "0 0 1 * * ?")
public void RedisErrInfoBackups() throws Exception {
log.info("redis FTP进行备份, 定时任务开始执行-----------------------------------------------");
String filePath = redisCache.getCacheObject("filePath") + "";
log.info(filePath);
if (StringUtils.isNotEmpty(filePath)) {
String[] fpath = filePath.split(",");
String sbr;
try {
sbr = FTPTools.upload("192.168.5.44", 14000, "PipBeiyuan", "123456o-0", fpath);
//上传失败时,添加到sbr, 重新放入redis,第二天继续进行备份
if (StringUtils.isNotEmpty(sbr)) {
if (sbr.endsWith(",")) {
sbr = sbr.substring(0, sbr.length() - 1);
}
redisCache.setCacheObject("filePath", sbr);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
上传文件代码:
public static String upload(String hostname, int port, String username, String password, String[] fpath) {
FTPClient ftpClient = new FTPClient();
StringBuilder sbr = new StringBuilder();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
try {
File file;
for (int i = 0, len = fpath.length; i < len; i++) {
file = new File(fpath[i]);
//判断文件是否存在(检查的是linux中的路径)
if(file.exists()) {
int index = fpath[i].lastIndexOf(File.separator);
//2 检查工作目录是否存在
if (changeWorkingDirectory(ftpClient,fpath[i].substring(0,index))) {
// 3 检查是否上传成功
log.info(fpath[i] + "---------开始上传");
if (storeFile(ftpClient, fpath[i].substring(index+1), new FileInputStream(fpath[i]))) {
log.info(fpath[i] + "----------备份上传成功");
} else {
sbr.append(fpath[i] + ",");
log.info(fpath[i] + "----------上传失败");
}
log.info(fpath[i] + "----------备份上传结束");
}
}
}
disconnect(ftpClient);
return sbr.toString();
} catch (IOException e) {
log.error("工作目录不存在");
e.printStackTrace();
disconnect(ftpClient);
}
}
return sbr.toString();
}
连接代码:
public static boolean connect(FTPClient ftpClient, String hostname, int port, String username, String password) {
boolean flag = false;
try {
//ftp初始化的一些参数
ftpClient.connect(hostname, port);
ftpClient.enterLocalPassiveMode();
ftpClient.setControlEncoding("UTF-8");
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setConnectTimeout(60*1000);
if (ftpClient.login(username, password)) {
log.info("连接ftp成功");
flag = true;
} else {
log.error("连接ftp失败,可能用户名或密码错误");
try {
disconnect(ftpClient);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
log.error("连接失败,可能ip或端口错误");
e.printStackTrace();
}
return flag;
}
切换目录代码:
private static boolean changeWorkingDirectory(FTPClient ftpClient,String substring) throws IOException {
boolean isMakeSucess=false;
//先切换到根目录
ftpClient.changeWorkingDirectory("/");
//再按文件路径切换或者创建目录
for (String st : substring.split(/*File.separator*/"/")) {
if(StringUtils.isNotEmpty(st)){
if(!ftpClient.changeWorkingDirectory(st)){
isMakeSucess = ftpClient.makeDirectory(new String(st.getBytes("UTF-8"),"iso-8859-1"));
ftpClient.changeWorkingDirectory(st);
}else {
//切换路径
isMakeSucess = true;
ftpClient.changeWorkingDirectory(st);
}
}
}
return isMakeSucess;
}
上传代码:
public static boolean storeFile(FTPClient ftpClient, String fileName, InputStream fileInputStream) throws IOException {
boolean flag = false;
try {
//判断文件是否存在(如果存在继续上传会报错[不会自动覆盖])
log.info("当前路径为--> :" + ftpClient.printWorkingDirectory());
InputStream stream = ftpClient.retrieveFileStream(new String(fileName.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING));
//不存在则进行上传文件
if(stream == null || ftpClient.getReplyCode() == FTPReply.FILE_UNAVAILABLE){
if (ftpClient.storeFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"), fileInputStream)) {
log.info("不存在直接上传---:");
flag = true;
}
}else {
flag = true;
}
} catch (IOException e) {
log.error("上传失败");
e.printStackTrace();
}
return flag;
}
Linux中的文件使用FTP进行文件备份的更多相关文章
- 工具WinSCP:windows和Linux中进行文件传输
工具WinSCP:windows和Linux中进行文件传输 2016-09-21 [转自]使用WinSCP软件在windows和Linux中进行文件传输 当我们的开发机是Windows,服务器是Lin ...
- Linux中检索文件
1 , Use locate command It is a fast way to find the files location, but if a file just created ,it w ...
- Linux中查看文件编码
在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱 ...
- 在Linux中查看文件的编码及对文件进行编码转换
如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8.下面介绍一下,在Li ...
- Linux中的文件描述符与打开文件之间的关系
Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...
- 5 个在 Linux 中管理文件类型和系统时间的有用命令
对于想学习 Linux 的初学者来说要适应使用命令行或者终端可能非常困难.由于终端比图形用户界面程序更能帮助用户控制 Linux 系统,我们必须习惯在终端中运行命令.因此为了有效记忆 Linux 不同 ...
- Linux中一个文件10行内容,如何输出5-8内容到屏幕
题目是这样的,Linux中一个文件10行内容,如何输出5-8内容到屏幕首先我们模拟一下这样的环境: [root@localhost question]# pwd /root/question [roo ...
- [转帖]NotePad++编辑Linux中的文件
NotePad++编辑Linux中的文件 https://blog.csdn.net/chengqiuming/article/details/78882692 原作者 未经允许不允许转帖 加密自己参 ...
- linux中的文件编码及编码修改
查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set fileencoding 即可显示文件编码格式. 如果你只是想查看其它编码格式的文件或者想 ...
随机推荐
- indexedDB数据库创建
1.首先需要使用使用indexedDB.open()方法,打开数据库 2.通过createObjectStore方法创建表, 创建表之后, 这个表通过createIndex方法创建索引 3.通过tra ...
- 「萌新指南」SOA vs. 微服务:What’s the Difference?
实话实说,在我还没有实习之前,我是连 SOA 是啥都不知道的,只听说过微服务,毕竟微服务实在太火了,想不知道都难,我觉得实习的时候肯定也是微服务,进组之后发现是 SOA 架构,当时都懵了,看了很多文档 ...
- 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)
当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...
- JAVA 之 每日一记 之 算法( 给你一个Excel表列序号,返回出它对应的数字 )
代码结果:(只想要代码的可以离开了,代码给你了,绝对能用的.想要思路的往下看.) class Solution { public int titleToNumber(String s) { int a ...
- openswan框架和编译时说明
刚开始学习openswan项目代码时,自己尝试了在虚拟机上编译.安装.运行openswan代码,由于当时刚开始学习openswan代码,因此对于其构成并不清楚,在编译.运行过程中有了问题,基本是通过百 ...
- oh,我的老伙计,你看看这近五十个dapr视频
oh,我的老伙计,你看看这近五十个 dapr 视频.这不就是你想要的视频资料吗?快来捡走吧! 开始了,但是没完全开始 Dapr 是一个可移植的.事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的. ...
- python模块--datetime
datatime.date类 构造器 返回值类型 说明 (year, month, day) date 类方法/属性 .max date datetime.date(9999, 12, 3 ...
- 妙用 background 实现花式文字效果
本文将讲解如何利用 background 系列属性,巧妙的实现一些花式的文字效果.通过本文,你将可以学到: 通过 background-size 与 background-position 实现酷炫的 ...
- 【第九篇】- Git 标签之Spring Cloud直播商城 b2b2c电子商务技术总结
Git 标签 如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签. 比如说,我们想为我们的 xxx 项目发布一个"1.0"版本. ...
- awk的执行方式
https://blog.csdn.net/fengyuanye/article/details/82858863 awk执行有三种形式: 1.直接以命令行来执行, 语法形式为:awk ...