バイナリーデータを区切って読込む – プログラミング – Home

バイナリーデータを区切って読込む
 
通知
すべてクリア

[解決済] バイナリーデータを区切って読込む


ピースケ
 ピースケ
(@ピースケ)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

256バイトの固定でバイナリーファイルを読む事ができたので
可変で出来るようにします。

読込むファイルのデータのバイト数 528

HANDLE hF; // ファイルのハンドル
DWORD dwResult; // 読み取ったバイト数
char chBuf[1024]; // バイナリーデータ格納領域
int value;         // バイト数格納

hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

ReadFile(hF, chBuf, value = GetFileSize(hF , NULL), &dwResult, NULL);

結果
  value は528と期待値が入っているのでOK

これを 0~256, 257~512, 513~528 と256づつ読み込みたい場合の方法が分りません。
ReadFileは先頭からしか取れないのでしょうか?(例えば 257バイト目から256バイト読
込む事が出来ないのか)
どなたか教えて下さい。よろしくお願い致します。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>0~256, 257~512, 513~528 と256づつ読み込みたい場合の方法が分りません。
ReadFileのヘルプに
>読み取りが完了すると、ファイルポインタの位置は、実際に読み取ったバイト数だけ
>進みます。
とありますけど、確認してみましたか?

質問する前に、まずはヘルプをみて、簡単なコードを試してみてください。


返信引用
ピースケ
 ピースケ
(@ピースケ)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

Blueさんありがとうございます。

ファイルを2回開くしかやり方が無いでしょうか?
最初の256バイトは読込む必要が無いので、257バイトから256づつデータを
読込む処理をしたいです。

私自身のやり方だと無駄が多くなってしまいます。
効率のいいやり方などご教授お願いします。

<サンプル>
memset(chBuf,'\0',sizeof(chBuf)); // 初期化
// ファイルを開く(全体のファイルサイズを取得する為)
hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

if (hF == INVALID_HANDLE_VALUE)
{
return 1;
}

// データを読み込む(全体のファイルサイズを取得)
ReadFile(hF, chBuf, nNumOfByte = GetFileSize(hF , NULL), &dwResult, NULL);
// ファイルを閉じる
CloseHandle(hF);

//ファイルを開く(257バイト目から256バイト取得する為)
hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

if (hF == INVALID_HANDLE_VALUE)
{
return 1;
}
for(count = 0; count< 4; count++)
{
memset(chBuf,'\0',sizeof(chBuf)); // 初期化

//この場合は頭からとっていくので本来は257バイトから256づつとりたい
ReadFile(hF, chBuf, 256, &dwResult, NULL);
}
// ファイルを閉じる
CloseHandle(hF);


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

> ファイルを2回開くしかやり方が無いでしょうか?
そうではなくて一回開いてReadを二回するのです。
ファイルのOpenは処理としては重い処理なので開きっぱなしで
支障が無い場合は開きっぱなしにするのが普通です。
あと、閉じてしまうとファイルポインタはファイルの先頭に戻るので
読み込み開始位置に設定しないと駄目になります。
通常は、

1.ファイルをOpen

2.ファイルからRead

3.読んだデータで処理。

4.ファイルエンドで無いなら2に戻る。

5.ファイルをClose

とすると思いますよ。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

がーっ、誤字。

誤)
> 読み込み開始位置に設定しないと駄目になります。

正)
読み込み開始位置をきちんと設定しないと駄目になります。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 最初の256バイトは読込む必要が無いので、257バイトから256づつデータを
> 読込む処理をしたいです。
普通に読み捨てればいいだけなのでは?

// ファイルを開く
hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if (hF == INVALID_HANDLE_VALUE)
{
return 1;
}

// 全体のファイルサイズを取得
nNumOfByte = GetFileSize(hF , NULL);
// ファイルサイズのチェック
if ( nNumOfByte != 528 )
{
return 1;
}

// 先頭256バイト読み捨て
ReadFile( hF, chBuf, 256, &dwResult, NULL );

// 257バイトから256取得
memset( chBuf, '\0', sizeof( chBuf ) );
ReadFile( hF, chBuf, 256, &dwResult, NULL );

また、SetFilePointerという関数があります。この関数はファイルの位置移動してくれ
ます。(詳しくはヘルプで)

ちなみに、MFCを使うのであれば、CFileクラスを使ったほうが見やすくなると思いま
す。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

CloseHandleが抜けている箇所がありました。

// ファイルサイズのチェック
if ( nNumOfByte != 528 )
{
CloseHAndle(hF);
return 1;
}


返信引用
ピースケ
 ピースケ
(@ピースケ)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

2回読込んだのは1回目の
ReadFile(hF, chBuf, nNumOfByte = GetFileSize(hF , NULL), &dwResult, NULL);
でファイルの最後まで読込んでいるので
2回目の
ReadFile(hF, chBuf, 256, &dwResult, NULL);
ではファイルポインターが最後の場所をさしているのでデータを読んでくれませんでし
た。

SetFilePointer(hF , 256 , NULL , FILE_CURRENT);
ファイルポインターを256番目を指すようにしてるつもりですが

ReadFile(hF, chBuf, 256, &dwResult, NULL);
データが何もはいってこないのはなぜでしょうか?

<参考HP>
http://72.14.235.104/search?
q=cache:M5tNjtXANtoJ:wisdom.sakura.ne.jp/system/winapi/win32/win113.html+SetFil
ePointer&hl=ja&gl=jp&ct=clnk&cd=4&lr=lang_ja


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> SetFilePointer(hF , 256 , NULL , FILE_CURRENT);
> ファイルポインターを256番目を指すようにしてるつもりですが

どこがでしょうか。
FILE_CURRENTの意味はちゃんとわかっていますか?
see) http://msdn.microsoft.com/en-us/fileio/fs/setfilepointer.asp

そもそも,全体を読み込む行為に意味はあるのですか?

> <参考HP>

何のためにわざわざGoogleキャッシュのURIを書いているんだか……。


返信引用
yoh2
 yoh2
(@yoh2)
ゲスト
結合: 18年前
投稿: 70
 

全ファイルを一度に読み込めるほどバッファサイズを大きくとれるorファイル
サイズが小さいなら、発想を変えて、全て読み込んだバッファを256バイトずつ
読むようにするという手も。
その際はくれぐれもバッファオーバーランにご注意を。

# それでも、今後のためにファイルの読み書き位置設定方法はしっかり
# 覚えておくべきでしょうけど。


返信引用
ピースケ
 ピースケ
(@ピースケ)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

返事遅れて済みません

みなさんありがとうございます。
このような形でやりました。

READ_DATA_SIZE 256

char chBuf[READ_DATA_SIZE];
//ファイルを開く
hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,NULL);

 if (hF == INVALID_HANDLE_VALUE)
 {
  return 1;
 }

 SetFilePointer(hF , 256 , NULL , FILE_CURRENT); // 最初の256バイトは進める

 // 256バイト読込む
 ReadFile(hF, chBuf, sizeof(chBuf), &dwResult, NULL);


返信引用
三草
 三草
(@三草)
ゲスト
結合: 19年前
投稿: 56
 

ごめんなさい、ご回答ではなく単なる赤ペン先生になってしまいますが、
補足とご参考までに。。。

// マジックナンバーや即値はなるべく避けましょう
#define READ_DATA_SIZE 256
#define READ_START_POINT 256
#define FILE_OPEN_ERROR 1
・・・

// # NULL分入れておくとよろしいかと
char chBuf[READ_DATA_SIZE + 1];

//ファイルを開く
hF = CreateFile(FilePath,GENERIC_READ,0,NULL,OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,NULL);

if (hF == INVALID_HANDLE_VALUE){
return FILE_OPEN_ERROR;
}

// 最初の256バイトは進める
// # 256バイト目から読み込ませるため、ポインタ移動する
SetFilePointer( hF, READ_START_POINT, NULL, FILE_BEGIN);
// ##「最初」から256バイト進める。ならこれ↑^^^^^^^^^^
// ## FILE_CURRENT だと、ファイルを開いた直後は「たまたま」最初を指しているで
// ## ピースケさんのイメージどおりに動いています。
// ## 仮に、ファイル開いた直後に、nバイト読み込む処理が入ってしまったら、
// ## FILE_CURRENT だと、n+256バイト目を指すことになります。(それで良いなら良い
のですが)

// 256バイト読込む
ReadFile(hF, chBuf, sizeof(chBuf), &dwResult, NULL);
// # ReadFileを「安全」に行うのであれば、第3引数はsizeof(chBuf)で良いと思います
// # ですが、そうするとコメントとコードが合わないので、コメントにあわせるなら、
// # ReadFile(hF, chBuf, READ_DATA_SIZE, &dwResult, NULL);
// ## でも組む人の思想によって、READ_DATA_SIZEとするか、sizeof(chBuf)とするか
// ## 分かれるかもしれません。


返信引用
ピースケ
 ピースケ
(@ピースケ)
ゲスト
結合: 18年前
投稿: 25
Topic starter  

三草さんありがとうございます。
赤ペン先生大変為になります。

またよろしくお願い致します。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました