• 締切済み

ファイル取得・日付比較・削除を行うプログラム

私は今、特定のフォルダにあるファイル(ファイル名はすべて日付 例:20160720.csv)をすべて取得し、取得したファイル名と現在時刻を比較し、現在時刻より1年以上過去のもの(現在が20160720だとすると20150720より古いファイル)を削除する というプログラムを作ろうとしています。(現在取り組んでいるのは取得したファイルを配列に入れて、forループで1つ1つ1年間離れているかチェックするような感じです。) ファイル取得はfindfirstfileで取得・removeで削除を行うことは調べてわかったのですが、それを使って上記のようなプログラムを作るやり方がまだわからないのです。(C・C++に触れてまだ半年ぐらいの身なので…) なるべく自分で調べて作り上げた方が自分の力になるのはわかっていますが、今回は全く思いつかないので、みなさんがどのようなコーディングをするのか、コードと解説を添えて教えて頂けるとありがたいです。 他の言語で作成する事は考えておりません。C・C++環境で動作させたいです。 開発環境はWindows 7 32bitでVisualStudio2013を利用しています。 宜しくお願い致します。

みんなの回答

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.10

>すみません。乗せ忘れていましたが、自分で作ってみたlist構造versionのソースです。 見ましたが、配列版のプログラムすら、ちゃんと理解できていないのがバレバレです。 いろいろなやりかたを、というのもわからなくはないですが、まずは配列版をしっかり理解するほうが先と思います。 実際のところ、std::listを使うのであれば、配列版もリスト版もほとんど変わりはありません。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.9

配列に入れるところまでできていますよね。 効率はひとまずおいておいて、質問者さんの当初の計画通りに書くなら、FindClose(h);の後ろから、fileTitleの中身を0からcountまでforループにして、その中で >それらをタイム型に変換した後に現在時刻と比較し、過去1年以上前のものは削除 ということでいいと思います。 対象ファイルが255を超えると困ったことになりますが、少しの改良で対処可能です。 リストを使う必要もありません。

loreley1213
質問者

お礼

すみません。乗せ忘れていましたが、自分で作ってみたlist構造versionのソースです。 void list(void) { WIN32_FIND_DATA ffd; list<string> fileList; list<string>::iterator iter; HANDLE h = FindFirstFile("ここにフォルダ"&ffd); for (iter = fileList.begin(); iter != fileList.end(); ++iter) { if (h == INVALID_HANDLE_VALUE) { FindClose(h); } while (FindNextFile(h, &ffd)); } FindClose(h);

loreley1213
質問者

補足

ご回答ありがとうございます。 おっしゃっている通りやってみようと思います。 また、何度も申し訳ないのですが、色々なやり方を覚えておきたいので、先ほど記載したプログラムを配列ではなくlist構造で記述するとどういったコードになるか教えていただけると嬉しいです…。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.8

forでなくても、whileでもif gotoでもいいんですが、FindFirstFileだけではファイル名はひとつしか取れないんで、該当するファイル名をすべて取得しようと思ったらFindNextFileと合わせてループにしなくてはならないはずですが、ちゃんと取得できているのでしょうか? まあ、ループを使わずに取得できているというのなら、それでもいいです。 そこからの改造は少しですむというのは変わりません。 よろしければ、ファイル名を取得するプログラムを見せていただけますでしょうか。 10行前後で済んでいるはずです。

loreley1213
質問者

補足

ご回答ありがとうございます。 以下がファイル名取得~配列に入れる?プログラムになります。 void deleteFiveYearsFile(void) { WIN32_FIND_DATA ffd; char fileTitle[255][MAX_PATH]; int count = 0; HANDLE h = FindFirstFile("ここにフォルダ指定", &ffd); if (h != INVALID_HANDLE_VALUE) { do { strcpy(fileTitle[count], ffd.cFileName); count++; } while (FindNextFile(h, &ffd)); FindClose(h); } } 話は少し変わりますが、休日いろいろ考えた結果、配列ではなくlist構造を使うことにしました(勿論使わずに質問文のような動作が可能ならそれがベストなのですが…)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.7

>という形ですと、for文とif文の()内の条件が上手くかけそうになかった為、今 変ですね。 ファイル取得のプログラムができているならば、for文の条件は解っているはずですよ。 ファイル取得のプログラムについて「作成できます」とありますが、実際には作成していないでしょうか? であれば、とにかく作成してみてください。それができれば、その先は難しくないはずです。

loreley1213
質問者

補足

ファイル取得は質問文にも記載している通りfindfirstfileを使っていますので、for文は使用しておりません

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.6

>配列に入れなきゃならんですか? ループの中でファイルを削除した場合のその後の挙動が定かでないので、一度配列にいれてから、後で削除したほうが無難かとおもっております。 MSDNを見ても、はっきりしたことは書いてないんですよね・・・。

回答No.5

配列に入れなきゃならんですか? for ( ディレクトリにある各ファイルについて ) {  if ( そのファイルは削除対象である ) {   そのファイルを削除する  } } じゃダメなんですか?

loreley1213
質問者

補足

お返事が遅くなって申し訳ありません。 ご回答ございます。 配列に入れる方がやりやすいのかな?という判断から配列に入れる動作を考えておりましたが、必須ではございません。 あくまでも、取得したファイル名と現在時刻を比較して1年以上過去のもの(取得したファイル名と現在時刻-1年を比較しても可)を削除したいのです。 episteme様の >for ( ディレクトリにある各ファイルについて ) {  if ( そのファイルは削除対象である ) {   そのファイルを削除する  } } という形ですと、for文とif文の()内の条件が上手くかけそうになかった為、今回、質問させて頂いた形で作ってみようという判断を致しました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>申し訳ありませんが、こちらを詳しく教えて頂きたいです…。 詳しくもなにも・・・。 要するに、ファイルが全部で1万あったとして、そのうち削除対象が千個あったとすると、ファイルを全部配列に入れようとすると、1万個分の配列が必要になりますが、削除対象のファイルだけなら、千個分の配列で済むというただそれだけですよ。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.3

>私が今1番苦戦している箇所は、取得したファイル名を配列に入れるところです。 固定配列でいいなら、strcpyでコピーしていくだけだと思いますが。 動的配列で考えているのでしょうか? いずれにしても、比較は配列に入れる前に行って、削除対象のファイルのみ配列に入れたほうがメモリの節約になると思います。

loreley1213
質問者

補足

お返事ありがとうございます。 >いずれにしても、比較は配列に入れる前に行って、削除対象のファイルのみ配列に入れたほうがメモリの節約になると思います。 申し訳ありませんが、こちらを詳しく教えて頂きたいです…。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

#1です。 ちなみに、for(またはwhile)で一つ一つチェックするのは、誰が書いても同じだと思います。 一回ソートをかけてからという方法もありそうだけど、たぶん単純に比較したほうが早い。 比較自体は単なる文字列比較で可能なので、あらかじめ1年前の文字列を作っておいて、それと比較するようにすると速いと思います。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

>ファイル取得はfindfirstfileで取得・removeで削除を行うことは調べてわかったのですが、 実際にファイル名を取得するだけのプログラムや、ファイルを削除するだけのプログラムを作ってみましょう。

loreley1213
質問者

補足

ご回答ありがとうございます。 取得と削除のプログラムは作成できます。 本文に詳しく記述していなかったのですが、取得したファイルを配列に入れて、それらをタイム型に変換した後に現在時刻と比較し、過去1年以上前のものは削除 という流れにしたいのです。 私が今1番苦戦している箇所は、取得したファイル名を配列に入れるところです。 説明不足で申し訳ありませんでした。

関連するQ&A