- PR -

C# 複数のファイルの更新日時を取得するには

投稿者投稿内容
ぶぎ
会議室デビュー日: 2005/12/20
投稿数: 6
投稿日時: 2005-12-21 20:32
はじめまして。C#をはじめたばかりの初心者です。
フォルダを指定して、複数のファイルの更新日時を取得するプログラムを作成しています。ひとつのファイルの更新日時を取得することはできましたが、flwt = File.GetLastWriteTime(filepath);の部分でエラーがでてしまいます。
filepathにフォルダ内のファイル全てのパスを代入しているので、うまく動かないのだと考えているのですが、、配列に代入するなど試してみましたが、うまく動きません。
複数のファイルの更新日時を取得するにはどうすればいいのでしょうか?
ご教示、よろしくお願いいたします。

今、作りかけのプログラムです。
foreach (System.IO.FileInfo fil in dirInfo.GetFiles("*.*"))
{
// 変数を宣言する
string strExt;
//拡張子を取得する
strExt = Path.GetExtension("@" + dirInfo + fil.Name);
if (strExt == ".JPG")
{
string filepath = "@" + dirInfo + fil.Name +"\n";
string[] lines = filepath.Split(new char[] { '\n' });

foreach (string line in lines)
{
DateTime flwt;
flwt = File.GetLastWriteTime(filepath);
textBox2.Text += "&tim = " + flwt.ToString("yyyyMMddHHmmss") + "&\r\n";
}
}
}
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-21 20:46
引用:

ぶぎさんの書き込み (2005-12-21 20:32) より:

strExt = Path.GetExtension("@" + dirInfo + fil.Name);
(snip)
string filepath = "@" + dirInfo + fil.Name +"n";


怖いことやってません?
dirInfo って DirectoryInfo クラスのインスタンス?
文字列の結合は & で行いましょう。

引用:

string[] lines = filepath.Split(new char[] { 'n' });


ラインフィード (\r) が残っているとかじゃないですよね?

引用:

flwt = File.GetLastWriteTime(filepath);


この時のファイル パスを検証すれば済みそうな話ですが...
妙な文字列が入っておりませんか?

引用:

flwt = File.GetLastWriteTime(filepath);の部分でエラーがでてしまいます。


「エラー」というか「例外」の詳細を教えてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-12-21 21:43
引用:

foreach (System.IO.FileInfo fil in dirInfo.GetFiles("*.*"))



あとで拡張子がjpgのものに対して処理するコードになってますが、それならこの時点でフィルタしてしまえば良いんではないでしょうか。

引用:

strExt = Path.GetExtension("@" + dirInfo + fil.Name);


引用:

string filepath = "@" + dirInfo + fil.Name +"\n";


引用:

flwt = File.GetLastWriteTime(filepath);



FileInfoインスタンスには、Extensionプロパティ、FullNameプロパティ、LastWriteTimeプロパティがあるのでそちらを使ったほうが自然でしょう。
ファイルパスの先頭にわざわざ @ を付加していますがこれは何故でしょう。これではパスとして認められないと思いますが。
またなぜ末尾に改行記号をつけているのでしょうか。なんかforeachの働きを把握しきれていないようにも見えますが。

引用:

string[] lines = filepath.Split(new char[] { '\n' });



ファイルパスに改行記号は使えませんから、ここでSplitの対象になるのはさっき付けた末尾のものだけになりますよ?
さらに末尾に改行記号があるため、最後尾要素は空文字列になってしまいます。

引用:

textBox2.Text += "&tim = " + flwt.ToString("yyyyMMddHHmmss") + "&\r\n";



コントロールに触るのは最小限にすべきです。
この場合なら、それぞれの値をstringやSystem.Text.StringBulderなどに書き溜め、全て足し終わってから最後に一度だけTextプロパティに書き込むようにした方がいいでしょう。



引用:

じゃんぬねっとさんの書き込み (2005-12-21 20:46) より:

文字列の結合は & で行いましょう。



C#ですから、文字列結合は + で良いですよー。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-21 22:07
引用:

Hongliangさんの書き込み (2005-12-21 21:43) より:

C#ですから、文字列結合は + で良いですよー。


すいません、しっかり見ていませんでした。
"@" も、テストデータのパスを隠しただけかと解釈してました。
(しっかり見ていないことがバレバレ... orz)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ぶぎ
会議室デビュー日: 2005/12/20
投稿数: 6
投稿日時: 2005-12-21 23:10
じゃんぬねっとさん、Hongliangさん返信ありがとうございます。

>>じゃんぬねっとさん
>strExt = Path.GetExtension("@" + dirInfo + fil.Name);
>string filepath = "@" + dirInfo + fil.Name +"n";

怖いことなんでしょうか?^^;
勝手に省略してしまったのですが、dirInfoにファイル一覧を表示させているつもりでいました。
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"D:\\\\フォルダ\\\\フォルダ\\\\");
//フォルダ内のファイル一覧

>ラインフィード (\\\\r) が残っているとかじゃないですよね?

文字列をわけて、flwtに代入すればうまく動くかと思ったのですが・・・。全く意味のないことかもしれないです。

>この時のファイル パスを検証すれば済みそうな話ですが...
>妙な文字列が入っておりませんか?

filepathの中には、フォルダの中のファイルのパスが出力されるようにしたつもりです。

エラーとはデバックしてプログラムを動く途中で黄色くラインが引かれて"指定されたパスのフォーマットはサポートされていません。"とでてしまいます。

説明不足ですみませんでした。


>>Hongliangさん

>あとで拡張子がjpgのものに対して処理するコードになってますが、それならこの時点でフィルタしてしまえば良いんではないでしょうか。

フィルタを知らなかったので、調べてやってみます。

>FileInfoインスタンスには、Extensionプロパティ、FullNameプロパティ、LastWriteTimeプロパティがあるのでそちらを使ったほうが自然でしょう。
>ファイルパスの先頭にわざわざ @ を付加していますがこれは何故でしょう。これではパスとして認められないと思いますが。
>またなぜ末尾に改行記号をつけているのでしょうか。なんかforeachの働きを把握しきれていないようにも見えますが。

foreachの動きはまだいまいちわかっていないのが正直なところです。わざわざ@をつけたのはファイルパスにするためだったのですが、私の勘違いだったようですね^^;

>ファイルパスに改行記号は使えませんから、ここでSplitの対象になるのはさっき付けた末尾のものだけになりますよ?
>さらに末尾に改行記号があるため、最後尾要素は空文字列になってしまいます。

ファイルパスの後の改行はSplitで文字列を分けるためだけにつけました^^;
DateTime型のflwtにひとつずつ入れてforeachでまわして代入すればうまく動くのかなと思いまして。
ファイルパスには改行記号は使えなかったんですね・・・勉強になります。

>コントロールに触るのは最小限にすべきです。
>この場合なら、それぞれの値をstringやSystem.Text.StringBulderなどに書き溜め、全て足し終わってから最後に一度だけTextプロパティに書き込むようにした方がいいでしょう。

なるほど・・・。参考にさせていただきます。

一昨日からずっと考えていて出来なかったので、お二人の指摘を受けて、いろいろ調べてもうちょっと考えてみようと思います。ありがとうございます。
未記入
会議室デビュー日: 2005/10/01
投稿数: 7
投稿日時: 2005-12-21 23:28
[quote]
ぶぎさんの書き込み (2005-12-21 23:10) より:

勝手に省略してしまったのですが、dirInfoにファイル一覧を表示させているつもりでいました。
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"D:\\フォルダ\\フォルダ\\");
[/quote]

System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"@D:\\フォルダ\\フォルダ\\\n");

ってなってる?

[ メッセージ編集済み 編集者: 未記入 編集日時 2005-12-21 23:30 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-12-22 01:20
引用:

ぶぎさんの書き込み (2005-12-21 23:10) より:

怖いことなんでしょうか?^^;
勝手に省略してしまったのですが、dirInfoにファイル一覧を表示させているつもりでいました。


省略はまずいですね。
FullName プロパティを使うべきです。

引用:

フィルタを知らなかったので、調べてやってみます。


サンプルです。

  ディレクトリ (フォルダ) 内のすべてのファイルを取得する

ワイルド カードとかパターンマッチングという言葉で検索すれば、すぐに判るかと思います。

引用:

foreachの動きはまだいまいちわかっていないのが正直なところです。わざわざ@をつけたのはファイルパスにするためだったのですが、私の勘違いだったようですね^^;


逐語的文字列リテラル (@) について、勘違いをなさっているようですね。
「エスケープシーケンス」はご存知ないのでしょうか?
文字列内で '¥' を表現する場合は "C:¥¥Hog¥¥" というように '¥¥' と書かなければなりません。
逐語的文字列リテラルを使えば、@"C:¥Hoge¥" のように書くことができます。

(説明中のパス区切り文字の '¥' は全角を使っています)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ぶぎ
会議室デビュー日: 2005/12/20
投稿数: 6
投稿日時: 2005-12-22 02:54
じゃんぬねっとさん、再び返信ありがとうございます。
未記入さん、返信ありがとうございます。

みなさんのご指摘のとおり、@の使い方がまずかったみたいです。
@を消したら、ちゃんと動きました。

dirInfo="@D:\フォルダ\フォルダ\・・・"; になってて、さらにfilepath = "@"+ dirInfoとしてたので、@@がふたつあって動かなかったみたいです。

いろいろあまり知らなかったエスケープシーケンスとかいろいろ調べて復習しときます^^;

皆さん、ありがとうございました。

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