2009-10-30 3 views
1

나는 "aaa.txt"와 같은 파일 레이블을 통하지 않고 드라이브에서 데이터를 읽고 쓰는 방법에 대한 조언을 구하기 위해 여기에 질문을 게시한다. "하지만, 단지 분야는 .. 내가 조언했다 읽고 .... 쓰기하지만 새로운 problems'v 제기 ... 털이 매개 변수최근에 나는 드라이브의 원시 읽기/쓰기 섹터를 필요로하는 프로젝트에있다.

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

내가 기능을 사용하고 wanto 읽기 시도 섹터 드라이브에서 ... 나는 x * 512로 계산을 설정해야 할 것 같습니다. 그것은 512 바이트의 몇 배가되어야합니다 ...

왜 ??? 바이트 단위로 직접 사용할 수있는 원시 기능이 있습니까? Thanx ... btb, 내가 원한다면 직접 I/O 드라이버 프로그램을 개발해야합니까? thanx

+4

이전 질문에 대한 답을 수락하면 시간을 보낸 사람이 보상을받을 수 있습니다. –

답변

4

장치에 대한 읽기 및 쓰기는 섹터 정렬과 섹터 크기의 정수배 인 바이트 수로 이루어져야합니다.

섹터 크기에 대한 가정을하지 마십시오. 모든 장치의 섹터 크기를 쿼리하고 동적으로 작업해야합니다. 일반적인 크기는 하드 드라이브의 경우 512 개이고 광학 드라이브의 경우 2048 개입니다. 당신은 당신이 DeviceIoControl()를 호출 할 수 있습니다 Windows에서 섹터 크기를 얻을 필요가있는 경우

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

:

당신이 낭비 오버 헤드를 침해하지 않는 범위 내에서이 장치에 대한 바이트로 바이트를 읽을 수 있도록 기능을 원하는 경우

이 트릭을 시도 IOCTL_DISK_GET_DRIVE_GEOMETRY.

Stdio는 검색을 s으로 정렬하고 크기는 s입니다. 또한 기본 stdio 구현이이 작업을 수행하지 않으면 posix_memalign() 또는 _aligned_malloc()을 사용하여 자체 버퍼를 제공 할 수 있습니다.

편집 : 당신은 FILE *f;으로, 섹터 크기 512 장치로 작업

코멘트에 혼란을 취소합니다. fseek()은 오프셋 37입니다. f의 위치는 업데이트되지만 장치는 검색되지 않습니다. 너 fread() 500 바이트. lseek()은 오프셋 0으로 호출됩니다. 512 바이트는 f의 버퍼로 읽혀집니다. 바이트 37 ~ 512는 사용자가 제공 한 버퍼에 복사됩니다. lseek()이 512의 오프셋으로 호출됩니다. 512 바이트가 읽히고 나머지 463 바이트가 fread()으로 전달 된 버퍼로 복사됩니다. 현재 fread()의 단일 바이트 인 경우 기기를 두드리지 않고 기존 버퍼에서 f으로 간단히 복사합니다.

+1

하지만 여전히 매개 변수로 number-of-bytes를 사용하여 fread/fwrite를 실행해야합니다. 그것은이 문제를 해결하지 못합니다. 당신이 말했듯이, 그는 먼저 드라이브의 섹터 크기를 결정한 다음 n 번째 섹터를 읽기 위해 n * sector_size 데이터를 읽어야합니다. 내가 틀렸다면 나를 바로 잡아라. –

+1

틀렸어. : 포인트가 장면 뒤에 있습니다. stdio는 크기 s의 전체 덩어리를 읽은 다음, 요청한 부분만을 제공하는 버퍼링을 수행합니다. –

+2

과 정확하게 일치해야합니다. 첫 번째 1 바이트 fread는 실제로 setvbuf (코드에서 섹터 크기)에 의해 설정된 바이트 수를 읽지 않지만 응용 프로그램에 단 하나의 바이트 만 제공합니다. 따라서 완전한 섹터를 읽으려면 애플리케이션이 섹터 크기의 자유를 수행해야합니다. 정확한 섹터 크기를 결정하기 위해 응용 프로그램은 먼저 ioctl (BLKSSZGET)을 발행해야합니다. Macroideal이 그가 분야별로 I/O를 할 수 있기를 원하는 것 같습니다. –

2

여기서는 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; 
    } 
관련 문제