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

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

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

Re[8]: テキストとバイナリの混合データの読み出し方


(過去ログ 163 を表示中)

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

■94350 / inTopicNo.1)  テキストとバイナリの混合データの読み出し方
  
□投稿者/ まどんな (3回)-(2020/04/05(Sun) 15:28:24)

分類:[.NET 全般] 


このページで
テキストとバイナリの混合データの出力の仕方を教えていただきました。

http://bbs.wankuma.com/index.cgi?mode=al2&namber=94347



逆にこのデータを読み出したい場合にはどうすれば良いですか?


        Using stream As Stream = File.OpenRead(FileOutPath)

            Using MyTxt As New StreamReader(stream, Encoding.Default)


            End Using

            Using reader As New BinaryReader(stream)



            End Using

        End Using

これでいけると思いますか?

一つ目の
End Usingでstreamは閉じてしまいませんか?

引用返信 編集キー/
■94351 / inTopicNo.2)  Re[1]: テキストとバイナリの混合データの読み出し方
□投稿者/ Hongliang (982回)-(2020/04/05(Sun) 16:17:11)
読み取りの方はバッファリングがあるから難しいですね。
StreamReaderは、内部で数百バイトとかをまずStreamから読み取って文字列に変換して内部に保持しておき、そこからReadLine()のたびに改行までのを返す、というような動作になっているので、利用者がバイナリデータを想定している部分まで元Streamから読みだされるのを阻止できません。
StreamReaderを使ってお望みの結果を得るのは不可能と考えていいでしょう。

何らかのライブラリは存在するかもしれませんが、少なくとも.NETの基本ライブラリにはStreamReader的に読み取るのとBinaryReader的に読み取るのが併存したクラスは用意されていません。

出力する形式に縛りがないのであれば、StreamWriterを使わずBinaryWriterのみを使うことで、文字列とその他バイナリを同一ストリームに出力させ、それをBinaryReaderで読み取ることができますので、まずこれを検討してみてはいかがでしょうか。
さらに抽象化を進めて、シリアライズやDBというのも考えてみてもいいかもしれません。

もちろん、そういう出力ではダメだというなら仕方ありませんが…その場合、かなり低レベルな記述が必要になるでしょう。
引用返信 編集キー/
■94353 / inTopicNo.3)  Re[2]: テキストとバイナリの混合データの読み出し方
□投稿者/ まどんな (4回)-(2020/04/05(Sun) 17:10:54)
代替案としては、
StreamReaderでテキストを読み出すときに、全テキストを結合した変数を容易しておき
最後にLenB関数で文字数を出力し、
そのバイト数の位置に移動して
StreamReaderを使えばうまくいきました。

ただ、二回同じ場所を読み込むことになり、あまりエレガントではありません。
もしもっと良い方法があれば
どなかたお教えください。

引用返信 編集キー/
■94356 / inTopicNo.4)  Re[3]: テキストとバイナリの混合データの読み出し方
□投稿者/ とっちゃん (666回)-(2020/04/05(Sun) 19:16:51)
No94353 (まどんな さん) に返信
> 代替案としては、
> StreamReaderでテキストを読み出すときに、全テキストを結合した変数を容易しておき
> 最後にLenB関数で文字数を出力し、
> そのバイト数の位置に移動して
> StreamReaderを使えばうまくいきました。
>
> ただ、二回同じ場所を読み込むことになり、あまりエレガントではありません。
> もしもっと良い方法があれば
> どなかたお教えください。
>
一度メモリに読み込んでおいて、そのメモリをメモリストリームとして再利用するというやり方もありますが
私も、ファイルフォーマット上の制約がないのなら、テキスト部分も含めてバイナリデータとして扱うほうがいいと思います。

.NET でのみ読み書きできればいいのなら、BinaryFormatter クラスを使うのはどうでしょう?

https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter?WT.mc_id=DT-MVP-32182

引用返信 編集キー/
■94359 / inTopicNo.5)  Re[4]: テキストとバイナリの混合データの読み出し方
□投稿者/ まどんな (5回)-(2020/04/05(Sun) 20:08:40)
ありがとうございます。

試してはいないのですが
BinaryFormatter クラスで保存したテキストは
テキストエディターで読んだ時に
以下のように改行されて読むことができますか?

AAA
BBB
CCC

これが文字化けなどしたら意味が無いのですが・・
引用返信 編集キー/
■94360 / inTopicNo.6)  Re[5]: テキストとバイナリの混合データの読み出し方
□投稿者/ Hongliang (984回)-(2020/04/05(Sun) 20:15:13)
まず、
・出力形式は問わないのか、特定の形式で出力されなければならないのか
・出力されたデータをテキストエディタやバイナリエディタで直接見たり編集したりする必要があるのか、単にプログラムから保存・読み込みできればいいのか
をはっきりさせましょう。
引用返信 編集キー/
■94361 / inTopicNo.7)  Re[6]: テキストとバイナリの混合データの読み出し方
□投稿者/ まどんな (6回)-(2020/04/05(Sun) 22:08:40)
・出力形式は問わないのか、特定の形式で出力されなければならないのか
・出力されたデータをテキストエディタやバイナリエディタで直接見たり編集したりする必要があるのか、単にプログラムから保存・読み込みできればいいのか

プログラムで保存・読み込みするだけでなく、
テキストエディターで閲覧できる必要があります。
編集する必要はありません。
この条件を満たせるのなら、特定の形式である必要はありません。

引用返信 編集キー/
■94362 / inTopicNo.8)  Re[7]: テキストとバイナリの混合データの読み出し方
□投稿者/ Hongliang (985回)-(2020/04/05(Sun) 23:28:37)
テキストエディタということは、
・テキスト部分が読めればいい、バイナリ部分は読める必要はない
・テキスト部分より前にバイナリ部分があるのは好ましくない
・改行は改行文字として出力される必要がある
・テキストサイズはGB単位とかになったりはしない
という感じの条件になるでしょうか。

テキストエディタで見やすいデータ構造というのは地味に厄介ですね。
代表的な構造化データであるXMLやJSONは改行の扱いがいまいちだし、各種シリアライザはヘッダとして複雑な記述を埋め込みがちだし。

テキストサイズがバイト単位で可変、文字符号化型式にUTF-8を使うとして、私なら以下のような形式を採るでしょうかね。

書き込み:
・テキスト全体をEncoding.UTF8のGetBytesを使ってバイト配列textBinaryに変換しておく
・StreamWriterで、
 ・textBinaryの長さを文字列としてまずファイルに書き込む(100バイトであれば「100」の3文字)
 ・10バイトに足りない分は空白文字を書き込む(「100」を書き込んだなら残り7文字の空白文字を書き込む)
 ・改行を書き込む
・あとはBinaryWriterでまずtextBinaryを書き出し、残りのバイナリを続けて書き出す

読み取り:
・FileStreamから、Readで10バイト読み取る
 ・読み取った10バイトをEncoding.UTF8.GetStringで文字列化し、さらにInt32.Parseで数値化する
・Seekで2バイト進める(改行文字(CRLF)を飛ばす)
・BinaryReaderを作って、まず最初に読み取った数値分のバイト配列を読み取る
 ・読み取ったバイト配列はEncoding.UTF8.GetStringで文字列に変換する
・残りはバイナリ部分なので、BinaryReaderで適宜読み取る
引用返信 編集キー/
■94363 / inTopicNo.9)  Re[8]: テキストとバイナリの混合データの読み出し方
□投稿者/ とっちゃん (667回)-(2020/04/06(Mon) 11:33:16)
No94361 (まどんな さん) に返信
> テキストエディターで閲覧できる必要があります。
> 編集する必要はありません。
> この条件を満たせるのなら、特定の形式である必要はありません。
>
テキストファイルとして参照できる(後続にごみデータみたいにバイナリがついていても問題ない)
という認識でいいのでしょうか?

テキストエディタ(ビュワー)で見れるようにするためにはいくつか前提条件があります。

1. 文字コード(エンコーディング)は決まっているか?
2. 文字コードが決まっている場合、選択できるのか出来ないのか?

最低限このあたりが確定していないと、プログラムとして出力するのは結構面倒ですよ。

さて。。。バイナリフォーマットはいじくってもいいということであれば、以下のような構造はどうでしょう?

保存の時に

sw.WriteLine(text)
sw.Flush()
Dim size As sw.BaseStream.Length ' 追加
Dim bw As New BinaryWriter(stream)
bw.Write(data)
bw.Write(size) ' 追加
bw.Flush()

としてやれば、以下のようなファイル構造になります(--はブロックの境目)
--
テキストデータ部分
--
バイナリデータ部分
--
テキストデータ部分のバイト数

こうしておいて、処理としては
ファイルを一括でメモリに読み取る
メモリの最後の部分から、sizeof(long) だけ前の位置に移動し、

BinaryReader で size 文だけ読み取る。
そのサイズ先頭から、指定サイズ分のバイト配列を「別途」用意する。

別途用意したバイト配列からメモリストリームを作成し、テキストを読み取る。

最初に読み取ったバイト配列で、メモリストリームを用意し
size 文だけ位置を移動して、バイナリとして読み取る。

これで、どんな文字コードであろうと、誤変換することなく読み取りできます。

フォーマット変更は最後に追加なので、若干拡張ですがほかの部分への影響は限りなく0だと思いますよ。

引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -