1

以前、「aaa.txt」のようなファイルラベルではなく、セクターだけでなく、ドライブとの間でデータを読み書きする方法についてアドバイスを求める質問をここに投稿しました..読み書きを試すように勧められました....しかし、新たな問題が発生しました...毛むくじゃらのパラメーター

int _read( int handle, void *buffer, unsigned int count );

関数を使用してドライブからセクターを読み取りたい場合...カウントを x*512 に設定する必要があるようです。512バイトの数倍でなければなりません...

どうして???バイトごとに直接使用できる生の関数はありますか... ありがとうございます... ところで、それをしたい場合は、独自の I/O ドライバー プログラムを開発する必要がありますか? ありがとう

4

2 に答える 2

4

デバイスへの読み取りと書き込みは、両方ともセクターにアラインされている必要があり、バイト カウントはセクター サイズの整数倍である必要があります。

セクター サイズについて推測しないでください。任意のデバイスのセクター サイズを照会し、それを動的に処理する必要があります。一般的なサイズは、ハード ドライブの場合は 512、光学ドライブの場合は 2048 です。

無駄なオーバーヘッドを発生させることなく、デバイス上でバイトごとに読み取ることができる関数が必要な場合は、次のトリックを試してください。

FILE *file_pointer = fopen("/path/to/device", "rb");
size_t sector_size;
ioctl(fd, BLKSSZGET, &sector_size);
setvbuf(file_pointer, NULL, _IOFBF, sector_size);

Windows でセクター サイズを取得する必要がある場合は、 で呼び出すことができDeviceIoControl()ますIOCTL_DISK_GET_DRIVE_GEOMETRY

Stdio はssize のチャンクにシークを合わせて読み取ります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

于 2009-10-30T10:47:36.187 に答える
2

ここでは、プラットフォームとしてLinuxを使用していると想定しています。Linuxでは、各デバイスはファイルです。/devにデバイスエントリがあります。これは、そのドライブで読み取り/書き込みを使用してI / Oを実行できることを意味します。たとえば、/ dev / sda1を開いて、nバイト数を読み取ることにより、ハードディスクパーティションを直接開くことができます。

次のコードを使用して、ドライブの正確なセクターサイズを決定します(コードでのエラー処理はありません)。n番目のセクターを読み取りたい場合はn*sector_size、開いているデバイスからバイトを読み取ります。これがあなたの問題の解決に役立つことを願っています。

    #include <stdio.h>
    #include <linux/fs.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #define SECTOR_NO 10 /*read 10th sector*/

    int main()
    {
            int sector_size;
            char *buf;
            int n = SECTOR_NO;

            int fd = open("/dev/sda1", O_RDONLY|O_NONBLOCK);
            ioctl(fd, BLKSSZGET, &sector_size);
            printf("%d\n", sector_size);
            lseek(fd, n*sector_size, SEEK_SET);

            buf = malloc(sector_size);
            read(fd, buf, sector_size);

            return 0;
    }
于 2009-10-30T12:41:45.737 に答える