- - PR -
プロセスが握っているディレクトリの強制排除
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-02-21 10:07
なんかいっぱい書き込みがあるなあと思ってたら、
プログラムの中で対処したかったんですね。 気づかなかったよ (´・ω・`) シャボーン もうしわけないです。 | ||||||||||||
|
投稿日時: 2009-02-21 13:35
プロセスでファイルを扱う場合に、絶対パスを指定しない時があります。それでもファイルにアクセスできるのは、プロセスがどこかのディレクトリをワーキングディレクトリとして押さえているからです。これは、System.IO.Directory.GetCurrentDirectory メソッドで確認できます。 将来的に、C ドライブに書き込みができるか、C ドライブがあるか、保障されません。一時ファイルの置き場所は、System.IO.Path.GetTempPath メソッドで取得します。
同じように、もう一つの、作るほうのスレッドも、作り終わった時点でどこにいるのか、表示させてみてください。 最初に、SaveFileDialog などで、ディレクトリを選んでいないでしょうか?もしそうなら、RRestoreDirectory プロパティ<microsoft.com> を true にすれば、解決できるかもしれません。 | ||||||||||||
|
投稿日時: 2009-02-21 16:59
ご回答ありがとうございます。はまってます・・。
教えていただいたようにパスを調べました。下記が両処理部のソースですが、 両方とも@の前後で確認しました。 Directory.GetCurrentDirectory(); "C:\\WINDOWS\\system32" Path.GetTempPath(); "C:\\Documents and Settings\\LocalService\\Local Settings\\Temp\\" ですが、全てこの値に変わりませんでした・・。 元々、Java上がりでして、カレントを移すというような発想もありませんでして・・。 他の部分も意図的に変えていないと思います。 ●生成部(Thread1) //フォルダの存在チェック(無ければ作成する) if (System.IO.File.Exists("C:/tmp" + "/back") == false){ System.IO.Directory.CreateDirectory("C:/tmp" + "/back"); } //出力先PDFファイル名作成 _outputfile = "C:/tmp" + "/back" + "/test.pdf"; //PDFファイル移動 File.Move(realfile, _outputfile); ←@両方ともフルパス指定 ●バックアップ処理部(Thread2) string work_dir = Path.Combine(Path.GetTempPath(), "PDF_test"); foreach (string fName in Directory.GetDirectories(work_dir)) { foreach (string fileName in Directory.GetFiles(fName)) { string bk = Path.Combine(pdfback_dir, Path.GetFileName(fName)); if (Directory.Exists(bk) == false) { Directory.CreateDirectory(bk); } bk = Path.Combine(bk, Path.GetFileName(fileName)); if (File.Exists(bk) == true) { File.Delete(bk); } File.Copy(fileName, bk); File.Delete(fileName); } // ここで、現在のディレクトリを表示させてみる MessageBox.Show(Directory.GetCurrentDirectory); Directory.Delete(fName, true); ←ここで、以下のエラーが出てます。 @ } ちなみに生成部で、ファイル作成後このディレクトリを削除しました所、正常に削除されました。 やはり、Threadが原因の削除不可が起きてる気がするのですが・・。 また、Javaですと、ディレクトリの保持、streamの開放漏れなど、ファイル・ディレクトリ操作ではありますが、C#は全てフルパスの文字列なんですよね(私の場合のみかもしれませんが・・)。 ソースで対応しようにも糸口が見つからない状態です・・。 また、どこかお気付きになりましたら、どうぞよろしくお願いします。 >ほったてさん 教えていただきありがとうございます。他ツールのインストールはちょっと考えてませんでした。 最悪、batでもできる事ですし。不思議なのはエクスプローラからは削除できるんですがね・・。このアプリが稼動中でも・・。?? | ||||||||||||
|
投稿日時: 2009-02-22 11:08
まずは、情報を正しく伝えることが大事だと思います。
この時点で「同じプログラムの別のスレッドでコピーと削除をしている」という意図を読むのは少々無理があったかもしれません。 件名も「プロセスが握っているディレクトリの強制排除」なのもあり、私は「別Thread」は「別のプログラム」と読みました。 別のプロセスではなく、別のスレッドでコピーと削除を行っているという話が正しく言及されたのは以下の投稿だと思います。
原因を推測すると、削除スレッドが削除を行う前にコピースレッドがディレクトリを使用している可能性があるため、削除できないのではないかと思います。ただ、そこに行き着くまでの流れが曖昧だったのでいろいろな提案がなされたのだと思います。 こちらのスレッドで、ぴあちゃんさんに指摘を受けていますが、それが生かされていないようです。
こちらのスレッドはこれで投稿が止まっていますが、解決されたのでしょうか。スレッドを放置して他の質問をするのはあまり良いとは思えません。 _________________ ぽぴ王子@わんくま同盟 ぽぴ王子の人生プログラミング中 / ぽぴンち。 | ||||||||||||
|
投稿日時: 2009-02-22 19:34
>ぽぴ王子さん
ありがとうございます。 表現が悪く、申し訳ありませんでした。過去質問したお題についても、忘れていました。 もうしわけありませんでした。 また、「プロセスが握っているディレクトリの強制排除 」をソース上で実現できるのかも分からない状態ですが、こちらは可能でしょうか? | ||||||||||||
|
投稿日時: 2009-02-22 21:44
ここ、次のようにしてみたら、どうなります?
| ||||||||||||
|
投稿日時: 2009-02-22 23:29
ありがとうございます。
教えていただいたようにしてみたのですが、現象は同じでした。 どうも、Threadが自身で生成したディレクトリを暗黙的に保持しているように感じます。 と言いますのも、前述の「●生成部(Thread1)」内でこのディレクトリをインターバルを介して、削除を行うとすんなりできました。 特に、属性を変更したり、カレントディレクトリを再セットしていません。 そうしますとこのプログラムが動作している上で、エクスプローラ上で削除できると言う現象が説明できませんが・・。 (Windowsが握っているのでは無く、.netFrameworkが握っている?) これで、「●バックアップ処理部(Thread2)」はファイルの移動だけ、「●生成部(Thread1)」の前で、ファイルが一枚も無い場合にそのディレクトリは削除と言うようにすれば解決はできそうです。 ただ、Thread内で生成したディレクトリは、他ディレクトリでは削除できないと言うことになりますと、今後も問題が出てきそうなので、同じような仕様経験があり、その時の現象・対処法を教えていただけるとありがたいです。 (ちなみに生成したファイルはバックアップ処理(別プロセス)で削除できてるんですが・・。) ・同アプリ内で複数Threadを使い、ディレクトリ操作を行っている。 ・それぞれ別Threadで同じディレクトリに対し、作成・削除を行っている。 [ メッセージ編集済み 編集者: 未記入 編集日時 2009-02-23 10:22 ] | ||||||||||||
|
投稿日時: 2009-02-24 12:22
それでは、それぞれのスレッドが実際に作業を行っている期間が重なっていないか、確認してみてください。
File.Move 中にディレクトリが消されたら、まずいですよね? # realfile から直接 pdfback_dir へコピーしたら良いんじゃない? |