Help us understand the problem. What is going on with this article?

仕事で使うファイルを、簡単にバックアップしたい

More than 1 year has passed since last update.

会社での困りごと

仕事上、資料のバックアップを残すことが、頻繁にあります。主な理由は、ファイルのバージョン管理です。

そのやり方は、最新版に手を加える前に、エクスプローラー上でファイルをコピーしたうえで、ファイル名に日付・時刻を入れ、各ファイルの更新日時が分かるようにする、というものです。こんな(↓)感じです。
pic-20190705T1416.png

世の中には、Boxのように、ファイルのバージョン管理を便利に行えるサービスはたくさんあり、活用している人も多いと思います。ただ、この方法にも、利点があります。

  • ファイル名を見ただけで、いつ更新したものかが分かる。
  • バージョンごとにファイル名が異なるので、区別しやすい(Boxなどでは、同一ファイル名でバージョン管理される)。
  • 当たり前ですが、無料

一方で、この管理方法の面倒な点は、次のように、手順が煩雑なところです。

  1. 「企画書.docx」をコピー&ペースト([Ctrl]+[C][Ctrl]+[V]
  2. 「企画書 - コピー.docx」という名前のファイルができる。
  3. そのファイル名の「 - コピー」部分を、日付と時刻に変更する。ファイルの更新日付を確認しながら入力するので、面倒。

一度くらいなら気になりませんが、これを毎日・何度も繰り返すうちに、かなり面倒に感じるようになりました。
また、タイプミスで日付を誤ったりすると、ファイル名で並べた時に更新順序が崩れる点にも、困っていました。

ツールを作って、一瞬でバックアップできるようにした

そこで、ツールを作り、楽をすることにしました。
「企画書-latest.docx」のように、ファイル拡張子の直前が「-latest」という名前のファイルであることが条件です。

そのファイルを、エクスプローラー上で、ツールにドラッグ&ドロップすると、自動的にバックアップ&ファイル名更新を行います。
backup.batというバッチファイルがツールで、対象のファイルを、バッチファイルにドラッグ&ドロップするだけです。

バッチファイルの中では、Javaのプログラムを実行しています。
pic-20190705T1556.png

下の図が、実行結果です。
バックアップをワンクリックで実行できるので、便利になりました。
pic-20190705T1435.png

ソースコード

ソースコードは、こんな感じです。Javaとバッチファイルの組み合わせで動きます。
Javaプログラムをコンパイルし、Classファイルとバッチファイルを同じフォルダに置いてください。

実行時は、上の図のように、バックアップしたいファイルを、エクスプローラー上で、バッチファイルにドラッグ&ドロップしてください。対象のファイルと同じフォルダに、バックアップを作ります。

あと自分の場合は、ツール(バッチファイル)のショートカットをデスクトップに作っておき、そのショートカットに対してドラッグ&ドロップするようにしています。

CopyAndBackupFile.java
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);
    }
  }
}
backup.bat
@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社のサービス」であるという、間違った記述がありましたので、修正しました。お詫びして訂正します。

hachan
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away