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

わんくま同盟

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

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

■89229 / 3階層)  MemoryStreamのメモリ解放
□投稿者/ 魔界の仮面弁士 (1926回)-(2018/11/09(Fri) 10:25:11)
No89225 (小道 さん) に返信
> Geotag(t, ido, keido)
> .Save(@"C:\geotag\" + filepass + "output" + countoutput + ".jpg", ImageFormat.Jpeg);

戻り値を解放し忘れています。Hongliang さんからも
『返しているImageをDisposeしない限りはどうにもならないです』と指摘されていますよね。

 using (var img = Geotag(t, ido, keido))
 {
  img.Save(@"C:\geotag\" + filepass + "output" + countoutput + ".jpg", ImageFormat.Jpeg);
 }


ついでに、他の部分についても。


> // 不要になった時点で破棄する (正しくは オブジェクトの破棄を保証する を参照)
> folderBrowserDialog1.Dispose();
FolderBrowserDialog は IDisposable ですが、これの Dispose は必須ではないので、
この行の有無は特に影響しないはず…。


> // ダイアログを表示し、戻り値が [OK] の場合は、選択したディレクトリを表示する
> if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
>   folderpass = folderBrowserDialog1.SelectedPath;
> }
folderPath ではなく
folderpass な点に違和感が。(Pass:通り過ぎる、Path:経路,小道)

ところでキャンセルされた場合も、そのまま処理を継続して良いのですか?


> IEnumerable<string> files =
> System.IO.Directory.EnumerateFiles(folderpass, "*", System.IO.SearchOption.AllDirectories);
AllDirectories での列挙中に、アクセス権の無いパスに当たってしまった場合、
列挙処理が中断されてしまうのでご注意ください。
https://qiita.com/otagaisama-1/items/8e5022367ee13a0a0193


> string s1 = Interaction.InputBox("緯度を10進法で入力してください");
名前からすると、Microsoft.VisualBasic.Interaction.InputBox メソッドでしょうか。
(あるいは、10進数以外での入力を許容しない、独自のダイアログを表示している?)


> string passout = @"C:\geotag\";
> this.Text = "geotagimege";
> if (Directory.Exists(passout))
> {
> }
> else
> {
>   Directory.CreateDirectory(passout);
> }

少し補足しておくと、Directory.CreateDirectory メソッドは、
C:\geotag ディレクトリが存在していてもエラーにはならない仕様ですが、
C:\geotag ファイルが存在していた場合はエラーになるという点が、
見落とされがちです。ファイル操作である以上、例外処理は含めておいた方が安全です。

ただし高速化という点では、事前の Directory.Exists チェックも有効な手段と言えます。
(今回は連続した呼び出しを行っているわけでも無いので、さほど重要では無いですが)
http://mag.autumn.org/Content.modf?id=20050327144238



> double ido = double.Parse(s1);
> double keido = double.Parse(s2);
InputBox 値の検査のため、double.TryParse の利用をお奨めします。


> IEnumerable<string> files =
> System.IO.Directory.EnumerateFiles(folderpass, "*", System.IO.SearchOption.AllDirectories);
> var directory = folderpass;
> int fileCount = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly).Length;

このあたりのコードに、ちぐはぐな継ぎ接ぎ感というか、不自然さを感じます。

・folderpass と directory の使い分けの意図は何ですか?
 どちらも同じ場所を示しているようですが…。

・前者は System.IO 名前空間を「明示」して、『EnumerateFiles』を使い、
 後者は System.IO 名前空間を「省略」して、『GetFiles』を使っていますが、
 このあたり、何か意図があるのでしょうか。

・前者は AllDirectories、後者は TopDirectoryOnly の探索になっていますが
 意図的に使い分けているのでしょうか。探索深度が異なるので、
 files.Count() は fileCount 以上の値になるはずですが、
 ループ処理内の goto も含め、意図が読み取れませんでした。


> foreach(string s in files)
> {
>   string filepass = Path.GetFileName(s);
>   string passin = @"C:\geotag\" + s;

この passin は未使用ですが、何のために用意されているのでしょうか?

files には、子階層・孫階層のディレクトリのファイルも含まれるので、
GetFileName からは、別階層にあった同名ファイルが返される可能性があります。
その場合、passin が競合するパスになりえますが…。



> Bitmap t = new Bitmap(s);
なぜ using を使わないのでしょうか?

> if(count == fileCount)
> {
>   goto Exit;
> }
この場合 t.Dispose() の行が呼ばれませんが、本当にそれで良いのですか?
何故 goto が必要なのかも謎です。


> Exit:
>   MessageBox.Show("すべての写真のジオタグが完了しました。");
MessageBoxIcon も指定した方が良いかも。

>   Application.Exit();
FormClosing がキャンセルされた場合などは、Application.Exit() では
終了しないこともありますね。(引数付きの Exit メソッドを使って判定できます)
編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Re[2]: MemoryStreamのメモリ解放 /小道 返信無し
 
上記関連ツリー

MemoryStreamのメモリ解放 / 小道 (18/11/08(Thu) 19:24) #89221
Re[1]: MemoryStreamのメモリ解放 / Hongliang (18/11/08(Thu) 19:34) #89222
  └ Re[2]: MemoryStreamのメモリ解放 / 小道 (18/11/09(Fri) 08:47) #89225
    ├ MemoryStreamのメモリ解放 / 魔界の仮面弁士 (18/11/09(Fri) 10:25) #89229 ←Now
    └ Re[3]: MemoryStreamのメモリ解放 / にゃるら (18/11/09(Fri) 09:26) #89226
      └ Re[4]: MemoryStreamのメモリ解放 / shu (18/11/09(Fri) 10:43) #89230
        └ Re[5]: MemoryStreamのメモリ解放 / 小道 (18/11/09(Fri) 18:12) #89232 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信