2014-09-12 5 views
0

레거시 시스템에서 파일 읽기 문제를 해결하려고합니다.read() 일부 시스템에서 읽은 잘못된 바이트 수를 반환합니다.

모든 SP, SDK 및 IDE가 설치된 Windows7/SP1/64bit 시스템에서만 테스트되고 실행되는 32 비트 Windows 응용 프로그램입니다. IDE는 VS2010/SP1입니다. 그래서

#define ANZSEL 20 

int ii, bfil, ipos; 

if ((bfil = open("Z:\\whatever.bla", O_RDONLY, 0)) == -1) { goto end; } // please don't complain about this; it's just here because I didn't want to rephrase the if == -1 above and because it's a legacy codebase; i also tried with UNC paths by the way with the same result 

    ii = read(bfil, &some_struct_instance, sizeof(some_struct)); 
    ipos = _lseek(bfil,0,SEEK_CUR); // ipos shows the correct position here, ie. sizeof(some_struct) 
    if (ii == sizeof(some_struct)) { 

     ii = read(bfil, &another_struct_instance, sizeof(another_struct)*ANZSEL); // ii here sometimes shows 15 instead of sizeof(another_struct)*ANZSEL 
     ipos = _lseek(bfil,0,SEEK_CUR); // ipos always shows the correct value of sizeof(some_struct) + sizeof(another_struct)*ANZSEL 
     if (ii == sizeof(another_struct)*ANZSEL) { 

     // should always come here as long as the files' long enough 

당신이 볼 수 있듯이, 일부 구조체로 읽는 평범한 구식 직접 바이너리해야한다 :

여기에 문제의 코드입니다. 내가 관찰 할 수있는 것은 파일을 만들고 처음에 memset/Zeromem을 사용하여 구조체를 지우고 0xCC 대신 0x00 (초기화되지 않은 디버그 모드로 mem에 태그 지정하는 microsoft의 방법 인 모든 초기화 바이트)을 초기화하는 것입니다 stack mem) 이전에 제대로 작동하지 않은 시스템에서 문제가 사라집니다. 그것이 내가 "제대로"문제를 해결할 수있는 방법을 나에게 분명히 보이지만

-이 너무 다르게 작동 할 수있는 이유에 대한 단서가없는

if ((bfil = open("Z:\\whatever.bla", O_RDONLY|O_BINARY, 0)) == -1) 

같은 오픈에서 O_BINARY()를 지정합니다. 두 시스템에서 open() 및 read() 소스를 단계별로 시도했지만 문제가 재현 될 수있는 유일한 시스템에만 액세스 할 수 있기 때문에 아직 아무것도 찾을 수 없습니다.

내 질문은 누군가가 이런 일이 발생하는 이유를 지적하고 일부 문서를 참조 할 수있는 경우입니다.

+0

@ JerryCoffin 방금 살펴 봤지만 파일에 0x1a가 없습니다. 필자는 항상 동일한 파일을 사용하여 모든 시스템 btw에서 테스트했습니다. –

+0

http://msdn.microsoft.com/en-us/library/wyssk1bs.aspx - 텍스트 모드에서 CR-LF 쌍은 단일 LF로 바뀝니다. 또한 (적어도 Visual Studio를 사용하여)'read'와'open' POSIX 호출은 더 이상 사용되지 않습니다. – icabod

+0

@icabod 모두 사실이지만 모든 시스템에서 동일한 동작이 발생하지 않아야합니까? Btw, 물론 impl. 우리가 64 비트 시스템으로 확장하고 엔디안이 다른 시스템으로 확장 할 계획이기 때문에 바이트 순서가 더 이상적이지 않은 것으로 변경 될 것입니다. 그러나 나는 단지 read()와 친구에 대해 놓친 것이 궁금합니다. –

답변

3

일반적으로 파일에 0x1a (별칭 : control-Z) 값이 포함 된 경우에 발생합니다. MS-DOS와 마찬가지로 Windows는 Ctrl-Z를 텍스트 파일의 끝을 나타내는 것으로 해석하므로 텍스트 모드에서 파일을 열고 0x1a에 도달하면 단순히 읽기만 멈 춥니 다.

이미 발견했듯이 이진 모드에서 파일을 열면 문제가 해결됩니다. 0x1a는 더 이상 파일 끝을 알리는 것으로 해석되지 않습니다.

+0

@eryksun : 실제로는 OS 자체 (대개 어쨌든)입니다. http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462.aspx –