2014-11-17 2 views
0

나는 내가 datas 바이너리 파일의 청크에 저장하고, 내가 발견 실험을 통해 내 지식을 알고, 바이너리 파일에 조금 혼란 스러워요 그 우리는이 같은 멤버 변수와 구조체가 있다면 :바이너리 파일의 청크 (알 수없는 크기)를 읽는 방법은 무엇입니까?

struct student{ 
int Roll_No; 
char Name[10]; 
} 

을 그런 다음 내용으로 변수를 업데이트하고 바이너리 파일에 저장하면 바이너리 파일은 14 바이트, char는 10 바이트, int는 4 바이트가됩니다. 따라서 파일을 분석하면 hex_itor에서 파일의 Roll_no가 4 바이트로 예약되고 10 바이트는 채워진 내용이 채워지는 이름이고 다른 것은 파일에서 점으로 보일 수 있습니다. 위와 같이 struct/class로 프로그램을 만들고 내용을 파일에 저장하면 파일의 크기는 우리가 만든 구조체와 같아서 int의 4 개와 char의 10 개를 의미합니다. 예를 들어 새로운 이미지 형식을 만든 경우 내 지식에서. (도트) .MyIMG는 stucture의 내 프로그램에서/클래스처럼이

struct MyIMG{ 
char Header[5]; 
int width, height; 
int Pixels[124000]; 
} 

그런 크기의 새 파일을 만듭니다 내 프로그램 49,613 바이트 또는 49 Kigabytes (헤더의 5, + (플러스) 8하는 int 픽셀의 + (+) 4 × 124000), 픽셀이 4, 8, 100 또는 무엇이든 상관없이 픽셀 배열이 비어있는 모든 픽셀을 작성하므로이 효과가 큰 MSpaint, Adobe Photoshop과 같은 소프트웨어, 빈 배열이 아닌 여관에 저장된 파일에 따라 파일을 쓰도록 프로그램을 만드는 것 ...

편집 : 이제 내 질문을 편집하고 명확하게 정의했습니다. 내 질문, pls 도와주세요, 사전에 감사합니다 !!

+1

도트는 "무효"를 의미하지 않으며 "인쇄 할 수없는 문자"를 의미합니다. –

+5

그것은 ... 모두 한 문장입니까? – etheranger

+0

16 진수 편집기는 파일의 16 진수 값의 한면과 ascii로 다른 한면을 보여 주므로 아무 것도 인쇄 할 수없는 ASCII 문자이기 때문에 C++의보기로 메모리에 읽은 후 (예 : 변수 .Char) 문자열은 자동으로 종료됩니다. 문자열은 끝났지 만, 청크 크기의 파일을 어떻게 처리합니까? – Rishabh

답변

1

파일을 쓰는 코드는 자신의 형식을 선택해야합니다. 파일에 student 구조를 작성할 때 예를 들어, 당신은 말할 수 같은 것을 : 이것은 다음 바이너리 파일에 대한 첫 번째 0/NUL 문자를 포함에 이름을 쓸 것이다

size_t name_len = strlen(my_student.Name); 
my_ofstream.write((const char*)&my_student, sizeof my_student - sizeof my_student.Name + name_len + 1); 

. 파일을 다시 읽을 때 프로그램은 ifstream에서 한 블록의 데이터를 읽을 수 있습니다. student이 오프셋으로 저장되어 있음을 알기 위해 들어오는 데이터의 .Name 부분에 strlen()을 사용하여 길이를 복구하고 부분적으로 만 복사 할 수 있습니다 - 그것은 유지하면서 하나의 NUL를 검색하기 위해 약간의 고통의

char buffer[32768]; 
student my_student; 
if (my_ifstream.read(buffer, sizeof buffer) && my_ifstream.gcount() > 5) 
{ 
    // check for NUL without risking reading buffer[.gcount()] 
    size_t pre_name_len = std::offsetof(student, name); 
    const char* p_name = buffer + pre_name_len; 
    const char* p_nul = strnchr(p_name, 
           std::min(10, my_ifstream.gcount() - pre_name_len), 
           '\0'); 
    if (p_nul == nullptr || *p_nul != '\0') 
     throw std::runtime_error("file didn't contain complete student record"); 
    memcpy(my_student, buffer, p_nul - buffer + 1); 

    // keep parsing input from p_nul + 1, not going past .gcount() 
} 

당신이 볼 수 있듯이 : 또한 필요한 student 객체에 대한 데이터 및 입력 스트림에서 다음 데이터 항목을 구문 분석을 시작할 위치를 알 파일에서 읽은 데이터 양을 추적하여 손상된 입력 파일을 가져올 경우 충돌이 발생하지 않도록하십시오.

초보자라면, 낮은 레벨의 많은 부분을 추상화하는 boost serialisation library에 대해 배우는 것이 가장 쉽고 강력 할 것입니다. 일부는 C 스타일의 I/O, 캐스팅 및 오프셋 계산을 사용하여 더 깨끗한 논리적 인터페이스를 제공합니다.

2

.png 및 .bmp와 같은 파일 형식은 특정 형식을 갖습니다. 파일 형식은 바이트 레이아웃 (예 : 너비 4 바이트, 높이 4 바이트, RGBA 픽셀 데이터 2MB 등)을 지정하거나 다양한 개체의 크기에 대한 정보를 제공 할 수 있습니다.

예를 들어, TIFF 파일은 파일 내의 특정 바이트 오프셋에 숫자 태그가 있음을 나타냅니다. 이러한 태그에는 이미지 데이터의 크기, 위치 및 형식에 대한 정보가 들어 있습니다. 따라서 고정 크기의 헤더를 가질 수 있습니다. "100 바이트에서 시작하는 태그 목록이 있으며 40 개의 태그가 포함되어 있습니다." 태그는 고정 크기 (예 : 16 바이트)가되므로 바이트 100에서 시작하는 40 개의 16 바이트 청크를 읽어야합니다.태그에는 이미지 데이터의 시작 위치의 바이트 오프셋, 픽셀의 바이트 수 및 픽셀 수 등의 정보가 들어 있습니다. 이를 통해 전체 형식이 무엇인지 미리 알지 못해도 데이터를 읽을 수 있습니다.

관련 문제