注意!!! 本文是在linux中进行ftp备份(备份到另一个linux服务器)

上传思路:

  1. 1.每次上传文件时, 后台接收文件, 使用transferTo上传到Linux服务器
  2. 2.把文件路径 + File.separator + 文件名, 放入redis, 如果redis中已存在, 则用逗号(,)进行拼接, 代码在例1
  3. 3.每天凌晨1点, redis中取出文件路径进行ftp备份, 代码在例2

注意事项:

  1. 1.ftp上传时, 如果有相同文件名, 则必须判断(ftp不会自动覆盖文件), 否则会返回false
  2. 2.使用java代码进行切换目录时(ftpClient.changeWorkingDirectory("/")), 子目录名一定不能和父目录名重名, 否则进入父目录时, 会自动进入到子目录.
  3. 例:
  4. 现在有目录/home/test/, test下有2个文件夹:test,test1
  5. 我现在使用changeWorkingDirectory进入/home/test/test1, 程序会自动进入到/home/test/test, 然后进入test1, 这时就会报错

例:

  1. 1:
  2. String uppath = baseDir + File.separator + file.getOriginalFilename();
  3. Object filePath = redisCache.getCacheObject("filePath");
  4. if (filePath != null ) {
  5. redisCache.setCacheObject("filePath", filePath + "," + uppath);
  6. }else {
  7. redisCache.setCacheObject("filePath", uppath);
  8. }
  9. 2:
  10. @Scheduled(cron = "0 0 1 * * ?")
  11. public void RedisErrInfoBackups() throws Exception {
  12. log.info("redis FTP进行备份, 定时任务开始执行-----------------------------------------------");
  13. String filePath = redisCache.getCacheObject("filePath") + "";
  14. log.info(filePath);
  15. if (StringUtils.isNotEmpty(filePath)) {
  16. String[] fpath = filePath.split(",");
  17. String sbr;
  18. try {
  19. sbr = FTPTools.upload("192.168.5.44", 14000, "PipBeiyuan", "123456o-0", fpath);
  20. //上传失败时,添加到sbr, 重新放入redis,第二天继续进行备份
  21. if (StringUtils.isNotEmpty(sbr)) {
  22. if (sbr.endsWith(",")) {
  23. sbr = sbr.substring(0, sbr.length() - 1);
  24. }
  25. redisCache.setCacheObject("filePath", sbr);
  26. }
  27. }catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }

上传文件代码:

  1. public static String upload(String hostname, int port, String username, String password, String[] fpath) {
  2. FTPClient ftpClient = new FTPClient();
  3. StringBuilder sbr = new StringBuilder();
  4. //1 测试连接
  5. if (connect(ftpClient, hostname, port, username, password)) {
  6. try {
  7. File file;
  8. for (int i = 0, len = fpath.length; i < len; i++) {
  9. file = new File(fpath[i]);
  10. //判断文件是否存在(检查的是linux中的路径)
  11. if(file.exists()) {
  12. int index = fpath[i].lastIndexOf(File.separator);
  13. //2 检查工作目录是否存在
  14. if (changeWorkingDirectory(ftpClient,fpath[i].substring(0,index))) {
  15. // 3 检查是否上传成功
  16. log.info(fpath[i] + "---------开始上传");
  17. if (storeFile(ftpClient, fpath[i].substring(index+1), new FileInputStream(fpath[i]))) {
  18. log.info(fpath[i] + "----------备份上传成功");
  19. } else {
  20. sbr.append(fpath[i] + ",");
  21. log.info(fpath[i] + "----------上传失败");
  22. }
  23. log.info(fpath[i] + "----------备份上传结束");
  24. }
  25. }
  26. }
  27. disconnect(ftpClient);
  28. return sbr.toString();
  29. } catch (IOException e) {
  30. log.error("工作目录不存在");
  31. e.printStackTrace();
  32. disconnect(ftpClient);
  33. }
  34. }
  35. return sbr.toString();
  36. }

连接代码:

  1. public static boolean connect(FTPClient ftpClient, String hostname, int port, String username, String password) {
  2. boolean flag = false;
  3. try {
  4. //ftp初始化的一些参数
  5. ftpClient.connect(hostname, port);
  6. ftpClient.enterLocalPassiveMode();
  7. ftpClient.setControlEncoding("UTF-8");
  8. ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
  9. ftpClient.setConnectTimeout(60*1000);
  10. if (ftpClient.login(username, password)) {
  11. log.info("连接ftp成功");
  12. flag = true;
  13. } else {
  14. log.error("连接ftp失败,可能用户名或密码错误");
  15. try {
  16. disconnect(ftpClient);
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. } catch (IOException e) {
  22. log.error("连接失败,可能ip或端口错误");
  23. e.printStackTrace();
  24. }
  25. return flag;
  26. }

切换目录代码:

  1. private static boolean changeWorkingDirectory(FTPClient ftpClient,String substring) throws IOException {
  2. boolean isMakeSucess=false;
  3. //先切换到根目录
  4. ftpClient.changeWorkingDirectory("/");
  5. //再按文件路径切换或者创建目录
  6. for (String st : substring.split(/*File.separator*/"/")) {
  7. if(StringUtils.isNotEmpty(st)){
  8. if(!ftpClient.changeWorkingDirectory(st)){
  9. isMakeSucess = ftpClient.makeDirectory(new String(st.getBytes("UTF-8"),"iso-8859-1"));
  10. ftpClient.changeWorkingDirectory(st);
  11. }else {
  12. //切换路径
  13. isMakeSucess = true;
  14. ftpClient.changeWorkingDirectory(st);
  15. }
  16. }
  17. }
  18. return isMakeSucess;
  19. }

上传代码:

  1. public static boolean storeFile(FTPClient ftpClient, String fileName, InputStream fileInputStream) throws IOException {
  2. boolean flag = false;
  3. try {
  4. //判断文件是否存在(如果存在继续上传会报错[不会自动覆盖])
  5. log.info("当前路径为--> :" + ftpClient.printWorkingDirectory());
  6. InputStream stream = ftpClient.retrieveFileStream(new String(fileName.getBytes("UTF-8"), FTP.DEFAULT_CONTROL_ENCODING));
  7. //不存在则进行上传文件
  8. if(stream == null || ftpClient.getReplyCode() == FTPReply.FILE_UNAVAILABLE){
  9. if (ftpClient.storeFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"), fileInputStream)) {
  10. log.info("不存在直接上传---:");
  11. flag = true;
  12. }
  13. }else {
  14. flag = true;
  15. }
  16. } catch (IOException e) {
  17. log.error("上传失败");
  18. e.printStackTrace();
  19. }
  20. return flag;
  21. }

Linux中的文件使用FTP进行文件备份的更多相关文章

  1. 工具WinSCP:windows和Linux中进行文件传输

    工具WinSCP:windows和Linux中进行文件传输 2016-09-21 [转自]使用WinSCP软件在windows和Linux中进行文件传输 当我们的开发机是Windows,服务器是Lin ...

  2. Linux中检索文件

    1 , Use locate command It is a fast way to find the files location, but if a file just created ,it w ...

  3. Linux中查看文件编码

    在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱 ...

  4. 在Linux中查看文件的编码及对文件进行编码转换

    如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8.下面介绍一下,在Li ...

  5. Linux中的文件描述符与打开文件之间的关系

    Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...

  6. 5 个在 Linux 中管理文件类型和系统时间的有用命令

    对于想学习 Linux 的初学者来说要适应使用命令行或者终端可能非常困难.由于终端比图形用户界面程序更能帮助用户控制 Linux 系统,我们必须习惯在终端中运行命令.因此为了有效记忆 Linux 不同 ...

  7. Linux中一个文件10行内容,如何输出5-8内容到屏幕

    题目是这样的,Linux中一个文件10行内容,如何输出5-8内容到屏幕首先我们模拟一下这样的环境: [root@localhost question]# pwd /root/question [roo ...

  8. [转帖]NotePad++编辑Linux中的文件

    NotePad++编辑Linux中的文件 https://blog.csdn.net/chengqiuming/article/details/78882692 原作者 未经允许不允许转帖 加密自己参 ...

  9. linux中的文件编码及编码修改

    查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set fileencoding 即可显示文件编码格式. 如果你只是想查看其它编码格式的文件或者想 ...

随机推荐

  1. linux centos7 read 命令

    2021-08-24 1. 命令简介 read 命令就是读取控制台输入,会将从键盘输入的数据分割成一个个字段依次存储在 parameter[0] .parameter[1] ......,若是没有指定 ...

  2. noip模拟21

    开题发现这场考过,定睛一看,发现是省选前最后一场,没改过呀--但是还是讲武德的赛时没提交 A. Median 神奇之处在于 \(1e7\) 个质数居然能线性筛出来~ 那么 \(S2\) 可以直接筛出来 ...

  3. [考试总结]noip模拟44

    这个真的是一个 \(nb\) 题. 考试快要结束的时候,在机房中只能听到此起彼伏的撕吼. 啊---------- 然后人们预测这自己的得分. \(\color{red}{\huge{0}}\) \(\ ...

  4. Appium问题解决方案(7)- Could not find 'adb.exe' in PATH. Please set the ANDROID_HOME environment variable with the Android SDK root directory path

    背景:运行代码提示找不到ADB An unknown server-side error occurred while processing the command. Original error: ...

  5. shell脚本测试变量是否为空,测试文件是否存在,sed修改配置文件参数,分支语句

    Shell脚本 1. 基本的几个变量 使用$?获取最近一次的执行结果: 使用$#获取传递的参数个数,类似C语言中的int argc; 使用$@获取所有的传参,类似C语言的char **argv 2. ...

  6. vim中字符串的替换

    vi/vim 中可以使用 :s 命令来替换字符串 :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sky : ...

  7. Docker修改容器中的时间

    Docker修改容器中的时间 前言 在公司开发时使用 Docker 创建数据库(SQL Server)的实例十分方便,还原数据库也只要设置好共享文件夹,在 SQL Server Management ...

  8. 华为云计算IE面试笔记-桌面云中的用户组、虚拟机模板、模板虚拟机、虚拟机组和桌面组的关系及区别。发放完整复制和链接克隆虚拟机时,步骤有什么区别,要怎么选择桌面组?

    概念解释: 模板虚拟机:FC上创建的裸虚拟机,用于制作不同类型的虚拟机模板. 虚拟机模板:用于创建虚拟机的模板,对裸虚拟机(模板虚拟机)进行配置或自定义安装软件后,转为模板.虚拟机模板类型有完整复制, ...

  9. linux中创建公私钥

    linux中创建公私钥要再~(root)目录下ssh-keygencd /root/.ssh/lsid_rsa 是私钥id_rsa.pub 是公钥把 authorized_keys删除掉,重新建aut ...

  10. 利用Qt中的ui文件生成PyQt5程序,自定义槽函数

    1.在Qt Creator4.8.0上面设计如上.ui文件 2.点击上方图标,可以建立信号-槽连接,button_click()为自定义槽函数 3.设计目的:点击clear按钮,可消除上方文本框中的内 ...