- PR -

ファイル階層を読み込んでファイルのパスを全て取得したいですが

投稿者投稿内容
タラン
大ベテラン
会議室デビュー日: 2004/03/17
投稿数: 138
投稿日時: 2004-06-24 16:56
お世話になります。

Rootからファイルの階層をみて全てのファイルのパスを取得したいです。
でもちょっと悩んでいるのは
Dirの中にまたDirがあるかもしれませんし、その階層が何階層か決まっているわけでもないのでどういうふうなロジッグにすればいいか分からなくて困っています。

Rootの下にDirがA、B、Cあって
Aの下にはDirがa,b,cあって
Bには。。。
Cには。。

こういう風に考えるとめちゃくちゃになっちゃいまして。。。

Vectorなどに入れてやろうと思っていますが

なかなか難しいです。

どうすれば一番簡単に的確にできますでしょうか。

ご指導よろしくお願いします




Cluster
ぬし
会議室デビュー日: 2003/03/06
投稿数: 289
お住まい・勤務地: 大阪
投稿日時: 2004-06-24 17:18
再帰(recursive)って、ご存知ですか?
プログラムロジック的には難度は高めですが、こういうときには便利です。

#ちなみに、Javaの用語ではなく、プログラミングでの一般用語です。

http://www.rsch.tuis.ac.jp/~ohmi/software-intro/recursive.html
に、解説を見つけました。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-06-24 17:39
私はJavaはほとんど知らないのでコードは示せませんが、アルゴリズムとしては木の走査の話ですね。
Javaのコードでどう書くかではなく、まず考え方を理解されるとよろしいかと思います。

ディレクトリのパスを引数に渡すと、それ以下の全てのファイルのパスのリストを返す関数(f()と呼びます)を作ります。
すると、取得する側ではRootを引数に渡してf()を呼び出してやれば全てのファイルのリストが取得できますよね。
で、f()の実装はどうするかというと、引数で渡されたディレクトリの中に存在するファイルの一覧と、ディレクトリ以下の全てのファイルの一覧を返してやればOKですよね。
ファイルの一覧は問題なく取得できますが、ではディレクトリ以下の全てのファイルの一覧はどう取得するかというと・・・もうそのための関数f()を作っているわけじゃないですか。
つまりf()の中でf()を使って仕事をすることになります。
これが再帰関数呼び出しというやつです。

アルゴリズムは良いプログラムを作る上で大事なものですので、「アルゴリズム」と「データ構造」について書かれた書物などを読んでみるとレベルアップできるかと思います。

[ メッセージ編集済み 編集者: 一郎 編集日時 2004-06-24 17:40 ]
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2004-06-24 17:42
jakarta commons IO に...。

でも自作してみるのもいいプログラム演習になりますね。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2004-06-24 17:47
Javaで再起をしたことなかったので勉強がてらにつくってみました。
Win環境限定で作っちゃったので、パスの記号とかWin用ですが・・・(^^;

コード:
public class TestDirectory {


    public static void main(String[] args) {
        //結果が入る利sと
        ArrayList list = new ArrayList() ;
        
        //検索開始
        getData("D:\\",0, list) ;
        
        //結果を表示
        for( int i = 0 ; i < list.size() ; i++ ) {
            System.out.println((String)list.get(i)) ;
        }
        
    }
    
    private static void getData(String targetPath, int nest, ArrayList list) {
        
        //指定されたパスのFileオブジェクトを取得する
        File target = new File(targetPath) ;
        
        //指定されたパスにある ディレクトリ・ファイルの配列を取得する
        File[] children = target.listFiles() ;
        
        
        if( children == null) {
            return ;
        }
        
        //要素数分ループ
        for( int i = 0 ; i < children.length ; i++ ) {
            
            //n番目の要素がディレクトリだったら
            if( children[i].isDirectory()) {
                //リストにディレクトリ名を設定                
                list.add(addSpace(nest) + children[i].getPath() + "\\") ;
                //この要素のパスを引数にして自分自身の関数を呼び出す
                getData(children[i].getPath(),nest+1, list) ;
            //ディレクトリじゃなかったら
            } else {
                //リストにファイル名を設定
                list.add( addSpace(nest) + children[i].getPath() + "\\" + children[i].getName()) ;
            }
            
        }

    }
    
    //ただネスト数分ハイフンを付加するだけ
    private static String addSpace(int nest) {
        StringBuffer buf = new StringBuffer() ;
        for( int j = 0 ; j < nest ; j++ ) {
            buf.append("--") ;
        }
        return buf.toString() ;
    }

}



こんなんでお役に立てれば幸いですが・・・。
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2004-06-24 18:12
くっだらないことですが,ちょっと気になったので確認させてください。

オブジェクト指向だと,あるメソッドから同じメソッドを呼んでも
対象となるインスタンスが違ってくる場合がありますよね。
そういう場合は「再帰」って呼んでいいんでしょうか?

# 再帰は『自分自身を呼び出す』という説明がよくされますが,
# インスタンスが違うと『自分自身』って感じがしなくて・・・



[ メッセージ編集済み 編集者: raccoon 編集日時 2004-06-24 18:15 ]
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2004-06-24 18:14
「ネストの上限が不確定なので再帰で書くは不適切では ?」と発言しようとしたら、commons IO も再帰で実装していますね...。実用上はあまり問題にならないのでしょうけれど。

最初は再帰で実装して、再帰を使わないように書き換えるのもいい演習になりますね
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-06-24 19:27
ちなみに、パスの区切りは File.pathSeparetor とかを使うと環境依存じゃないコーディングにできます。
http://java.sun.com/j2se/1.3/docs/api/java/io/File.html#pathSeparator

スキルアップ/キャリアアップ(JOB@IT)