下記のような、データ加工プログラムをJavaで書こうと思っているのですが
暗礁に乗り上げています。
どなたか、良い知恵(どのようなアルゴリズムが考えられるか、等)を
お貸しいただけないでしょうか?
よろしくお願いいたします。
【元ファイルのビット列】
・・・・00000001 00011100 00000000 10000100 01001100・・・・・
↓「00000001 00011100」の先頭6ビットを削除
【新規ファイルに書きこみ】
01000111 00
↓以降のビット列をそのまま新規ファイルに追加書きこみ
【書きこみ結果】
01000111 00000000 00100001 00010011 00・・・・・
【処理概要】
1.バイナリファイル(サイズは不特定)を先頭から読みこむ。
2.00000001 00011100というビット列が現れるまで、読み捨てていく。
3.上記のビット列が現れたら、00000001の先頭6ビットを削除し、
その結果を新規ファイルに書きこむ。
このビット列が元ファイルの何バイト目に現れるかは、その都度違う。
4.それ以降のビット列(ファイルの終端まで)をすべて新規ファイルに追加書きこみしていく。
No.1ベストアンサー
- 回答日時:
I/Oはバイト単位が最小ですから、ビット単位のI/Oを行おうとすると面倒ですね。
次のような処理手順で出来ないでしょうか。
基本方針:処理途中のデータはboolean配列として格納する。ファイルが小さいことがわかっているならファイル全体をその配列に格納するが、ある程度の大きさがある、またはその可能性があるなら「ある程度を読む、処理する、ある程度を書く」の繰り返しにする。
// 初期化
(1)最初はboolean配列は長さゼロ。
// ここからループ
// 読み出し
(2)ファイルの終端に達したら(8)へ。
(3)ファイルから1バイト読んで、8個のbooleanを追加する。
(4)boolean配列が長さ16未満なら(2)へ。
// 主たる処理
(5)boolean配列の先頭から16個の要素が、【処理概要】2のパターンなら
(5-1)先頭6要素を削除する。
// 書き出し
(6)boolean配列が長さが8以上なら、
(6-1)先頭から8要素を1バイトに変換して、ファイルに書き出す。
(6-2)その後boolean配列の先頭から8要素を削除する。
(7)(2)へ。
// ここまでループ
// 後始末
(8)boolean配列が長さが1~7なら、
(8-1) 8-(長さ)分の詰め物をして、1バイトに変換する。
(8-2) そのバイトをファイルに書き出す。
上記を元に、高速化のために「boolean配列は仮想的なものとして、実際のデータはbyte配列とする」などの改良を加えていくと良いでしょう。
この回答への補足
丁寧なご回答、ありがとうございました。
たいへん参考になりました。なんとかできそうな気がします。
ただ1点、わからないことがあります。
>(6-1)先頭から8要素を1バイトに変換して、ファイルに書き出す。
これがよくわかりません。
8要素(True or False)をひとつひとつ取り出しつつ
10進数に変換して、それをwriteするという意味なのでしょうか?
それとも、そのための有用なメソッドがクラスライブラリに定義されているのでしょうか?
No.3
- 回答日時:
おおよそhappy_peopleさんの書かれた方法でいいと思うんですが,boolean配列を使わずbyteにシフト演算を行ったほうが楽なのではないかと思います。
処理の流れはだいたい以下のような感じです。
1) ファイルからバイト列を読み込む
'00000001 00011100'が見つかるまでそのバイト列を別ファイルに出力
(該ビット列の出現判定は,例えば「連続する2バイトに対し,それぞれ 0x1, 0x1C とのXORを取って結果がゼロになるかどうか」などとすればよいでしょう)
2) 見つかったら,
2-1) まず1バイト目(b1)を6ビット左にシフト: bf = b1 << 6;
2-2) 次に2バイト目(b2)を2ビット右にシフト: bt = b2 >>> 2;
2-3) bfとbtのORを取って出力するバイト値(b)を生成: b = bf | bt
2-4) bを出力ファイルに書き込む
2-5) b2をb1に代入し,次の処理に備える
3) 以後,次の1バイトをb2に読み込み,
2-1~2-6の処理を行う
これをb2に読み込むべきバイトが無くなるまで繰り返す
4) b2の読み込みでEOFが返ってきたら,
2-1の処理を行ったのち,そのバイト(bf)を出力ファイルに書き込んで終了
…と,こんな感じでしょうか。
#適当に書いたのでもしかしたら破綻してるかもしれませんが,大筋はこんな感じでいいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- その他(OS) windows11非対応のインストール 3 2022/10/26 07:12
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- Visual Basic(VBA) tatsumaru77様 昨日回答して頂いたものです。 すみませんが、昨日の質問で1つ補足があります 1 2022/05/15 15:06
- Excel(エクセル) マクロの付いたExcelが開けません 3 2023/02/01 10:54
- その他(データベース) Excel VBA 転記について 1 2022/04/20 16:55
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでテキストファイルの改行を...
-
Cで2次元配列にCSVファイルを...
-
Unicodeのファイル読み込みがう...
-
テキストファイルを後ろから読...
-
[VBS] 16進数でバイナリファイ...
-
awk getlineをもう一度ファイル...
-
C言語でのファイル読み込み
-
C言語初心者です。 C言語のファ...
-
DXFファイルをVBで取り込み、図...
-
数値から画像を作りたい
-
fread関数の使い方がわかりませ...
-
バイナリデータの書き換え
-
ファイルのアクセス回数について
-
エクセルのプロパティーでセキ...
-
バッチファイル 二つ上のディ...
-
エクセルvbaでdocuworksprinter...
-
Wordで差込印刷した後に別々の...
-
カンマ区切りのCSVファイルから...
-
エクセルで複数のコメントのサ...
-
Excel 相対パス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バイト型のデータを16進表記で...
-
VBAでテキストファイルの改行を...
-
テキストファイルを後ろから読...
-
VBAでテキストファイルを複数開...
-
バイナリファイルでOutOfMemory...
-
DXFファイルをVBで取り込み、図...
-
RGBのバイナリデータをCImageに...
-
CFileの使い方を教えてください
-
datagridviewでドラッグ操作が...
-
Excel VBAで画像解析
-
バイナリの読み込みから出力まで
-
bmpファイルの明暗の数値化の方法
-
fread関数の使い方がわかりませ...
-
SDKにて。
-
日本語を配列に収め、そして表...
-
バイナリ出力
-
VBSにてCSV読み込みし比較
-
ファイル内の(&H0A)を(&H0D0A)...
-
Cで2次元配列にCSVファイルを...
-
日本語混じりのファイルをラン...
おすすめ情報