プロが教えるわが家の防犯対策術!

オシロスコープからの画像データ(40kバイト程度のtifファイル)をPCのCOMポートから受信し
保存するプログラムを作成しているのですが、受信データを正しくPC上に保存できません。

具体的には下記のコードでtifファイルは作成されますが、容量が数kバイトで明らかに不足
しています。

MsgBoxを有効にして受信バッファサイズや書込み長さを確認しましたが、「OK」ボタンを押す
たびに下記の表示になります。COMポートのバッファサイズが4096バイトなので「dat.Length」
をすべて足し合わせると本来の受信データサイズになると思うのですが、PC上に作成された
ファイル容量から「dat」が常に上書きされているような気がします。

正しく保存するにはどのような修正が必要でしょうか?

【MsgBoxを有効にしたときの表示値(OKを押すたびに数値が変わる)】
「dat.Length」
183
4075
4072
4092
4088
4084
4085
4092
4059
4078
3910






「ByteToRead」
4060
1508
324
908
2334
1785
70
227
400






【作成したコード】
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As_ System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived


' シリアルポートからデータ受信
Dim dat As Byte() = New Byte(SerialPort1.BytesToRead - 1) {}
SerialPort1.Read(dat, 0, dat.GetLength(0))

'MessageBox.Show(dat.Length)
'MessageBox.Show(SerialPort1.BytesToRead)

File.WriteAllBytes("C:\test1.tif", dat)

SerialPort1.DiscardInBuffer()


End Sub


【環境】
OS:Win7
VB:2010
ポート設定:SerialPortクラス標準からポート番号以外は変更なし

A 回答 (2件)

>PC上に作成された


>ファイル容量から「dat」が常に上書きされているような気がします。

http://msdn.microsoft.com/ja-jp/library/system.i …

「新しいファイルを作成し、指定したバイト配列をそのファイルに書き込んだ後、ファイルを閉じます。 既存のターゲット ファイルは上書きされます。」
と書かれているのですから、当然かと。

OpenWrite()辺りで開いて、ファイルの末尾にシーク、書き出し。
となるかと。
# 「VB バイナリファイル 書き込み」辺りで検索すれば見つかるんじゃないですかね?
# http://msdn.microsoft.com/ja-jp/library/szz5syt3 … とか。
    • good
    • 0
この回答へのお礼

即時回答ありがとうございました。アドバイス頂いたMSDNサイト「VBでバイナリファイルに書き込む方法」の"My.Computer.FileSystem.WriteAllBytes"で無事保存できました。

念のため以下に修正コードを記載させていただきます。この質問にたどり着いた皆様の役に立てれば幸いです。


My.Computer.FileSystem.WriteAllBytes
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

' シリアルポートからデータ受信
Dim dat As Byte() = New Byte(SerialPort1.BytesToRead - 1) {}
SerialPort1.Read(dat, 0, dat.GetLength(0))

' シリアルポートからデータ受信
My.Computer.FileSystem.WriteAllBytes("C:\test1.tif", dat, True)

End Sub

お礼日時:2014/01/17 14:03

SerialPort1_DataReceivedイベントは、シリアルポートに最初の1バイト目が受信された時に発生する。


だから、SerialPort1.BytesToReadを取得した瞬間は、まだデータを受信中の可能性がある。
実際に読込んだバイト数は、SerialPort1.Read()の戻り値で確認できる。
    • good
    • 0
この回答へのお礼

アドバイスありがとうございました。イベントが発生するタイミングがとても重要という事が分かりました。

今後はデータ受信完了フラグの追加などでより完成度の高いものに仕上げて行きたいと思います。

お礼日時:2014/01/17 14:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A