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

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

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

VB.NET でCSVファイルを開いた時

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■92440 / inTopicNo.1)  VB.NET でCSVファイルを開いた時
  
□投稿者/ あお (1回)-(2019/09/26(Thu) 11:38:04)

分類:[VB.NET/VB2005 以降] 

以下の構文でCSVファイルを読み込んで、閉じています。
Dim StReader1 As New System.IO.StreamReader(TextBox1.Text)
While (StReader1.Peek() >= 0)
StReader1.ReadLine()
LineCount = LineCount + 1
End While
StReader1.Close()

この処理自体はエラーなく完了するのですが、実際に読み込んだCSVファイルを手動で開いて保存しようとすると「ファイルの保存中にエラーが発生しました。
書き込みが禁止されている、他のプログラムで保護されているなどが考えられます。」というメッセージが出ました。
これはプログラムでちゃんとファイルが閉じられてないのでしょうか?
実際にプログラム自体を完全に終了させると、書き込みできるようになります。
Close処理はしているのですが、何が問題なのでしょうか?
引用返信 編集キー/
■92441 / inTopicNo.2)  Re[1]: VB.NET でCSVファイルを開いた時
□投稿者/ ぶなっぷ (211回)-(2019/09/26(Thu) 12:59:37)
状況からして、やはりClose()できていないと考えるのが妥当な気がします。
上記ソースコードはわかりやすくするため、最小限のコードにしてますよね?

実際は例外処理とかしてませんか?
例外ハンドラに飛ぶと、Close()処理が実行されません。

「Try Finally」や「Using」などを使用して、確実にClose()されるようにしましょう。
  https://www.atmarkit.co.jp/fdotnet/vb2005/vb2005_05/vb2005_05_01.html

引用返信 編集キー/
■92442 / inTopicNo.3)  Re[1]: VB.NET でCSVファイルを開いた時
□投稿者/ 大谷刑部 (19回)-(2019/09/26(Thu) 13:03:34)
No92440 (あお さん) に返信
> 以下の構文でCSVファイルを読み込んで、閉じています。
> Dim StReader1 As New System.IO.StreamReader(TextBox1.Text)
> While (StReader1.Peek() >= 0)
> StReader1.ReadLine()
> LineCount = LineCount + 1
> End While
> StReader1.Close()
>
> この処理自体はエラーなく完了するのですが、実際に読み込んだCSVファイルを手動で開いて保存しようとすると「ファイルの保存中にエラーが発生しました。
> 書き込みが禁止されている、他のプログラムで保護されているなどが考えられます。」というメッセージが出ました。
> これはプログラムでちゃんとファイルが閉じられてないのでしょうか?
> 実際にプログラム自体を完全に終了させると、書き込みできるようになります。
> Close処理はしているのですが、何が問題なのでしょうか?

実際のファイルの属性ははどうなってますか?(エクスプローラーでプロパティーを確認という意味)
それがわからないとロジックのせいでそうなってるか判断のしようがないです。
引用返信 編集キー/
■92449 / inTopicNo.4)  Re[2]: VB.NET でCSVファイルを開いた時
□投稿者/ あお (3回)-(2019/09/26(Thu) 16:06:18)
コメントありがとうございます。

ぶなっぷ様
 例外処理等はしておりません。
 上記の処理のみを実行してもファイルはcloseされていない事を確認しました。

大谷刑部様
 ファイルの属性は読取専用でもないし、隠しファイルでもなく普通のCSVファイルです。
引用返信 編集キー/
■92450 / inTopicNo.5)  Re[3]: VB.NET でCSVファイルを開いた時
□投稿者/ 大谷刑部 (20回)-(2019/09/26(Thu) 16:34:24)
No92449 (あお さん) に返信
> コメントありがとうございます。
>
> ぶなっぷ様
>  例外処理等はしておりません。
>  上記の処理のみを実行してもファイルはcloseされていない事を確認しました。
>

で、どうするつもりなのです?
ぶなっぷさんの回答の内容は試してみたのですか?
上記じゃ聞かれたことの答えになってない気がしますが。
引用返信 編集キー/
■92454 / inTopicNo.6)  Re[4]: VB.NET でCSVファイルを開いた時
□投稿者/ あお (4回)-(2019/09/26(Thu) 17:50:23)

ぶなっぷ様
プログラムを1行ずつデバッグしながら流してみて、StReader1.Close()の行は通っているのですが、それでもcloseされない事があるのですか?
Using 処理を使ってみましたが、やはり現象は解決しておりません。
引用返信 編集キー/
■92455 / inTopicNo.7)  Re[5]: VB.NET でCSVファイルを開いた時
□投稿者/ WebSurfer (1927回)-(2019/09/26(Thu) 18:26:14)
No92454 (あお さん) に返信

今のコードから問題を再現するのに不要な部分はどんどん削っていって、問題を
再現するための必要最低限にして、そのコードをここにアップして、詳細な再現
手順を書くということはできませんか?
引用返信 編集キー/
■92456 / inTopicNo.8)  Re[6]: VB.NET でCSVファイルを開いた時
□投稿者/ ぶなっぷ (212回)-(2019/09/27(Fri) 09:36:12)
確かに、私が懸念していたのは、StReader1.Close()の行を通らない可能性です。
なので、それではないことは分かりました。

でも、そうなると何が原因ですかねぇ。
私自身、ファイル系を扱うソフトウェアはC++時代から、かなり馴染みがあるん
ですが、Close()を呼んだのにロックが外れないというのは経験が無いです。

次に疑うのは、Open()とClose()の数があっていないというやつです。
その辺りから調査してみてはどうでしょうか?

引用返信 編集キー/
■92457 / inTopicNo.9)  Re[1]: VB.NET でCSVファイルを開いた時
□投稿者/ 魔界の仮面弁士 (2397回)-(2019/09/27(Fri) 11:47:47)
No92440 (あお さん) に返信
> 以下の構文でCSVファイルを読み込んで、閉じています。
> Dim StReader1 As New System.IO.StreamReader(TextBox1.Text)

New System.IO.StreamReader(TextBox1.Text)
という呼び出しは、
New System.IO.StreamReader(TextBox1.Text, Encoding.UTF8, True, 1024)
な呼び出しと同義ですね。

Shift_JIS や ASCII ではなく、UTF-8 な CSV ファイルという認識で良いでしょうか。


> というメッセージが出ました。

何が原因でしょうね。
ネットワークパスなどは用いず、ローカル HDD 上のパスを指定してみましたが、
現象を再現できませんでした。当方では問題なく閉じられています。

UAC 絡みかと思い、マニフェストで VirtualStore の有効化/無効化を
切り替えつつ、仮想化されるパスを参照させてみましたが、やはり再現しません。


> Close処理はしているのですが、何が問題なのでしょうか?

LeaveOpen モードで開いた場合に限り、StreamReader を Close あるいは Dispose したとしても、
ファイルが開きっぱなしの状態となりえます。しかしそれは、今回のケースには当てはまりません。
元質問のコードのみなら LeaveOpen は常に False 状態であり、Close 後、即座に閉じられるはず…。


ファイルパスの間違いというわけでも無さそうですし、今のところ、
 (1) 同じファイルが、他の箇所(あるいはセキュリティ系のソフトなど)でも同時に開かれていた。
 (2) 何らかの理由で Close されていない。
ぐらいしか思い当たらないです。


確認のため、
 ' 一時ファイルにコピー
 Dim tmp As String = System.IO.Path.GetTempFileName
 System.IO.File.Copy(TextBox1.Text, tmp)
 ' コピーを開く
 Dim StReader1 As New System.IO.StreamReader(tmp)
 While (StReader1.Peek() >= 0)
  StReader1.ReadLine()
  LineCount = LineCount + 1
 End While
 StReader1.Close()
 ' 一時ファイルを処分
 System.IO.File.Delete(tmp)
のようにしてみては如何でしょうか。試していませんけど。


一時ファイルから読み込んでいるなら、元ファイルが開かれたままになることも無いと思います。

また、ファイルコピーで失敗するようであれば、他の場所で同時に開かれていた可能性が浮上します。
一時ファイルを Delete できなかったとすると、セキュリティソフト等による阻害の可能性があるかも。


> 実際に読み込んだCSVファイルを手動で開いて保存しようとすると「ファイルの保存中にエラーが発生しました。

何の解決にもならないですが、手動で保存できれば良いだけなら、
 Dim StReader1 As New System.IO.StreamReader(TextBox1.Text)
のかわりに、
 Dim StReader1 As New System.IO.StreamReader(New System.IO.FileStream(TextBox1.Text, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite))
にすれば、排他制御が廃され、Close される前でも外部から書き込み可能となります。
引用返信 編集キー/
■92458 / inTopicNo.10)  Re[5]: VB.NET でCSVファイルを開いた時
□投稿者/ 大谷刑部 (21回)-(2019/09/27(Fri) 14:31:51)
No92454 (あお さん) に返信
>
> ぶなっぷ様
> プログラムを1行ずつデバッグしながら流してみて、StReader1.Close()の行は通っているのですが、それでもcloseされない事があるのですか?
> Using 処理を使ってみましたが、やはり現象は解決しておりません。

closeの後にStReader1にnothing代入してみるとか。
closeメソッドが通ってるということは、ファイル閉じてるのに使用中扱いになっているという可能性が考えられるので。
ただ、closeメソッドが実質的にdisposeをしているのだとすると、解決望み薄ですけどね。

VB6時代に、excelを閉じる時にcloseとquitを両方しても、excelがタスクとして残り、以降excelが正常に動かないときに
nothingしたら、解消したということからの連想ですけどね。
袋小路に入っているなら一度試してみてはと。
引用返信 編集キー/
■92459 / inTopicNo.11)  Re[2]: VB.NET でCSVファイルを開いた時
□投稿者/ PANG2 (319回)-(2019/09/27(Fri) 16:13:54)
Process Monitor(ProcMon)でファイルを監視する

Path | ends with | test.csv | Include

Process Monitor の基本的な使い方について
https://qiita.com/nanmei365/items/64c2b23aa49c0aa9f5e0
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ