C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: GetDirectoriesで取得されるフォルダについて


(過去ログ 101 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■60381 / inTopicNo.1)  GetDirectoriesで取得されるフォルダについて
  
□投稿者/ M.U (5回)-(2011/06/30(Thu) 17:52:45)

分類:[C#] 

開発環境:WindowsXP SP3、VisualStudio2005 SP1
実行環境:Windows7 SP1

お世話になります。
Windows7環境にて下記プログラムを実行すると、存在しないディレクトリが表示されます。

using System;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DirectoryInfo di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
            foreach (DirectoryInfo dinfo in di.GetDirectories())
            {
                Console.WriteLine(dinfo.FullName);
            }
        }
    }
}

実行結果
C:\Users\ユーザ名\Documents\My Music   ※存在しない
C:\Users\ユーザ名\Documents\My Pictures ※存在しない
C:\Users\ユーザ名\Documents\My Videos  ※存在しない
C:\Users\ユーザ名\Documents\Visual Studio 2005

しかし、「My Music」や「My Pictures」は存在しないため、「dinfo 」から
GetFiles関数などでファイル情報を取得しようとすると実行時エラーになります。
エラー内容「'C:\Users\ユーザ名\Documents\My Music'へのアクセスが拒否されました。」

存在しないディレクトリが列挙される理由、回避方法など分かりましたら教えてください。
ちなみに、最終目的はDocumentsフォルダのサイズ取得です。

引用返信 編集キー/
■60387 / inTopicNo.2)  Re[1]: GetDirectoriesで取得されるフォルダについて
□投稿者/ 魔界の仮面弁士 (2232回)-(2011/06/30(Thu) 20:57:56)
No60381 (M.U さん) に返信
> C:\Users\ユーザ名\Documents\My Music   ※存在しない
> C:\Users\ユーザ名\Documents\My Pictures ※存在しない
> C:\Users\ユーザ名\Documents\My Videos  ※存在しない
> C:\Users\ユーザ名\Documents\Visual Studio 2005
> しかし、「My Music」や「My Pictures」は存在しないため、
存在はしています。ジャンクションとしてですけれども。

コマンドプロンプトを起動して、
 cd "C:\Users\ユーザ名\Documents"
で Documents ディレクトリーに移動した後、
 dir /aL
というコマンドを実行してみてください。
再解析ポイント(リパースポイント)が表示され、Documents の下に
"My Music"、"My Pictures"、"My Videos" がジャンクションとして
登録されていることを確認できるかと思います。

http://www.atmarkit.co.jp/fwin2k/win2ktips/991fjunction/fjunction.html

また、上記の Documents ディレクトリー上から、
 cd "My Pictures"
を実行すれば C:\Users\ユーザ名\Documents\My Pictures\ に移動し、さらに
 echo test>sample.txt
とすれば、ライブラリ\ピクチャの仮想フォルダに sample.txt が出現します。


> GetFiles関数などでファイル情報を取得しようとすると実行時エラーになります。
たとえ存在していたとしても、権限不足等によって例外が発生する事はあるので、
いずれにしても、catch 処理はあった方が良いかと思います。

> 存在しないディレクトリが列挙される理由、回避方法など分かりましたら教えてください。
FileAttributes fa = File.GetAttributes(dinfo.FullName);
Console.WriteLine(string.Format("{0} - {1}", dinfo.FullName, fa));
を実行してみてください。今回該当する物については、ReparsePoint の
属性が付与されているかと思います。


> 最終目的はDocumentsフォルダのサイズ取得です。
一見すると簡単な処理ではありますが、実は求める精度によっては、
いろいろと考慮しなければならない事があったりします。

たとえばハードリンクされたファイルにおいては、一つのファイルに
複数のパスが割り当てられる事があります。そうした場合に、サイズを
重複カウントするべきか否か(実際に消費するのは一つ分)とか、
スパースファイルの扱いはどうするのかとか、名前付きストリームを持つ
ファイルの場合、主ストリーム以外のサイズも考慮するのか、とか…。

http://tmz.skr.jp/mini/sparse.html
http://msdn.microsoft.com/ja-jp/library/ms810604.aspx
http://www.atmarkit.co.jp/fwin2k/win2ktips/991fjunction/fjunction.html


そうした細かい点を考慮する必要が無いのであれば、先の FileAttributes と
権限不足によるエラーを無視しながらサイズを集計していくことで、
合計サイズを得られるかと思います。
引用返信 編集キー/
■60392 / inTopicNo.3)  Re[2]: GetDirectoriesで取得されるフォルダについて
□投稿者/ M.U (7回)-(2011/07/01(Fri) 09:11:02)
No60387 (魔界の仮面弁士 さん) に返信

返答ありがとうございます。

> コマンドプロンプトを起動して、
>  cd "C:\Users\ユーザ名\Documents"
> で Documents ディレクトリーに移動した後、
>  dir /aL
> というコマンドを実行してみてください。
確認しました。確かに、<JUNCTION>として3個のディレクトリが表示されました。

>>GetFiles関数などでファイル情報を取得しようとすると実行時エラーになります。
> たとえ存在していたとしても、権限不足等によって例外が発生する事はあるので、
> いずれにしても、catch 処理はあった方が良いかと思います。
System.IO.Directory.Existsではtrueが返されたので、対応に困っていました。
権限不足なども考慮して例外処理で対応すべきなのですね。

>>存在しないディレクトリが列挙される理由、回避方法など分かりましたら教えてください。
> FileAttributes fa = File.GetAttributes(dinfo.FullName);
> Console.WriteLine(string.Format("{0} - {1}", dinfo.FullName, fa));
> を実行してみてください。今回該当する物については、ReparsePoint の
> 属性が付与されているかと思います。
属性で判断できるのですね。さっそく試してみます。

>>最終目的はDocumentsフォルダのサイズ取得です。
> 一見すると簡単な処理ではありますが、実は求める精度によっては、
> いろいろと考慮しなければならない事があったりします。
なるほど、そんなに単純な話ではないんですね。簡単に考えすぎていました。
サイズ取得の目的がファイルのコピー時間を見積もるためであり、
あまり高い精度は求められていないため、ひとまずはご提示いただいた方法で
試してみます。

魔界の仮面弁士さん、詳細な回答ありがとうございました。
※スパースファイルや名前付きストリームなど、存在自体知りませんでした。勉強になりました。
 簡易的な容量チェックが出来たら次のステップとしてそれらの対応に挑戦してみます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -