Java:MacからWindowsへのファイル転送で作成される余分なファイルを削除する
【課題】
Mac環境のファイルをHDやUSBメモリなどを使ってWindows環境へコピーした場合,Windows側で見ると以下のようなファイルができていることがあります。
1)ディレクトリごとに「.DS_Store」ファイル
2)1つのファイルに対してファイル名の先頭に「._」がついた同名ファイル
このうち1)はMacのFinderに関する情報で,2)はFAT32のディスクにコピーした時に作られる,ファイル情報が格納されたファイルです。1)はコピー元のMac上に存在しますが,2)はありません。
これらのファイルはWindowsでは不要なファイルなので,今回はこれらを一括削除するプログラムをJavaで作成してみます。
【仕様】
プログラムを作成するにあたって以下の点に留意する必要があります。
●処理の内容
1)ファイル名の先頭に「._」がついたファイルが存在した場合,それとペアになる「._」がついていないファイルが存在するかを確認した上で削除します。
2)「.DS_Store」ファイルの削除について,「.DS_Store」に対して「._.DS_Store」が存在するので「.DS_Store」を先に削除してしまうと1)の処理で「._.DS_Store」の削除が行われなくなってしまいます。そのため,先に1)の処理を行ってから「.DS_Store」の削除を行う必要があります。
●実装について
ディレクトリ内のファイルを削除する際,for文の中でリストからFileを1件づつ取り出し,削除すべきファイルかどうか判定して,その場で削除する処理を行うと,1つのファイル削除でリストの順番が1つ繰り上がるので,for文で取り出す「次」のFileがリストの「2つ先」になってしまいます。
そのため削除すべきファイルをその場で削除せず,キューに保存して後で一括して削除するようにする必要があります。
【実装】
1)ファイル名の先頭が「._」のファイルを削除する「removeSpecific」メソッドの実装は以下になります。
import java.io.File; import java.io.IOException; import java.util.Deque; import java.util.LinkedList; //-------------------------------------------------------------------------- /** * ファイル名の先頭が「._」のファイルの削除. * @param dir ファイルが格納されているディレクトリ. * @throws IOException */ private static void removeSpecific ( File dir) throws IOException { Deque<File> que = new LinkedList<File>(); String name; File[] paths = dir.listFiles(); for (File path : paths) { if (path.isDirectory()) { removeSpecific(path); } else if ((name = path.getName()).startsWith("._")) { File peerfile = new File(path.getParentFile(), name.substring(2)); if (peerfile.exists()) { que.push(path); } } } while (!que.isEmpty()) { File path = que.pop(); System.out.println(path.getPath()); path.delete(); } } |
2)「.DS_Store」ファイルを削除するメソッド「removeDSstore」は以下になります。
import java.io.File; import java.io.IOException; import java.util.Deque; import java.util.LinkedList; //-------------------------------------------------------------------------- /** * 「.DS_Store」ファイルの削除. * @param dir ファイルが格納されているディレクトリ. * @throws IOException */ private static void removeDSstore ( File dir) throws IOException { Deque<File> que = new LinkedList<File>(); File[] paths = dir.listFiles(); for (File path : paths) { if (path.isDirectory()) { removeDSstore(path); } else if (".DS_Store".equals(path.getName())) { que.push(path); } } while (!que.isEmpty()) { File path = que.pop(); System.out.println(path.getPath()); path.delete(); } } |
3)各処理を呼び出すmain関数は以下になります。
//-------------------------------------------------------------------------- /** * main関数:エントリーポイント. * @param args */ public static void main(String[] args) { try { String pathStr = (args != null && 0 < args.length)? args[0]: null; if (pathStr == null || pathStr.isEmpty()) { pathStr = "."; } File dir = new File(pathStr); if (dir.isDirectory()) { removeSpecific(dir); removeDSstore(dir); } } catch (Exception ex) { ex.printStackTrace(); } } |
【著作権表記】上記コードを含む本ブログのプログラムコードは,私的利用可,商用利用可,改変しての利用可です。利用の際に作者に許諾を得る必要はありません。
■関連書籍をAmazonで検索:[Java]
●増補改訂版 Java言語で学ぶデザインパターン入門(kindle版)
←この記事が役に立ったという方はクリックお願いします。
| 固定リンク
| トラックバック (0)