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

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

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

Re[2]: C#でバイナリファイルの一部置換


(過去ログ 127 を表示中)

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

■75364 / inTopicNo.1)  C#でバイナリファイルの一部置換
  
□投稿者/ B.B (1回)-(2015/03/19(Thu) 02:53:13)

分類:[C#] 

Windows7 64Bit
Visual Studio Express 2012 for Windows Desktop

C#でバイナリファイルを読み込んで一部を別の数値に置換して保存するという処理がしたいのです。
66-00-50-65の50を70に置換する場合どのようにしたらいいでしょうか。
byte[] data = File.ReadAllBytes(binaryFile);
などとバイト配列に入れた後に表示したりの解説は見つけられるのですが置換の仕方が分かりません。
よろしくお願いいたします。

引用返信 編集キー/
■75365 / inTopicNo.2)  Re[1]: C#でバイナリファイルの一部置換
□投稿者/ Azulean (454回)-(2015/03/19(Thu) 07:23:02)
No75364 (B.B さん) に返信
> などとバイト配列に入れた後に表示したりの解説は見つけられるのですが置換の仕方が分かりません。

1.byte[] となっている data から 66-00-50-65 と並んでいる部分をループで探す。
2.見つけたら、50 の部分を data[n] = 0x70; /* 16進数の場合 */ として置き換える。
3.最後まで到達したら File.WriteAllBytes で書き込む。


ただ、この方法、対象のファイルサイズ次第ではメモリを大きく消費しますし、数百メガバイトといった状況になってくる場合は処理が失敗します。
本当にそのアプローチで良いのかは考えた方が良いかも。
引用返信 編集キー/
■75366 / inTopicNo.3)  Re[2]: C#でバイナリファイルの一部置換
□投稿者/ B.B (2回)-(2015/03/19(Thu) 08:07:31)
>2.見つけたら、50 の部分を data[n] = 0x70; /* 16進数の場合 */ として置き換える。
> 本当にそのアプローチで良いのかは考えた方が良いかも。
アドバイスありがとうございます。これとは違うアプローチが知りたいです。
置換という考え方がそもそも違っているのかもしれませんが、どういう方法があるのかが見当つかないのです。
バイナリデータをバイト配列以外に読み込んで処理する方法というのがあるのでしょうか。
16進文字列での表記とかにはこだわっていません。

引用返信 編集キー/
■75367 / inTopicNo.4)  Re[3]: C#でバイナリファイルの一部置換
□投稿者/ 魔界の仮面弁士 (246回)-(2015/03/19(Thu) 09:38:12)
No75366 (B.B さん) に返信
> アドバイスありがとうございます。これとは違うアプローチが知りたいです。
検索アプローチと言うことなら、KMP法とか。
http://ja.wikipedia.org/wiki/KMP%E6%B3%95


>> byte[] data = File.ReadAllBytes(binaryFile);
そもそも File.ReadAllBytes だと、最初に全データをメモリ上に読み込んでしまうため、
ギガバイト級のファイルの置換などには向きません。

入力ファイルと出力ファイルをそれぞれ FileStream で用意し、
適当なサイズに切り出しながら走査・置換していった方が良いかも。
引用返信 編集キー/
■75368 / inTopicNo.5)  Re[4]: C#でバイナリファイルの一部置換
□投稿者/ daive (46回)-(2015/03/19(Thu) 10:31:06)
大きいファイルサイズの物の処理について
参考にならないかも、しれませんが、
面白いアプローチです。
テストとしては、500Mbytes 位まで行った様子

テキストファイルの処理時間短縮
http://www.moug.net/faq/viewtopic.php?t=71045&highlight=%C3%F3%BC%D6%BE%EC
引用返信 編集キー/
■75383 / inTopicNo.6)  Re[4]: C#でバイナリファイルの一部置換
□投稿者/ B.B (3回)-(2015/03/19(Thu) 13:58:33)
No75367 (魔界の仮面弁士 さん) に返信
> 検索アプローチと言うことなら、KMP法とか。
これは知りませんでした。教えていただきありがとうございます

> そもそも File.ReadAllBytes だと、最初に全データをメモリ上に読み込んでしまうため、
> ギガバイト級のファイルの置換などには向きません。
こういう情報が知りたかったのです。最初から間違っていました、おはずかしい

> 入力ファイルと出力ファイルをそれぞれ FileStream で用意し、
> 適当なサイズに切り出しながら走査・置換していった方が良いかも。
FileStreamを使用する方向で行こうと思います。
引用返信 編集キー/
■75384 / inTopicNo.7)  Re[5]: C#でバイナリファイルの一部置換
□投稿者/ B.B (4回)-(2015/03/19(Thu) 14:02:08)
No75368 (daive さん) に返信
アドバイスありがとうございます。
自分の無知ゆえに大きいファイルサイズを読み込むことの問題がわかっておりませんでした。
どうしても一括で読み込みたいわけではなく切り出して処理する方向でいきます。
引用返信 編集キー/
■75385 / inTopicNo.8)  Re[5]: C#でバイナリファイルの一部置換
□投稿者/ B.B (5回)-(2015/03/19(Thu) 14:29:36)
FileStream fs = new FileStream(binaryFile, FileMode.Open);
BinaryReader br = new BinaryReader(fs);

BinaryReaderクラスのメソッドを利用すれば実装できるでしょうか。
https://msdn.microsoft.com/ja-jp/library/system.io.binaryreader(v=vs.110).aspx
他に必要な知識があればヒントになる用語を教えていただきたいです。




引用返信 編集キー/
■75386 / inTopicNo.9)  Re[6]: C#でバイナリファイルの一部置換
□投稿者/ Hongliang (295回)-(2015/03/19(Thu) 14:45:16)
> BinaryReaderクラスのメソッドを利用すれば実装できるでしょうか。

不要です。
FileStream::Readでbyte[]に読み込んで、それを検索する、を繰り返すだけです。
// 分けて調べる場合、検索すべき対象がちょうど分けられてしまっていた場合のケースの対応が少し面倒です。
引用返信 編集キー/
■75387 / inTopicNo.10)  Re[7]: C#でバイナリファイルの一部置換
□投稿者/ B.B (6回)-(2015/03/19(Thu) 15:15:43)
No75386 (Hongliang さん) に返信
> 不要です。
> FileStream::Readでbyte[]に読み込んで、それを検索する、を繰り返すだけです。
ありがとうございます。わざわざ難しく考えててはずかしいです

> 分けて調べる場合、検索すべき対象がちょうど分けられてしまっていた場合のケースの対応が少し面倒です。
これは質問しようかと思っていました。
検索値が8バイトなら切り出して検索した後に次の切り出し位置を8バイト戻して読み込みでいいでしょうか。

引用返信 編集キー/
■75396 / inTopicNo.11)  Re[1]: C#でバイナリファイルの一部置換
□投稿者/ yoh2 (6回)-(2015/03/19(Thu) 22:34:14)
何だか、バイナリファイルから特定のパターン (今回の例では66-00-50-65) を
検索して置換する、という流れになっていますが、その検索は今回必要なことですか?
質問者さんは話の勢いに押されて、本当にやりたいことを説明できないまま
流されているように見えたもので。

置換を行いたいパターンのある位置が決まっている (固定位置だったり、
別の固定位置にパターンの位置が記録されていたり) ので、そこを
一部だけ変更したい、という話だったりはしませんか?

検索 & 置換が本来行いたいことだったのなら今の流れでよいのですが。
引用返信 編集キー/
■75397 / inTopicNo.12)  Re[2]: C#でバイナリファイルの一部置換
□投稿者/ B.B (7回)-(2015/03/20(Fri) 01:22:04)
No75396 (yoh2 さん) に返信
> 質問者さんは話の勢いに押されて、本当にやりたいことを説明できないまま
> 流されているように見えたもので。
おっしゃるとおりです。途中で知りたいことが変わったような感じになりました
本来知りたいことは例えば”Ver.1”が複数個所にあり”1”を”2”に変えたいということです。

> 置換を行いたいパターンのある位置が決まっている (固定位置だったり、
> 別の固定位置にパターンの位置が記録されていたり) ので、そこを
> 一部だけ変更したい、という話だったりはしませんか?
これも知りたいことでもありグダグダになったようで申し訳ありません
置換というより読み込んだデータに他のデータを上書きするのでしょうか。

事前に調べたのが以下のサイトになります。
http://www.atmarkit.co.jp/fdotnet/dotnettips/669bincopy/bincopy.html
他のサイトも似たような内容でここから置換につながるイメージがわきませんでした。
私の頭にあるイメージはテキストファイルでのReplaceのようなものでしたが違うかどうかもわかりません。
どのようなアプローチで行けばよいかアドバイスお願いいたします。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -