• 締切済み

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

私は今、特定のフォルダにあるファイル(ファイル名はすべて日付 例: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

  • デスクトップ上の全ファイル取得

    開発環境 WindowsXP,SP2 Visual Studio 2005 VC++ SDK SHGetFolderPath()でデスクトップのパスを取得した後、FindFirstFileによってデスクトップ上の全ファイル及びディレクトリの名前を取得したいと考えております。 SHGetFolderPathで取得したパスは、 C:\Documents and Settings\...\デスクトップ となっており、この文字列をwsprintfで次のように加工しました。 wsprintf(output,"%s\\*.*","C:\Documents and Settings\...\デスクトップ"); このoutputをFindFirstFile,FindNextFile,FindCloseを組み合わせたプログラムでディレクトリ内の全てのファイル及びディレクトリの名前を取得しています。 このプログラムは普通(?)のディレクトリでは有効で、こちらの期待通りの動きをしてくれるのですが、取得したデスクトップのパスを渡すと、デスクトップフォルダ内にはデスクトップという名前のフォルダしかないと出力されます。以下のような感じです。 調査ディレクトリ:C:\Documents and Settings\...\デスクトップ 調査結果 "C:\Documents and Settings\...\デスクトップ"ディレクトリ内のファイル及びディレクトリ:デスクトップ これはWindowsの仕様の動作なのでしょうか。 特殊フォルダであるデスクトップは、FindFirstFileでは調査出来ないのでしょうか? 他に方法はありますか? どうか教えてください。

  • VBSを利用して、ファイル名を取得

    VBSを利用して、ファイル名を取得 はじめまして VBSを利用して、ファイルのフルパスを取得したいと思っております。 具体的には、フォルダ内のファイルを1ファイルずつ取得するようなプログラムを 作成したいと思っております。 C:\TEST \2010 \aaa.csv C:\TEST \2010 \bbb.csv C:\TEST \2009 \ccc.csv C:\TEST \2008 \ddd.csv C:\TEST \2008 \eee.csv フルパスを取得したいのですが、どのようにしたら良いでしょうか。 最終的には、上記の読み込んだファイルごとにファイルの中身を1行ずつ確認して、 特定の文字が含まれているか確認をするようなスクリプトにしようと思っております。 そのため、objFS.OpenTextFile("取得フルパス",ForReading)のようにして 取得したフルパスごとに読み込みをしようと思っております。 どなたか、お手数ではございますが、ご教授願います。

  • プログラムの削除は

    WiNMXをダウンロードしたのですが、よくないということで、ファイルを削除したいのですが、コントロ-ルパネルから「プログラムの追加と削除」から削除しようと思うのですが、それらしいプログラムが見つかりませんでも、画面の右下の時刻のところにMXとあって、それをクリックすると、プログラムが立ち上がります。スタートからは削除したのですが根本的に、なされてないのでしょう。すいません。教えてください。機種はMebius PCーGP1-C5Mです。OSはXPです。

  • あるディレクトリ内のファイルをファイル名でソートして取得

    _FindFirst や FindFirstFile を使用すると指定フォルダの ファイル名を順番に取得できるのですが、ファイル名でソートされていません。 ファイル名でソートして取得する関数(API)はあるのでしょうか?

  • 削除しようとしても、削除できないファイルがあります。

    削除しようとしても、削除できないファイルがあります。 エラーメッセージ  「ファイル名.***」を削除できません。ほかの人またはプログラムによって使用されています。  ファイルをしようしている可能性があるプログラムをすべて閉じてから、やり直してください。  ネットワークにもつながっていず、 使用していたアプリケーションも全て閉じています。  削除する方法はありますか?

  • プログラムの削除

    マカフィーのSpamKillerを一度削除したいのですが コントロールパネルのプログラムの追加と削除には表示されていません。ファイル名を指定して ”全てを置換”を実行しましたが変わりません。すべてのプログラムから捜すとと確かにインストールされています。 どうしたら削除できますか?

  • ファイルの削除について

    初めて投稿します。Perl初心者です。 あるディレクトリ内のファイル(ファイル名はマシン日付.csvとなっています。例:20040906.csv)を検索し、 今日より90日前の日付を取得し、それ以前のファイルをディレクトリから削除する という操作をしたいと思うのですが。 Perlでこのようなファイル操作は可能なのでしょうか?

    • ベストアンサー
    • Perl
  • プログラムの削除について

    「プログラムの追加と削除」の、「現在インストールされているプログラム」のリストには、Cドライブのプログラムファイルに入っているものしかリストアップされないと思うんですが、別のドライブにダウンロードしてきたフリーソフト等を削除する場合、ただゴミ箱に入れちゃうだけで削除したことになるんでしょうか?それとも普通は落としたフリーソフト等も、Cドライブのプログラムファイルに入れるものなんでしょうか?

  • 拡張子CSVファイルの削除

    マイドキュメントに、.CSVファイルがあります。 種類は、Microsoft Excel CSVファイル 場所は、C:\・・・¥Owner\MyDocuments・・・ この.csvファイルは削除してもシステムに問題はないですか。またエクセルがプログラムから消えることもないですか。

  • ファイルを削除できません!

    削除したいファイルが削除できません!どうしてらよいですか? 質問です。 削除したいファイル(フォルダ)があるのですが、 ○○を削除できません。ほかの人またはプログラムによって使用されています。 ファイルを使用している可能性があるプログラムをすべて閉じてから、やりなおしてください。 と出てしまい、削除できません。ファイル名の変更もできません。 もちろん、何のアプリケーションも起動していませんので 他のプログラムによって使用されてることは絶対にありません。 コマンドプロンプトより削除しようとして操作していたのですが、 例)C:\WINDOWS>DEL <削除するファイル名> と入力後、 よろしいですか?と表示され、 (Y/N)? と表示されます。この後の操作方法が分かりません。 この段階ではまだ削除できていませんよね? 色々なサイトで検索してみても、入力後エンターで削除、 と書かれているだけで皆さんすんなりと削除できているようなんですが このメッセージは私にだけ出るんでしょうか? 削除方法を教えてください!!よろしくお願いします。

専門家に質問してみよう