Scala作为script使用也是非常的方便。
原文地址:https://www.yangbajing.me/2019/03/22/scala实战:迁移文件/
前因
最近因为线上文件越来越多,导致磁盘不够用。需要将磁盘上数据迁移到一块新的磁盘上(不用问为啥没用云存储,因为用了的话就不会有这篇文章了)。迁移数据时遇到几个问题:
- 迁移过程中服务不能中断
- 因为磁盘文件较大,文件移动耗费时间较长……等copy完的话再重新挂载磁盘会造成移动时间这段时间内新上传文件丢失
终上,我想到一个一个子目录的进行迁移,在迁移完后再将新目录做一个符号连接回原地址。这样在完成整体迁移之前若有新文件上传,文件将通过符号连接最终存储到新的磁盘上。
实现
所用Scala script代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import java.nio.file.{Files, Path, Paths} import java.time.{Duration, Instant}
import scala.sys.process._
if (args.length != 2) { println("""请输入参数:scala MoveDir.scala <src_dir> <dest_dir>""") }
val Array(srcDir, distDir) = args
val IGNORE_NAMES = Set("s1")
def ignoreDirectories(dir: Path) = { val name = dir.getName(dir.getNameCount - 1).toString IGNORE_NAMES(name) || name.length != 2 }
Files .list(Paths.get(srcDir)) .forEach { case dir: Path if !Files.isDirectory(dir) || Files.isSymbolicLink(dir) => println(s"$dir 不是目录或为符号链接") case dir: Path if ignoreDirectories(dir) => println(s"强制忽略目录:$dir") case dir: Path => val name = dir.getName(dir.getNameCount - 1).toString val target = s"$distDir/$name" val start = Instant.now() try { s"mv $dir $target".!! s"ln -sf $target $srcDir/$name".!! val cost = Duration.between(start, Instant.now()) println(s"移动目录成功,耗时$cost;$dir --> $target") } catch { case e: Throwable => val cost = Duration.between(start, Instant.now()) System.err.println(s"移动目录失败,耗时$cost;$dir --> $target。${e.toString}") } }
|
脚本执行后的部分输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ scala MoveDir.scala /home/upload /data 移动目录成功,耗时PT0.012S;/home/upload/d4 --> /data/d4 移动目录成功,耗时PT0.002S;/home/upload/ba --> /data/ba 移动目录成功,耗时PT0.002S;/home/upload/fd --> /data/fd 移动目录成功,耗时PT0.002S;/home/upload/7e --> /data/7e 移动目录成功,耗时PT0.002S;/home/upload/b7 --> /data/b7 移动目录成功,耗时PT0.003S;/home/upload/76 --> /data/76 移动目录成功,耗时PT0.002S;/home/upload/43 --> /data/43 强制忽略目录:/home/upload/hongka-tmp 移动目录成功,耗时PT0.001S;/home/upload/df --> /data/df /home/upload/logo.jpg 不是目录或为符号链接 移动目录成功,耗时PT0.001S;/home/upload/85 --> /data/85 移动目录成功,耗时PT0.001S;/home/upload/f0 --> /data/f0 ......
|
小结
Scala是一门强大的、融合了函数式与面向对象范式的编程语言。同时,Scala也是一门精致的语言,除了通常那些 重量 级应用外,日常工作中的脚本也可以使用。接下来,也许你可以尝试下 lihaoyi 的 http://ammonite.io/。