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

わんくま同盟

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

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

■87148 / 1階層)  Byte配列→文字列→Byte配列の方法策
□投稿者/ 魔界の仮面弁士 (1643回)-(2018/04/16(Mon) 15:18:41)
2018/04/16(Mon) 16:18:23 編集(投稿者)

No87146 (io さん) に返信
> あるByte配列をList of Tでリスト作成して、そのリストを使って色々しているのんですが
文字列化する意図が分からなかったのですが、File.ReadAllBytes / File.WriteAllBytes を使って、
テキストではなく、バイナリとして保持する…というわけにはいかないのですね?


> Byte配列を文字列に変更し、一旦テキストへファイルへ保存
Convert クラスの ToBase64String / FromBase64String メソッドでは駄目でしょうか?

io さんがやろうとしている方法(いわゆる hexString)では、
テキスト化に伴い、データ量が 2 倍(200%)に増加しますが、
上記(BASE64)の場合は 4/3 倍(133%) で済みます。



> @ Private recive As New List(Of Byte()) で リストを作成
> A ここに recive.Add(Byte配列)を入れていく
recive ではなく
receive なのでは、という点はさておき。

上記の変数宣言が、
 Private recive As New List(Of Byte) '(a)
ではなく、
 Private recive As New List(Of Byte()) '(b)
になっていますが、これは間違いないのですね?


(a) の場合は、単一のバイナリを蓄えるもので、たとえば
 recive.AddRange(New Byte() { &H01, &H03, &H05, &H07 })
 recive.AddRange(New Byte() { &H09, &H0B, &H0D, &H0F, &H11, &H13 })
などのように使うもの。この場合、recive.Count は 10 を返します。

(b) の場合は、複数のバイナリを蓄えるもので、たとえば
 recive.Add(New Byte() { &H01, &H03, &H05, &H07 })
 recive.Add(New Byte() { &H09, &H0B, &H0D, &H0F, &H11, &H13 })
などのように使うものですね。この場合、recive.Count は 2 を返し、
recive(0).Length は 4 を返し、recive(1).Length は 6 を返します。



> Brecive(Index)をある分だけ、string変換
> Cstrをテキスト保存
VB には「Str 関数」が存在するので、str という名の変数は避けた方が良いですよ。
とりあえず、ここでいう recive(Index) が、上記 (b) を表すのであれば、
 Dim str1 As String = BitConverter.ToString(recive(0)).Replace("-", "")
 Dim str2 As String = BitConverter.ToString(recive(1)).Replace("-", "")
とすることで、
 Dim str1 As String = "0103050709"
 Dim str2 As String = "0B0D0F1113"
という結果を得ることが出来ます。
(Replace しなかった場合には、2 文字ごとに "-" が入ります)


> Dファイルからstring配列(Load_str)に読み込み
Cの str との関係性が分かりませんが、これが
> Dim load As String() = File.ReadAllLines("C\テスト\test.csv", enco)
の部分ということでしょうか。

だとすると、C:\テストではなく C\テストになっていますが、間違いないでしょうか。
また、一括読み込みのための File.ReadAllText や ReadAllBytes を使わず、
行単位読み込みの File.ReadAllLines を使っているのは意図的なものでしょうか。


> Eload_strをまた新しいbyte配列へ変換
元はバイナリであるはずの csv ファイルを、テキストデータとして文字列にデコードし、
それを再度バイナリデータに、別の形式で再エンコードするという流れなのですか?
回りくどい作業が行われているように思うのですが、
本当にその手順は必要なものなのでしょうか。


> Frecive.Add(New Byte)
ここの説明が、先の説明と矛盾していますね。

recive.Add(New Byte() {}) なら、Private recive As New List(Of Byte()) ですし、
recive.Add(New Byte()) なら、Private recive As New List(Of Byte) のはず。


> Dim load As String() = File.ReadAllLines("C\テスト\test.csv", enco)
ちなみに File.ReadAllLines メソッドは、
「改行が、レコードとレコードの間に配置されるタイプの CSV テキスト」と
「改行が、各レコードの末尾に配置されるタイプの CSV テキスト」を
区別できませんのでご注意ください。

具体的には、CSV の中身が
「あい,うえ{改行}かき,くけ」
「あい,うえ{改行}かき,くけ{改行}」
のいずれのファイルを読み取った場合も、load.Length が 2 になってしまうということです。

そのため、この方法でファイルを読み取った場合は、元のファイルを
完全再現させることができませんのでご注意ください。


> For i As Integer = 0 To load.Length - 1
> bytedata(i) = CByte(Convert.ToInt32(load(i), 16))
> Next
上記で i = 0 のときに、load(i) に格納されている文字列は何でしょうか?

load(i) = "00" や load(i) = "FF" ならば、
CByte まで成功します。

load(i) = "0100" や load(i) = "0B0D0F11" ならば、
ToInt32 は成功しますが、CByte の部分で失敗します。

load(i) = "" や load(i) = "0B0D0F1113" だった場合、
CByte はおろか、ToInt32 さえ失敗するでしょう。


この部分だけを見れば、行単位で処理しようとするのではなく、
hexString を 2 文字ずつ変換してやれば復元はできるでしょうが、
bytedata() のインデックスは「バイト位置」で
load() のインデックスは「行番号」なのですから、どちらにしても
そもそもの変換ルールに問題があるように見えます。


> そもそも、やり方が間違ってるのかしらべたんですが
> わからずこちらで、ご質問させていただきました。

やりたいことを、もう一度整理してみてください。

数行の短い CSV ファイルを用意し、
それぞれの変数に、どのような値が入ることを期待しているのかを
再度考え直してみることをお奨めします。
編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←Byte配列→文字列→Byte配列の方法策 /io 返信無し
 
上記関連ツリー

Byte配列→文字列→Byte配列の方法策 / io (18/04/16(Mon) 13:54) #87146
Re[1]: Byte配列→文字列→Byte配列の方法策 / furu (18/04/16(Mon) 14:21) #87147
Byte配列→文字列→Byte配列の方法策 / 魔界の仮面弁士 (18/04/16(Mon) 15:18) #87148 ←Now
Re[1]: Byte配列→文字列→Byte配列の方法策 / 魔界の仮面弁士 (18/04/16(Mon) 16:50) #87149
  └ Re[2]: Byte配列→文字列→Byte配列の方法策 / io (18/04/16(Mon) 17:47) #87150
    └ Re[3]: Byte配列→文字列→Byte配列の方法策 / 魔界の仮面弁士 (18/04/16(Mon) 19:47) #87151
      └ Re[4]: Byte配列→文字列→Byte配列の方法策 / io (18/04/17(Tue) 09:03) #87155

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信