2017-12-05 9 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

最初にこのログファイルに悪いソリューションです。呼び出し側場合

:(なしFILE_FLAG_OVERLAPPEDため)FILE_APPEND_DATASYNCHRONIZEこの場合、あなたが開いているファイルに

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

:そう呼び出しがどのように見える必要があります - あなたはGENERIC_READ | GENERIC_WRITE代わりに/ FILE_APPEND_DATAアクセスと、開いているファイルを作成して必要FILE_APPEND_DATASYNCHRONIZEフラグのみを設定すると、 はファイルの最後に書き込むことができ、オフセット情報は に書き込むことができますファイルは無視されます。ファイルは、このタイプの操作に必要に応じて が自動的に拡張されます。

この後、ログはWriteFile経由で必要です。自動的にファイルの末尾に追加されます。これはログファイルが必要とするものです。 CreateFileMappingMapViewOfFileを使用したい場合は

しかし、 - エラーの最初のCreateFileMappingリターン0で、そのチェック if (hMapping == INVALID_HANDLE_VALUE)は、ファイルのサイズを変更したい場合は

間違っている - あなたはFileEndOfFileInfo(ビスタ+)で、このSetFileInformationByHandleに使用必要がありますかFileEndOfFileInformationNtSetInformationFile(ハードSetFileInformationByHandleNtSetInformationFileまたはZwSetInformationFile以上の非常に薄いシェルで理解できないどのように、どこでも作業が(ユーザーモードで、これは同じ機能です))。 SetFilePointerを使用してください。SetEndOfFileでも可能ですが、有効ではありません。単体ではなくsrcコードで2つの呼び出しがあります。バイナリで - あなたはさらに悪い状況:最初にファイルの位置を設定すると、SetEndOfFileこのファイルの位置を読み取って、最後にこの位置でNtSetInformationFileを呼び出します。だから、3人が1人を呼び出す。そしてSetFilePointerSetEndOfFile通話

間(このハンドル上の)その誰も変更ファイルの位置をとるが、明確なあなただけアンマップビューと近いセクションの後にすることができますFileEndOfFileInfoでそのコールSetFileInformationByHandleを理解する必要があります。そうでなければ、CreateFileMapping関数が のhFile用ファイルマッピングオブジェクトを作成するために呼び出され

場合はエラーERROR_USER_MAPPED_FILESTATUS_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を追加する必要があります。 CreateFileMappingMapViewOfFileすべての

関連する問題