최근에 저는 드라이브의 원시 읽기 / 쓰기 부문이 필요한 프로젝트에 있습니다.

StackOverflow https://stackoverflow.com/questions/1648943

  •  22-07-2019
  •  | 
  •  

문제

전에, 나는 여기에 "aaa.txt"와 같은 파일 레이블을 통해 데이터를 읽고 쓰는 방법에 대한 조언을 구하는 질문을 여기에 게시합니다. 그러나 새로운 문제가 발생했습니다 ... 털이 많은 매개 변수

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

기능을 사용하고 드라이브에서 섹터를 읽을 때 ... 카운트를 x*512로 설정 해야하는 것 같습니다. 512 바이트의 여러 번이어야합니다 ...

왜??? 바이트로 바이트 바이트를 직접 사용할 수있는 원시 기능이 있습니까? 고맙습니다

도움이 되었습니까?

해결책

장치에 대한 읽기 및 쓰기는 두 섹터 모두 정렬되어야하며, 부문 크기의 정수 배수 인 바이트 카운트가 있어야합니다.

섹터 규모에 대해 가정하지 말고 모든 장치의 섹터 크기를 쿼리하고 동적으로 작업해야합니다. 일반적인 크기는 하드 드라이브의 경우 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는 정렬 할 것입니다 s 그리고 크기의 덩어리를 읽으십시오 s. 또한 자신의 사용 버퍼를 제공 할 수 있습니다. posix_memalign(), 또는 _aligned_malloc(), 귀하의 기본 STDIO 구현이이를 수행하지 않는 경우.

편집 : 의견에 약간의 혼란을 해결하려면

부문 크기 512가있는 장치로 작업하고 있습니다. FILE *f;. 너 fseek() 37을 상쇄합니다. f의 위치는 업데이트되었지만 장치에서는 찾지 않습니다. 너 fread() 500 바이트. lseek() 512 바이트를 읽습니다. f버퍼. 바이트 37 ~ 512가 제공 한 버퍼에 복사됩니다. lseek() 512 바이트를 읽고 512 바이트를 읽고, 예상되는 나머지 463 바이트는 전달한 버퍼에 복사됩니다. fread(). 당신이 지금이라면 fread() 단일 바이트는 기존 버퍼에서 간단히 복사됩니다. f, 장치를 치지 않고.

다른 팁

여기서는 Linux를 플랫폼으로 사용하고 있다고 가정합니다. Linux에서 각 장치는 파일입니다. /dev에서 장치 항목을 찾을 수 있습니다. 즉, 해당 드라이브에서 읽기/쓰기를 사용하여 I/O를 수행 할 수 있음을 의미합니다. 예를 들어/dev/sda1을 개방하고 N 수의 바이트를 읽어 하드 디스크 파티션을 직접 열 수 있습니다.

다음 코드를 사용하여 드라이브의 정확한 섹터 크기를 결정하십시오 (코드의 오류 처리 없음). Nth Sector를 읽고 싶다면 그냥 읽으십시오. 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;
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top