none
Using句を使ったファイル出力でデータ混線 RRS feed

  • 質問

  • VB 2010を使っています。

    プログラム内部で、2つのファイル出力をしており、それぞれUsing句を利用しています。

    Using writerA As New StreamWriter("ファイルA", True, Encoding.GetEncoding("shift_jis"))
         writerA .Write(dataA)
    End Using

       ・・・

    Using writerB As New StreamWriter("ファイルB", True, Encoding.GetEncoding("shift_jis"))
         writerB .Write(dataB)
    End Using

       ・・・


    上記の2つのUsing句は、プログラム内の複数箇所で利用されており、その都度、dataA、dataBは異なっています。
    存在場所は、同じSubプロシージャ内にあったり、別のSubプロシージャ内にあったりします。
    なお、2つのUsing句がネストすることはありません。

    この状況で、ごくまれにおかしな現象が生じています。
    ファイルBの中に、dataAが混入してしまいます。

    上記コーディングに、何か不足していたり、根本的に間違っていることがあるのでしょうか?

    よろしくお願いいたします。


    doratch


    • 編集済み doratch 2012年7月18日 0:50 スクリプトに誤記(writer_log)があったため修正
    2012年7月18日 0:11

回答

  • > 上記の2つのUsing句は、プログラム内の複数箇所で利用されており、その都度、dataA、dataBは異なっています。

    ここが少し気になります。dataA、dataB のインスタンスが中間処理で入れ替わってませんか?いったんリファクタリングでメソッドを整理してみるといいと思います。


    ひらぽん http://d.hatena.ne.jp/hilapon/

    • 回答としてマーク doratch 2012年7月18日 11:37
    2012年7月18日 2:08
    モデレータ

すべての返信

  • > ファイルBの中に、dataAが混入してしまいます。

    writer_logってどこでどうやって定義されているのでしょうか。
    いまそこに貼ってある内容だと、もしかして同じファイルに書き込んでるんじゃないの?という内容です。
    また、「混入」ってどういう状態でしょうか。それももう少し説明されたほうが良いです。
    普通に考えると「dataBの内容がdataAになってるから」(要するにただのバグ)と考えられますが、そちらは本当に大丈夫でしょうか。
    現状は、情報が足りないのでなんでも原因として考えられる状態だと思います。
    2012年7月18日 0:41
  • すみません、誤りがありました。

    writer_logの件ですが、正しくは以下の通りです。

    Using writerA As New StreamWriter("ファイルA", True, Encoding.GetEncoding("shift_jis"))
         writerA.Write(dataA)
    End Using

       ・・・

    Using writerB As New StreamWriter("ファイルB", True, Encoding.GetEncoding("shift_jis"))
         writerB.Write(dataB)
    End Using

       ・・・

    大変失礼しました。

    普通に考えると「dataBの内容がdataAになってるから」(要するにただのバグ)と考えられますが、そちらは本当に大丈夫でしょうか。

    これにつきましては、dataBとdataAは明らかに異なるタイプのデータですし、プログラム内でのバグの可能性も探ってみましたが、正しいと思われます。


    doratch

    2012年7月18日 0:48
  • 混乱を避けるため、元の質問文の誤記を修正させていただきました。

    ●修正前

    Using writerA As New StreamWriter("ファイルA", True, Encoding.GetEncoding("shift_jis"))
         writer_log.Write(dataA)
    End Using

       ・・・

    Using writerB As New StreamWriter("ファイルB", True, Encoding.GetEncoding("shift_jis"))
         writer_log.Write(dataB)
    End Using

       ・・・

    ●修正後

    Using writerA As New StreamWriter("ファイルA", True, Encoding.GetEncoding("shift_jis"))
         writerA.Write(dataA)
    End Using

       ・・・

    Using writerB As New StreamWriter("ファイルB", True, Encoding.GetEncoding("shift_jis"))
         writerB.Write(dataB)
    End Using

       ・・・


    doratch

    2012年7月18日 0:54
  • さすがにそういう現象に出くわしたことはありません。何か処理を書き間違えていると思いますので、コードを見直すことをお勧めします。
    2012年7月18日 0:58
  • > これにつきましては、dataBとdataAは明らかに異なるタイプのデータですし、プログラム内でのバグの可能性も探ってみましたが、正しいと思われます。

    バグじゃないとおっしゃられるならそれでも良いのですが(上記のは全然理由になっていないと思いますが)、
    その混入したと思われるデータは、プログラムのどこで書きだされたものか判断できているのでしょうか。
    そしてそこで本当に
    ・dataBに入るべき情報が入っているでしょうか
    ・writerBが正しくファイルBへのストリームになっているでしょうか
    ・間違ってwriterB(dataA)になってないでしょうか
    というのは確認されていますか。
    失礼ながら、ご返信を見る限り、やっぱりただのバグのように思いますが、
    どうしてもダメなら現象を再現できる最小限のコードを提示してみると良いと思います。

    2012年7月18日 1:15
  • ご返信ありがとうございます。

    >その混入したと思われるデータは、プログラムのどこで書きだされたものか判断できているのでしょうか。
    >そしてそこで本当に
    >・dataBに入るべき情報が入っているでしょうか

    はい、dataAとdataBは明らかに違うタイプのデータでして、dataAは、カンマ区切りのCSVデータ、dataBはHTMLを構成するデータです。

    ですので、dataBに異常値が入っていることは目視でチェックできました。

    また、ソースコードを追っている限りでは、それぞれのタイプのデータがどこで書き出されたかは判断できていまして、その処理はあっているように思えます。

    >・writerBが正しくファイルBへのストリームになっているでしょうか

    >・間違ってwriterB(dataA)になってないでしょうか

    はい、こちらも正しいです。

    ただ、目視とエディターブラウジングによってチェックしてますので、確かにご指摘のように、ただのバグを見逃した可能性も捨てきれませんが、Using句の使い方等に根本的な誤りがあるのではないかと思い、質問させていたいた次第です。

    よろしくお願いいたします。


    doratch

    2012年7月18日 1:52
  • > 上記の2つのUsing句は、プログラム内の複数箇所で利用されており、その都度、dataA、dataBは異なっています。

    ここが少し気になります。dataA、dataB のインスタンスが中間処理で入れ替わってませんか?いったんリファクタリングでメソッドを整理してみるといいと思います。


    ひらぽん http://d.hatena.ne.jp/hilapon/

    • 回答としてマーク doratch 2012年7月18日 11:37
    2012年7月18日 2:08
    モデレータ
  • あと

    > ただ、目視とエディターブラウジングによってチェックしてますので、確かにご指摘のように、ただのバグを見逃した可能性も捨てきれませんが・・・

    個人的にはただのバグの可能性が高く思われます。それを防ぐためにもテストは必要ですね。

    http://www.atmarkit.co.jp/fdotnet/chushin/chushinmeeting_05/chushinmeeting_05_02.html


    ひらぽん http://d.hatena.ne.jp/hilapon/

    2012年7月18日 2:13
    モデレータ
  • doratch さま よろしく

    Using 自体の記述に問題があるとは思えません。
    ファイルBの中に、dataAが混入 した時、直前まで書き込んでいた Data は A , B 共に問題ありませんか?
    また、書き込みを制御する変数等はちゃんと処理できていますか?
    どうも、この辺が問題 (Bug) だと思います。
     
    参考までに、上記の点を疑う根拠を以下に示します。

     Using ステートメント (Visual Basic)  の Help の中に
     Using ブロックを使えば、(中略) 。これは、StackOverflowException を除く未処理の例外の場合にも該当します。

     StackOverflowException クラス の Help の中に
     入れ子になったメソッド呼び出しが多くなりすぎ、実行スタックがオーバーフローした場合にスローされる例外。
     (中略)
     .NET Framework Version 2.0 以降は、StackOverflowException オブジェクトを、try-catch ブロックによってキャッチすることはできません

    2012年7月18日 3:10
  • リファクタリングでメソッド整理しては、とのアドバイスありがとうございます。

    恥ずかしながら、リファクタリングは使ったことはなかったので、調べてみたところ、フリーのツールもありそうですね。

    この方法からもアプローチしてみたいと思います。


    doratch

    2012年7月18日 3:33
  • ご返事ありがとうございます。

    >Using 自体の記述に問題があるとは思えません。

    そうですしたか。

    >ファイルBの中に、dataAが混入 した時、直前まで書き込んでいた Data は A , B 共に問題ありませんか?
    >また、書き込みを制御する変数等はちゃんと処理できていますか?

    この問題が起きるのはごくまれでして、幸か不幸か私の環境では再現せず、直前まで書き込んでいたA、Bについては、正しいものしかとらえられていません。

    他の方の環境でまれに発生するのですが、その方はビルドされたモジュールを使ってますので、デバッグ的なことができないのです。

    従って、今のところ、私の方でテスト回数を増やしてその現象が起こるのを捕らえて状況を検証せざるを得ませんが、気が遠くなりそうなところです。


    doratch

    2012年7月18日 3:43
  • アドバイスをくださった皆様、ありがとうございます。

    総合的に見ても、私のバグの可能性が高そうですので、アドバイスいただいたリファクタリングを使って、原因を究明していこうと思います。

    ありがとうございました。


    doratch

    2012年7月18日 11:39