/* -*- mode: java; coding: iso-2022-jp -*-
* Time-stamp: "2001-10-09 22:10:53 tfuruka1"
*
* Compile:
* javac -encoding ISO2022JP Jtree.java
*
* このファイルはISO-2022-JPでコーディングしています。コンパイル時には
* codingオプションを指定して下さい。
*/
import java.io.File;
import java.util.Date;
import java.util.Comparator;
import java.io.FilenameFilter;
import java.text.SimpleDateFormat;
/**
* ドライブやパスのディレクトリ構造を図式表示します。ようするにWindows
* NT等のtreeコマンドと同じような事をします。
*
*
* - 【形式】
*
-
java Jtree [-f] [-a] [-l] [パス]
* - 【説明】
*
-
* -f 各ディレクトリのファイル名を表示します。
* -a 拡張文字ではなく、ASCII 文字で表示します。
* -l ファイルサイズと更新日時を表示します。
*
*
*/
public class Jtree implements FilenameFilter, Comparator {
private static final int MAX_LEVEL = 100;
private static boolean[] nestStat = new boolean[MAX_LEVEL];
private static boolean bFile = false;
private static boolean bLongFormat = false;
private static boolean bAsciiKeisen = false;
private static String curDirName = null;
private static int firstLevel;
/**
* インターフェイスComparatorのcompareメソッドの実装。順序付けのた
* めに 2 つの引数を比較します。最初の引数が 2 番目の引数より小さ
* い場合は負の整数、両方が等しい場合は 0、最初の引数が 2 番目の引
* 数より大きい場合は正の整数を返します。
*
* このメソッドの目的は、ディレクトリ内のファイルとディレクトリを
* ソートする事です。ファイルとディレクトリの場合は、ファイルが先
* に現れるようにソートします。
*
* このメソッドを呼び出す時はcurDirNameに正しいディレクトリ名が設
* 定されている必要があります。
*
* @param o1 オブジェクト(ファイル名)
* @param o2 オブジェクト(ファイル名)
*/
public int compare(Object o1, Object o2) {
File f1 = new File(curDirName + "/" + (String)o1);
File f2 = new File(curDirName + "/" + (String)o2);
int w1;
int w2;
w1 = f1.isDirectory() ? 1 : 0;
w2 = f2.isDirectory() ? 1 : 0;
if (w1 < w2) {
return -1;
}
if (w1 > w2) {
return 1;
}
return ((String)o1).compareTo((String)o2);
}
/**
* インタフェース FilenameFilterのacceptメソッドの実装。指定された
* ファイルをファイルリストに含めるかどうかをテストします。このメ
* ソッドの実装目的は、ディレクトリのみの出力と、全てのファイルの
* 出力を実現する為です。
*
* @param dir ファイルが見つかったディレクトリ
* @param name ファイルの名前
*/
public boolean accept(File dir, String name) {
File newFile = new File(dir.toString() + "/" + name);
if (bFile) {
return true;
}
return newFile.isDirectory() ? true : false;
}
public static void main(String[] args) {
File curDir = null;
int i;
for (i = 0; i < MAX_LEVEL; i++) {
nestStat[i] = false;
}
for (i = 0; i < args.length; i++) {
if (!(args[i].substring(0, 1)).equals("-")) {
break;
}
if (args[i].equals("-f")) {
bFile = true;
continue;
}
if (args[i].equals("-l")) {
bLongFormat = true;
continue;
}
if (args[i].equals("-a")) {
bAsciiKeisen = true;
continue;
}
System.out
.println(args[i] + "は無効なオプションです\n"
+ "Usage: Java Jtree [-a] [-f] [-l] パス\n"
+ "\t-a ASCII罫線を使用します\n"
+ "\t-f 各ディレクトリのファイル名を表示します\n"
+ "\t-l ファイルサイズと更新日時を表示します");
System.exit(1);
}
curDirName = (args.length == i) ? "." : args[i];
curDir = new File(curDirName);
if (curDir.isDirectory() == false) {
System.out.println(curDirName + "is not directory.");
System.exit(1);
}
curDirName = curDir.getAbsolutePath();
System.out.print(curDirName);
printFileSizeAndDate(curDir);
firstLevel = getDirLevel(curDirName) + 1;
printDirs(curDirName);
}
private static String replaceString(String s, String from, String to) {
StringBuffer sb = new StringBuffer(s);
int idx;
while (true) {
idx = (sb.toString()).indexOf(from);
if (idx == -1) {
break;
}
sb = sb.replace(idx, idx + 1, to);
}
return sb.toString();
}
private static void printKeisen(String k) {
if (bAsciiKeisen) {
k = replaceString(k, " ", " "); // 全角の空白をASCIIへ
k = replaceString(k, "│", "| ");
k = replaceString(k, "└", "+-");
k = replaceString(k, "├", "|-");
k = replaceString(k, "─", "--");
}
System.out.print(k);
}
private static int getDirLevel(String dir) {
int i;
int n = 0;
String sub = null;
for (i = 0; i < dir.length(); i++) {
sub = dir.substring(i, i + 1);
if (sub.equals("/") || sub.equals("\\")) {
n++;
}
}
return n;
}
private static void prtLine(int nlevel) {
int i;
for (i = firstLevel; i < nlevel; i++) {
printKeisen((nestStat[i] ? "│" : " ") + " ");
}
}
private static void printFileSizeAndDate(File file) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date lastModified = null;
if (bLongFormat) {
lastModified = new Date(file.lastModified());
System.out.println(", " + file.length() + ", "
+ sdf.format(lastModified));
}
else {
System.out.println("");
}
}
private static boolean isLastDir(String path, String[] name, int index) {
File file;
for (; index < name.length; index++) {
file = new File(path + "/" + name[index]);
if (file.isDirectory()) {
return false;
}
}
return true;
}
private static void printDirs(String path) {
String[] dirList = null;
String fileName = null;
File file = null;
int i;
int nLevel;
nLevel = getDirLevel(path) + 1;
dirList = (new File(path)).list(new Jtree());
if (null == dirList) {
System.out.println("E: " + path + "にアクセスできません");
return;
}
curDirName = path;
java.util.Arrays.sort((Object[])dirList, (Comparator)(new Jtree()));
for (i = 0; i < dirList.length; i++) {
fileName = path
+ ((path.substring(path.length() - 1)).equals("/") ? "" : "/")
+ dirList[i];
file = new File(fileName);
nLevel = getDirLevel(fileName.toString());
nestStat[nLevel] = true;
prtLine(nLevel);
if (file.isDirectory() == true) {
printKeisen(((i == (dirList.length - 1)) ? "└" : "├")
+ "─");
System.out.print(dirList[i]);
printFileSizeAndDate(file);
if (i == (dirList.length - 1)) {
nestStat[nLevel] = false;
}
printDirs(fileName.toString());
}
else {
printKeisen((isLastDir(path, dirList, i + 1)
? " " : "│") + " ");
System.out.print(dirList[i]);
printFileSizeAndDate(file);
if (i == (dirList.length - 1)) {
nestStat[nLevel] = false;
prtLine(nLevel);
System.out.println("");
}
}
}
}
}