質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

4回答

2694閲覧

ファイル削除の効率的な方法

f_tonakai

総合スコア15

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2019/07/10 14:13

システムで出力しているログを定期的に削除したいんですが、
効率的な削除方法が無いか悩んでいます。

[仕様]
1.システム起動時に、3ヶ月以上前のログファイルを削除する(3ヶ月分は消さずに置いておく)
2.ログファイル名は「aa_xxxxx_yyyymm.log (例:aa_sample_20190701.log)」
(xxxxxは5文字以上の場合あり、yyyymmはシステム起動時の日付)

[今考えている実装]

string[] files = System.IO.Directory.GetFiles( @"E:\work\Log", "*", System.IOSearchOption.AllDirectories); for(int i=0; i<files.length; i++) {  System.IO.File.Delete(files[i]); }    :  (後続の処理)    :

この場合、
1日1ログファイル生成されるとして、最低90ファイル数(1ヶ月30日として)以上あるので、
メモリで一括保持するのはどうかなと思っています。

他にいい方法はありませんか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/10 14:23

ファイルのパスを保持するだけでメモリを圧迫する可能性があるほど大量ということでしょうか?
k.matsuda

2019/07/11 08:35

参考までに ファイル名にある日付の数字から抽出するのではなく、ファイルの作成日時や更新日時を取得することも出来ます。
guest

回答4

0

ベストアンサー

100 ほどのファイル名でメモリが圧迫されるようなシステムであれば、ハードの増強が必須でしょう。この程度のメモリの使用は問題にならないと思います。
しかし、もっと大規模な使用を視野に入れて、無駄なメモリを確保したくないというのであれば、GetFiles の代わりに EnumerateFiles を使ってください。こちらは配列を返すのではなく、列挙子を返します。

例えば次のような使い方をすることによって、foreach ループが一回回るたびに該当ファイルが一つ列挙されます。
これを遅延評価といいます。

[雑記] LINQ と遅延評価

C#

1using System; 2using System.Linq; 3using System.Text.RegularExpressions; 4 5namespace ConsoleApp1 6{ 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 var regex = new Regex(@"_(\d{4})(\d{2})(\d{2}).log$"); 12 var threshould = DateTime.Today.AddDays(-90); 13 bool ShouldDelete(string path) 14 { 15 var match = regex.Match(path); 16 if (!match.Success) return false; 17 var dateOfLogFile = new DateTime( 18 int.Parse(match.Groups[1].Value), 19 int.Parse(match.Groups[2].Value), 20 int.Parse(match.Groups[3].Value)); 21 return dateOfLogFile < threshould; 22 } 23 var files = System.IO.Directory 24 .EnumerateFiles("path", "*", System.IO.SearchOption.AllDirectories) 25 .Where(ShouldDelete); 26 foreach (var file in files) 27 { 28 System.IO.File.Delete(file); 29 } 30 } 31 } 32}

投稿2019/07/10 16:01

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haruniku

2019/07/11 11:46

低評価とさせて頂きます。理由はわかりますよね?
Zuishin

2019/07/11 11:47

わかりませんね。説明してください。
Zuishin

2019/07/11 11:48

通報しておきましたので、運営が見る前に正当な理由を考えておいてください。
haruniku

2019/07/11 11:48

自分の心の中で考えて見てください^ ^
Zuishin

2019/07/11 11:49

わからないので説明してください。あなたが私よりもこの言語について詳しいのですか?
Zuishin

2019/07/11 11:52

まず、このコードが何をしているのか説明できますか?
Zuishin

2019/07/11 12:00

どうしました権左衛門さん? 一行もわからないのに低評価したのですか? 失笑
f_tonakai

2019/07/11 12:38

Zuishinさん コードまで載せて頂きありがとうございます。 試してみたいと思います ありがとうございます
pepperleaf

2019/07/11 13:30

この方法、確かに効率的、とも思ったのですが、遅延評価で、ファイル名取得中に、ファイル削除ってどうなのでしょうか? .Netの内部処理分かりませんが、Unixみたいに、ディレクトリファイルの場合、ファイル名取得中にファイル名を保持しているファイル(ディレクトリファイル)を更新する事になる気がします。
Zuishin

2019/07/11 13:55

私が試した時にはうまく動きました。確認お願いできますか?
pepperleaf

2019/07/11 13:59

ループの中で、ループ変数(オブジェクト)を変更するのに近いと思った次第。 試してみたいですが、すぐは無理そう。 ソースをみれば、早いでしょうか?
YAmaGNZ

2019/07/11 14:38

リファレンスソースをみると、列挙にはFindFirstFile、FindNextFileを利用しているようです。 フォルダ削除などで使いますし、問題はないのかなと思います。
Zuishin

2019/07/11 14:45

確認ありがとうございます。私の方も特に問題となったという情報は見つからなかったのですが、安心しました。
pepperleaf

2019/07/11 14:55

YAmaGNZさん、確認ありがとうございます。 ソースまで見れてないですが、検索してみると、同様にやっている方もあり、問題なさそうですね。(心配したけど、OKってのもあった)
guest

0

非力なPCなら、ともかく、Windows10がストレスなく使える PCならば、100ファイル程度のリストの取得は全く問題無いと思います。

今、ログファイルが 100を越えたところで、削除していますが、特に問題はありません。 ただ、テストが面倒なだけ。

投稿2019/07/10 14:27

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

f_tonakai

2019/07/10 15:15 編集

スペック的な問題はありません 削除するときには、消せないログファイルが 常に3ヶ月分(90~100程度)あるので、 単純にそれ以上のファイルリストを 作ることになります。 実装として問題ないのか気になって質問させて頂きました
guest

0

どうしてもメモリ保持したくないという要件があるとして、xxxxのところが分かると仮定すると。

今日の日付から消すべきファイルのファイル名が計算によって求まります。そのファイル名が存在するかを判定して、存在すれば消せばいいと思います。
運用にもよりますが、数日から1ヶ月分の日付のものを消すことにし、ファイルが存在しなかったときにループを中断すればループ回数も抑制できるかと。

投稿2019/07/11 14:00

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

バッチなりシェルなりで消すとか

投稿2019/07/10 15:08

YAmaGNZ

総合スコア10266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

f_tonakai

2019/07/10 15:14

bat,vbscript,shellscriptではなく c#で実装になったので、選択肢がありません shellscriptが楽だと思ってたのですが
YAmaGNZ

2019/07/10 15:23 編集

C#から、バッチファイルなりを作成し、それを実行後消すとかでもダメなんですか? まぁ、アプリ起動時だけであれば、列挙して消しても問題ないと思いますけどね。 日付がファイル名にあるので、そのフォルダ全てのファイルを列挙する必要もないでしょうし
f_tonakai

2019/07/10 22:13

日付がファイル名にあるので、そのフォルダ全てのファイルを列挙する必要もないでしょうし とは どういうことですか?
YAmaGNZ

2019/07/10 22:35

どのようなスパンでアプリを起動するのか分かりませんが、仮に1日1回は起動するというのであれば、2019/07に起動の場合、2019/03が削除対象になるのですから、*201903*.logと列挙するなりフィルタはできるのではないかと思います。 ただ、正解はZuishinさんの回答だと思いますね
f_tonakai

2019/07/11 12:37

>*201903*.logと列挙するなりフィルタはできるのではないかと思います。 なるほどです。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問