// Get the size of the file (I assume the whole file can be mapped). DWORD dwFileSize = GetFileSize(hFile, NULL);现在已经得到了文件的长度,你能够通过调用CreateFileMapping函数创建文件映射对象。创建的文件映射对象的长度是dwFileSize加一个宽字符的大小(对于0字符来说)。当文件映射对象创建后,该对象的视图就被映射到FileReverse的地址空间。变量pvFile包含了MapViewOfFile函数的返回值,并指向文本文件的第一个字节。
// 文件末尾添加 0,作为字符串的结束符 PSTR pchANSI = (PSTR) pvFile; pchANSI[dwFileSize / sizeof(CHAR)] = 0;在文本文件中,每一行的结尾都是一个回车符(‘\ r’)后随一个换行符(‘\ n’)。但是,当调用_strrev对文件进行倒序时,这些字符也会被倒序。如果将已经倒序的文本文件加载到文本编辑器,那么出现的每一对“ \ n \ r”字符都必须重新改为它的原始顺序。这个倒序操作是由下面的循环代码进行的:
while (pchANSI != NULL) { // We have found an occurrence.... *pchANSI++ = '\r'; // Change '\n' to '\r'. *pchANSI++ = '\n'; // Change '\r' to '\n'. pchANSI = strstr(pchANSI, "\n\r"); // Find the next occurrence. }当你观察这样一个简单的代码时,可能很容易忘记你实际上是在对磁盘驱动器上的文件内容进行操作(这显示出内存映射文件的功能是多么大)。
// Remove trailing zero character added earlier. SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN); SetEndOfFile(hFile);
BOOL CFileRevDlg::FileReverse() { bool bIsTextUnicode = FALSE; // Assume text is Unicode // Open the file for reading and writing. HANDLE hFile = CreateFile(m_DirectoryPath + FILENAME , GENERIC_WRITE | GENERIC_READ ,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE){ MessageBox(_T("File could not be opened.")); return FALSE; } // Get the size of the file (I assume the whole file can be mapped). DWORD dwFileSize = GetFileSize(hFile, NULL); // Create the file-mapping object. The file-mapping object is 1 character // bigger than the file size so that a zero character can be placed at the // end of the file to terminate the string (file). Because I don't yet know // if the file contains ANSI or Unicode characters, I assume worst case // and add the size of a WCHAR instead of CHAR. HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize + sizeof(WCHAR), NULL); if (hFileMap == NULL) { MessageBox(_T("File map could not be opened.")); CloseHandle(hFile); return FALSE; } // Get the address where the first byte of the file is mapped into memory. PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0); if (pvFile == NULL) { MessageBox(_T("Could not map view of file.")); CloseHandle(hFileMap); CloseHandle(hFile); return FALSE; } // Does the buffer contain ANSI or Unicode? int iUnicodeTestFlags = -1; // Try all tests bIsTextUnicode = IsTextUnicode(pvFile, dwFileSize, &iUnicodeTestFlags); SetDlgItemText(IDC_TEXTTYPE,bIsTextUnicode ? TEXT("文件编码:Unicode") : TEXT("文件编码:ANSI")); if (!bIsTextUnicode) { // For all the file manipulations below, we explicitly use ANSI // functions because we are processing an ANSI file. // 文件末尾添加 0,作为字符串的结束符 PSTR pchANSI = (PSTR) pvFile; pchANSI[dwFileSize / sizeof(CHAR)] = 0; // Reverse the contents of the file. _strrev(pchANSI); // Convert all "\n\r" combinations back to "\r\n" to // preserve the normal end-of-line sequence. pchANSI = strstr(pchANSI, "\n\r"); // Find first "\r\n". while (pchANSI != NULL) { // We have found an occurrence.... *pchANSI++ = '\r'; // Change '\n' to '\r'. *pchANSI++ = '\n'; // Change '\r' to '\n'. pchANSI = strstr(pchANSI, "\n\r"); // Find the next occurrence. } } else { // For all the file manipulations below, we explicitly use Unicode // functions because we are processing a Unicode file. // Put a zero character at the very end of the file. PWSTR pchUnicode = (PWSTR) pvFile; pchUnicode[dwFileSize / sizeof(WCHAR)] = 0; if ((iUnicodeTestFlags & IS_TEXT_UNICODE_SIGNATURE) != 0) { // If the first character is the Unicode BOM (byte-order-mark), // 0xFEFF, keep this character at the beginning of the file. pchUnicode++; } // Reverse the contents of the file. _wcsrev(pchUnicode); // Convert all "\n\r" combinations back to "\r\n" to // preserve the normal end-of-line sequence. pchUnicode = wcsstr(pchUnicode, L"\n\r"); // Find first '\n\r'. while (pchUnicode != NULL) { // We have found an occurrence.... *pchUnicode++ = L'\r'; // Change '\n' to '\r'. *pchUnicode++ = L'\n'; // Change '\r' to '\n'. pchUnicode = wcsstr(pchUnicode, L"\n\r"); // Find the next occurrence. } } // Clean up everything before exiting. UnmapViewOfFile(pvFile); CloseHandle(hFileMap); // Remove trailing zero character added earlier. SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN); SetEndOfFile(hFile); CloseHandle(hFile); return TRUE; }
点击下载