会社での困りごと
仕事上、資料のバックアップを残すことが、頻繁にあります。主な理由は、ファイルのバージョン管理です。
そのやり方は、最新版に手を加える前に、エクスプローラー上でファイルをコピーしたうえで、ファイル名に日付・時刻を入れ、各ファイルの更新日時が分かるようにする、というものです。こんな(↓)感じです。
世の中には、Boxのように、ファイルのバージョン管理を便利に行えるサービスはたくさんあり、活用している人も多いと思います。ただ、この方法にも、利点があります。
- ファイル名を見ただけで、いつ更新したものかが分かる。
- バージョンごとにファイル名が異なるので、区別しやすい(Boxなどでは、同一ファイル名でバージョン管理される)。
- 当たり前ですが、無料。
一方で、この管理方法の面倒な点は、次のように、手順が煩雑なところです。
- 「企画書.docx」をコピー&ペースト(
[Ctrl]+[C]
→[Ctrl]+[V]
) - 「企画書 - コピー.docx」という名前のファイルができる。
- そのファイル名の「 - コピー」部分を、日付と時刻に変更する。ファイルの更新日付を確認しながら入力するので、面倒。
一度くらいなら気になりませんが、これを毎日・何度も繰り返すうちに、かなり面倒に感じるようになりました。
また、タイプミスで日付を誤ったりすると、ファイル名で並べた時に更新順序が崩れる点にも、困っていました。
ツールを作って、一瞬でバックアップできるようにした
そこで、ツールを作り、楽をすることにしました。
「企画書_-latest_.docx」のように、ファイル拡張子の直前が「-latest」という名前のファイルであることが条件です。
そのファイルを、エクスプローラー上で、ツールにドラッグ&ドロップすると、自動的にバックアップ&ファイル名更新を行います。
backup.bat
というバッチファイルがツールで、対象のファイルを、バッチファイルにドラッグ&ドロップするだけです。
バッチファイルの中では、Javaのプログラムを実行しています。
下の図が、実行結果です。
バックアップをワンクリックで実行できるので、便利になりました。
ソースコード
ソースコードは、こんな感じです。Javaとバッチファイルの組み合わせで動きます。
Javaプログラムをコンパイルし、Classファイルとバッチファイルを同じフォルダに置いてください。
実行時は、上の図のように、バックアップしたいファイルを、エクスプローラー上で、バッチファイルにドラッグ&ドロップしてください。対象のファイルと同じフォルダに、バックアップを作ります。
あと自分の場合は、ツール(バッチファイル)のショートカットをデスクトップに作っておき、そのショートカットに対してドラッグ&ドロップするようにしています。
import java.net.*;
import java.nio.file.*;
import java.text.*;
import java.util.*;
public class CopyAndBackupFile {
private static final String DEFAULT_PLACE_HOLDER = "latest";
private static final SimpleDateFormat FORMAT_PREFIX = new SimpleDateFormat("YYYYMMdd");
private static final SimpleDateFormat FORMAT_SUFFIX = new SimpleDateFormat("HHmm");
public static void main(String[] args) throws Exception {
int argc = 0;
String placeHolder;
if (args[argc].equals("-p")) {
placeHolder = args[++argc];
++argc;
} else {
placeHolder = DEFAULT_PLACE_HOLDER;
}
assert placeHolder != null : "Placeholder is null";
Path[] paths = new Path[args.length - argc];
for (int i = 0; i < paths.length; i++, argc++) {
paths[i] = Paths.get(args[argc]);
}
rename_loop:
for (int i = 0; i < paths.length; i++) {
Path pathOrg = Paths.get(paths[i].toString());
Path dir = pathOrg.getParent();
Path file = pathOrg.getFileName();
String sFile = file.toString();
int phStart = sFile.lastIndexOf(placeHolder);
if (phStart < 0) {
System.err.printf("ERROR: %s does not include \"%s\"%n", sFile, placeHolder);
continue rename_loop;
}
int phEnd = phStart + placeHolder.length();
long lastModified = pathOrg.toFile().lastModified();
Date date = new Date(lastModified);
String backupDate = FORMAT_PREFIX.format(date)
.concat("T")
.concat(FORMAT_SUFFIX.format(date));
String sFileNew = sFile.substring(0, phStart)
.concat(backupDate)
.concat(sFile.substring(phEnd));
Path pathNew = Paths.get(dir.toString(), sFileNew);
System.out.printf("%s -> %s%n", pathOrg, pathNew);
Files.copy(pathOrg, pathNew);
}
}
}
@echo off
setlocal
rem
rem The top directory of the tool
rem
set __tools_dir=%~d0%~p0
set __last_char=%__tools_dir:~-1%
if "%__last_char%"=="\" set __tools_dir=%__tools_dir:~0,-1%
rem
rem Environment variables
rem
set __java_bin_dir=C:\ProgramData\Oracle\Java\javapath
set __classpath=%__tools_dir%
if "%JAVA_HOME%"=="" (
echo WARNING: JAVA_HOME is empty. Using %__java_bin_dir%
) else (
set __java_bin_dir=%JAVA_HOME:"=%\bin
)
if not exist "%__java_bin_dir%\java.exe" (
echo ERROR: %__java_bin_dir%\java.exe does not exist
echo ERROR: set JAVA_HOME to the top directory of Java SE 7 or later
goto :EOF
)
set __java_options=
rem
rem Run
rem
@echo on
"%__java_bin_dir%\java.exe" %__java_options% -classpath "%__classpath%" CopyAndBackupFile %*
@echo off
@endlocal
記事訂正(2019年7月14日)
「Box」が「Microsoft社のサービス」であるという、間違った記述がありましたので、修正しました。お詫びして訂正します。