2017-12-05 1 views
-1

이 코드에서는 메모리 매핑 된 텍스트 파일에 일부 텍스트를 쓰고 있습니다. 데이터는 파일에 성공적으로 기록되지만 메모장에서 열면 기록 된 데이터 뒤에 "NULL"이 작성된 텍스트보다 큰 매핑 된 메모리 제한까지 반복적으로 기록됩니다.메모리 매핑 된 텍스트 파일에 쓰기 매핑 된 메모리의 끝까지 NULL 인쇄

가능한 이유는 무엇입니까?

pLogMsg = (char*)calloc(1024,sizeof(char)); 
printf("[INFO] entering logger writeback thread\n"); 

log_file = CreateFile (TEXT("one.txt"),    // Open one.txt. 
        GENERIC_READ | GENERIC_WRITE, // Open for reading and writing 
        FILE_SHARE_WRITE,    // file share 
        NULL,       // No security 
        OPEN_ALWAYS,     // Open or create 
        FILE_ATTRIBUTE_NORMAL,   // Normal file 
        NULL);       // No template file 
if (log_file == INVALID_HANDLE_VALUE) 
{ 
    printf("%d [ERR] cant open file GLE %d\n",GetCurrentThreadId(),GetLastError()); 
    return -1; 
} 
hMapping = CreateFileMapping(log_file, 0, PAGE_READWRITE, 0,4096 ,0); 
if (hMapping == INVALID_HANDLE_VALUE) 
{ 
    printf("%d [ERR] cant create file mapping %d\n",GetCurrentThreadId(),GetLastError()); 
    return -1; 
} 
pFileData = (CHAR*)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0,0, 0); 
if (pFileData == NULL) 
{ 
    printf("%d [ERR] cant mapview of file %d\n",GetCurrentThreadId(),GetLastError()); 
    return -1; 
} 
pLogMsg = LogPrint();//returns a null terminated string 
memcpy(pFileData,pLogMsg,strlen(pLogMsg)); 
pFileData += strlen(pLogMsg); 
free(pLogMsg); 
+0

일반적인주의 사항으로 'hMapping == INVALID_HANDLE_VALUE' - 이것은 오류입니다. 'CreateFileMapping'은 실패시 0을 반환합니다. – RbMm

답변

1

먼저 CreateFileMappingMapViewOfFile 이것은 로그 파일에 대한 나쁜 해결책입니다. 당신은 FILE_APPEND_DATA 액세스 대신 GENERIC_READ | GENERIC_WRITE와/열린 파일을 만들 필요 - 그래서 전화를 찾아야 같은 :이 경우

HANDLE log_file = CreateFileW(L"one.txt", 
    FILE_APPEND_DATA, 
    FILE_SHARE_WRITE|FILE_SHARE_READ,  
    NULL, 
    OPEN_ALWAYS,     
    FILE_ATTRIBUTE_NORMAL, 
    NULL); 

FILE_APPEND_DATASYNCHRONIZE (없기 때문에 FILE_FLAG_OVERLAPPED)와 당신이 열려있는 파일 :

호출자의 경우 FILE_APPEND_DATASYNCHRONIZE 플래그 만 설정하면 은 파일 끝 부분에만 쓸 수 있고 오프셋 정보는 에 대한 쓰기 작업이 가능합니다. 파일은 무시됩니다. 이 파일 형식은 으로 자동으로 확장됩니다.

이 후에는 WriteFile을 통해 로그가 필요합니다. 자동으로 파일 끝에 추가됩니다. 이것은 정확히 로그 파일에 필요한 것입니다. CreateFileMappingMapViewOfFile를 사용하려는 경우

그러나, - 오류에 첫 CreateFileMapping 반환 0, 그래서 확인 if (hMapping == INVALID_HANDLE_VALUE)은 파일 크기를 변경하려는 경우

잘못된 것입니다 - 당신이 FileEndOfFileInfo (비스타 +)와 함께이 SetFileInformationByHandle 사용이 필요하거나 NtSetInformationFileFileEndOfFileInformation (모든 곳에서 작업하고 있습니다. SetFileInformationByHandleNtSetInformationFile 또는 ZwSetInformationFile 이상의 매우 얇은 쉘입니다 (사용자 모드에서는 동일한 기능입니다)). SetFilePointer을 사용하고 SetEndOfFile도 가능하지만 나쁘지 만 효과적이지는 않습니다. 단일 전화 대신 src 코드를 2 번 호출합니다. 바이너리에서 - 더 나쁜 상황이 될 것입니다 : 먼저 파일 위치를 설정하면 SetEndOfFile이 파일 위치를 읽고 마지막으로 NtSetInformationFile을이 위치로 호출합니다. 그래서 3 대신에 3이 호출됩니다.및

전화 SetFilePointer 사이 SetEndOfFile (이 핸들) 그 아무도 변경 파일의 위치를 ​​가정하지만, 분명 필요 FileEndOfFileInfo와 그 전화 SetFileInformationByHandle을 이해 할 수 있습니다 만의 매핑을 해제보기 및 확대 섹션 후. 그렇지 않으면하여 CreateFileMapping이 HFILE에 대한 파일 매핑 개체를 만들라고

경우 오류 ERROR_USER_MAPPED_FILE (STATUS_USER_MAPPED_FILE)를 가지고, UnmapViewOfFile은을 닫하여 CloseHandle 모든 뷰와 전화 의 매핑을 해제 먼저 호출해야 파일 매핑 개체 전에 전화 SetEndOfFile.

1

파일 내에 '파일 끝'표시자가 없습니다. OS가 올바르게 표시하도록 파일 길이를 설정해야합니다. 당신은 파일 매핑을 통해 파일 끝 마커를 설정할 수 없습니다 SetEndOfFile

Sets the physical file size for the specified file to the current position of the file pointer.

+0

['SetFilePointer'] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=vs.85) .aspx)가 필요할 수도 있습니다. –

+0

쓰기가 끝나면 SetEndOfFile이 문제를 해결하지 못했습니다. –

+0

@ DhyanDeepA.K - 파일 크기를 설정하고 'ERROR_USER_MAPPED_FILE'을 (를) 얻으려면보기 및 닫기 섹션의 매핑을 해제하지 않았을 것입니다. – RbMm

1

에 대한

참조 MSDN 설명서를 참조하십시오. 파일 끝 마커는 실제로 파일에 존재하지 않습니다. 파일 끝을지나 읽을 때 OS에서 발생시키는 플래그입니다.

파일 크기를 설정하려면 SetFilePointer을 호출 한 다음 파일 매핑을 만드는 데 사용 된 파일 객체에서 SetEndOfFile을 호출해야합니다.

관련 문제