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 即可显示文件编码格式. 如果你只是想查看其它编码格式的文件或者想 ...
随机推荐
- android http get
Executors.newSingleThreadExecutor().execute{ val uri = "https://www.cnblogs.com/hangj" val ...
- MyBatis学习总结(四)——字段名与实体类属性名不相同的冲突的解决
表中的字段名和表对应实体类的属性名称不一定都是完全相同的,这种情况下的如何解决字段名与实体类属性名不相同的冲突.如下所示: 一.准备演示需要使用的表和数据 CREATE TABLE my_user( ...
- [编译] 10、kconfig 入门指导教程
目录 前言 1. 安装 kconfig 2. 克隆一个 demo 3. 运行 kconfig 4. 源码解析 4.1 选择题目设计模板 4.2 填空题目设计模板 4.3 判断题目设计模板 5. 产物解 ...
- Apache Hudi内核之文件标记机制深入解析
1. 摘要 Hudi 支持在写入时自动清理未成功提交的数据.Apache Hudi 在写入时引入标记机制来有效跟踪写入存储的数据文件. 在本博客中,我们将深入探讨现有直接标记文件机制的设计,并解释了其 ...
- 图像处理之Canny边缘检测(一)
一:历史 Canny边缘检测算法是1986年有John F. Canny开发出来一种基于图像梯度计算的边缘 检测算法,同时Canny本人对计算图像边缘提取学科的发展也是做出了很多的贡献.尽 管至今已经 ...
- Spring系列之集成MongoDB的2种方法
MongoDB是最流行的NoSQL数据库,SpringBoot是使用Spring的最佳实践.今天带大家讲一讲SpringBoot集成MongoDB的两种方式,MongoDB的安装自行去官网查询,本地开 ...
- Identity角色管理五(添加用户到角色组)
因需要在用户列表中点详情按钮来到当前页,所以需要展示分组详情,并展示当前所属角色组的用户 public async Task<ActionResult> Details(string id ...
- CSS004. 自定义滚动条样式(webkit)
CSS /* 滚动条宽度 */ ::-webkit-scrollbar { width: 6px; } /* 轨道样式 */ ::-webkit-scrollbar-track { backgroun ...
- python库--jieba(中文分词)
import jieba 精确模式,试图将句子最精确地切开,适合文本分析:全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义:搜索引擎模式,在精确模式的基础上,对长词再次切 ...
- FastAPI 学习之路(一)fastapi--高性能web开发框架
fastapi是高性能的web框架.他的主要特点是:- 快速编码- 减少人为bug- 直观- 简易- 具有交互式文档 - 高性能 - 基于API的开放标准 支持python 3.6版本. 安装 pip ...