デバイスへの読み取りと書き込みは、両方ともセクターにアラインされている必要があり、バイト カウントはセクター サイズの整数倍である必要があります。
セクター サイズについて推測しないでください。任意のデバイスのセクター サイズを照会し、それを動的に処理する必要があります。一般的なサイズは、ハード ドライブの場合は 512、光学ドライブの場合は 2048 です。
無駄なオーバーヘッドを発生させることなく、デバイス上でバイトごとに読み取ることができる関数が必要な場合は、次のトリックを試してください。
FILE *file_pointer = fopen("/path/to/device", "rb");
size_t sector_size;
ioctl(fd, BLKSSZGET, §or_size);
setvbuf(file_pointer, NULL, _IOFBF, sector_size);
Windows でセクター サイズを取得する必要がある場合は、 で呼び出すことができDeviceIoControl()
ますIOCTL_DISK_GET_DRIVE_GEOMETRY
。
Stdio はs
size のチャンクにシークを合わせて読み取りますs
。さらに、基になる stdio 実装がこれを行わない場合はposix_memalign()
、 またはを使用して独自のバッファを提供できます。_aligned_malloc()
編集:コメントの混乱を解消するには
セクター サイズが 512 のデバイスを使用していますFILE *f;
。You fseek()
to offset 37.f
の位置は更新されますが、デバイスでシークは行われません。あなたはfread()
500バイトです。はオフセット 0 で呼び出されます。512 バイトがのバッファlseek()
に読み込まれます。f
バイト 37 から 512 は、指定したバッファーにコピーされます。lseek()
512 のオフセットで呼び出されます。512 バイトが読み取られ、予想される残りの 463 バイトが、渡したバッファーにコピーされますfread()
。1 バイトの場合、デバイスにヒットすることなくfread()
、既存のバッファから単純にコピーされます。f