文章編號: 125713 - 上次校閱: 2006年11月21日 - 版次: 3.1

常見的檔案對應問題] 和 [平台差異

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

本文將說明使用檔案對應時所發生的一些常見問題。它也會指出檔案的對應實作某些平台的差異。

本文不會說明程序,以執行檔案對應。 如需使用檔案對應資訊,請參閱檔案對應概觀 Microsoft Win32 程式設計人員參考 》 中。也請參閱 CreateFileMapping()、 OpenFileMapping()、 MapViewOfFile()、 MapViewOfFileEx()、 UnmapViewOfFile(),和 FlushViewOfFile() 描述。

其他相關資訊

名稱空間衝突

事件、 號誌、 Mutex 和檔案對應物件的名稱共用相同的命名空間,因此不可能有相同名稱的兩個不同的物件型別。它是以嘗試建立或開啟一個使用已經正由另一個型別的物件的名稱的型別物件錯誤。

如果它們指定正由另一個型別的物件使用中的物件名稱,將會失敗 CreateFileMapping() 和 OpenFileMapping()。在這兩種情況下 GetLastError() 會傳回 ERROR_INVALID_HANDLE (6)。

若要避免物件型別之間的衝突,一個解決方案是在名稱中包含的物件類型。比方說用於 EV_myapp_block_ready 」 的事件物件名稱和 FM_myapp_missile_data"檔案對應物件名稱。

necessity 的 unmapping 對應檔案的所有檢視

是否 MapViewOfFile() 或 MapViewOfFileEx() 所建立的 Windows 就會維護該物件中的每一個檢視的檔案對應物件的內部控制代碼。這個內部的控制代碼是另外保持 CreateFileMapping() 所傳回的控制代碼。內部控制代碼不被封閉的直到由呼叫 UnmapViewOfFile() unmapped 與控制代碼相關聯的檢視。若要完全關閉檔案對應物件會需要先關閉所有的控點,用於該物件包括內部控點。因此,以關閉 [檔案對應物件的該物件的所有檢視必須都是未對應,而且必須關閉控點由 CreateFileMapping() 傳回。

現存的檔案對應物件的未對應的檢視不會導致一個 CloseHandle() 上物件的控制碼失敗。亦即成功關閉物件的控制代碼時, 它不一定真所有檢視都已未對應,所以檔案對應物件已不一定是都被釋放。

正確 unmap 物件的所有檢視,及關閉物件控制代碼失敗會造成遺漏 (Memory Leak) 應用程式的分頁集區、 未分頁集區、 虛擬位元組,而且也在系統中廣泛認可的位元組。

檔案對應物件的大小限制

由系統分頁檔支援的檔案對應物件的大小受限於可用的系統虛擬記憶體 (這表示可能是 VirtualAlloc()) 的呼叫與認可的記憶體數量。

在 Windows NT 上具名的磁碟檔案備份的檔案對應物件的大小會受到可用的磁碟空間限制。物件的對應檢視的大小是限制為執行對應 (至多減去已經處理序所保留的虛擬記憶體 2 GB) 處理序中未保留的虛擬記憶體的最大的連續區塊。

上 Win32s,具名的磁碟檔案備份的檔案對應物件的大小受限於可用的系統虛擬記憶體限於 Win32s 的虛擬記憶體管理實作。Win32s 會定期的虛擬記憶體配置記憶體的對應的區段即使它並不需要交換空間而由 Windows 所設定的 VM 的量太小而無法用於對應大型檔案。如同 Windows NT 可用磁碟空間也強加限制。

在 Windows 95 上具名的磁碟檔案備份的檔案對應物件的大小受限於可用的磁碟空間。物件的對應檢視的大小是限制為共用虛擬競技場中未保留的虛擬記憶體的最大的連續區塊。這個區塊會最多 1 GB 減去使用中的其他元件的 Windows 95 用 (例如 16 位元 Windows 架構應用程式) 共用虛擬競技場任何記憶體。每個對應的檢視將會從這個競技場使用記憶體,所以這項限制適用於所有非重疊的對應檢視所有系統上執行的應用程式的總大小。

對應的檔案可能不會自動成長

如果指定的檔案對應物件大小備份由具名磁碟 CreateFileMapping() 的呼叫中的檔案是大於用來備份對應檔案的大小,檔案通常將會被指定的大小由 CreateFileMapping() 呼叫增長。

上僅使用 Windows NT,如果 PAGE_WRITECOPY 指定 fdwProtect] 參數檔案將不會自動被成長。這會導致失敗,CreateFileMapping() 並且 GetLastError() 會傳回 ERROR_NOT_ENOUGH_MEMORY (8)。若要呼叫 CreateFileMapping() 之前先設定檔案的大小,使用 [SetFilePointer() 和 SetEndOfFile()]。

MapViewOfFileEx() 和 lpvBase 的有效範圍

在 Windows NT 上在 0-2 的位址範圍中對應的檔案對應物件檢視 GB。傳遞此範圍之外的位址作為 lpvBase MapViewOfFileEx() 的參數會使它失敗,並且 GetLastError() 會傳回 ERROR_INVALID_PARAMETER (87)。

在 Windows 95 上檢視檔案對應物件會對應 2-3 GB (共用虛擬競技場) 位址範圍中。傳遞此範圍之外的位址會導致失敗,MapViewOfFileEx() 並且 GetLastError() 會傳回 ERROR_INVALID_ADDRESS (487)。注意 Windows 95 的未來更新可能會將對應範圍變更為 0 2 GB,為 Windows NT 上。

lpvBase MapViewOfFileEx() 與配置狀態

如果地址指定給 lpvBase 參數的 MapViewOfFileEx(),而且不該位址不夠大,無法滿足 cbMap 參數中指定的位元組數目的未保留的虛擬位址空間區塊,然後 MapViewOfFileEx() 將會失敗,並且 GetLastError() 會傳回 ERROR_NOT_ENOUGH_MEMORY (8)。這並不表示系統記憶體不足,或處理程序無法配置更多的記憶體。它只是表示所要求的虛擬位址範圍已經已保留在該處理序中。

之前要呼叫 MapViewOfFileEx() VirtualQuery() 可用來判斷適當的範圍,未保留的虛擬位址空間。

MapViewOfFileEx() 和 lpvBase 細微性

針對 MapViewOfFileEx() 的呼叫中指定參數 lpvBase,您應該使用系統的配置資料粒度的整數倍。在 Windows NT 上未指定這類的值將導致 MapViewOfFileEx() 失敗,並返回 ERROR_MAPPED_ALIGNMENT GetLastError() (1132)。在 Windows 95 上地址會捨去小數,而系統的配置資料粒度最接近的整數倍數。

若要判斷系統的配置資料粒度,呼叫 GetSystemInfo()。

對應的檢視表的地址

對應檔案 (或共用的記憶體) 的檢視,時可能可以讓作業系統決定在檢視的位址,或做為 lpvBase 參數 MapViewOfFileEx() 函式的指定位址。如果檔案對應要在多個處理程序之間共用,建議的方法就是使用 MapViewOfFile(),讓選取對應位址為您的作業系統。這樣的好理由有:
  • 在 Windows NT 上檢視表是獨立到每個處理序位址空間對應。雖然可能會方便嘗試對應於相同位址,每個處理程序中檢視,不可能可用在所有的相關處理程序中指定的虛擬位址範圍。因此,對應可能會失敗一 (或多個) 處理程序嘗試要共用檔案對應中。
  • 在 Windows 95 上檔案對應物件存在於 2-3 GB 位址範圍 (共用虛擬競技場)。因此,一旦決定初始檢視的位址對應的其他檢視會對應到每個處理程序中相同的位址還是,而且沒有在嘗試強制初始對應到特定的位址沒有好處。為對應物件第二個及後續檢視,如果位址指定給 lpvBase 不符合實際的位址,Windows 95 已對應檢視然後 MapViewOfFileEx() 失敗,並且 GetLastError() 傳回 ERROR_INVALID_ADDRESS (487)。此外,嘗試對應第一個檢視在預定位址時, 該位址可能已被使用中的其他元件的 Windows 95 用共用的虛擬競技場。注意 Windows 95 的未來更新可能會將對應範圍變更為 0 2 GB,為 Windows NT 上。
如果是絕對必要,在相同的地址,在 [Windows NT 的多個處理序中建立對應以下是兩種可能的方法:
  1. 挑選適當的地址和管理虛擬位址空間,使這個地址會保持可用。這表示基於您的 DLL、 配置於特定位置的記憶體,而且使用這類的處理序 Walker 工具來觀察虛擬位址空間圖樣。儘速中在應用程式執行時,請保留您想要的地址空間或執行對應。執行這項操作的一個很好的起點將 PROCESS_ATTACH 處理一個 DLL 中,因為啟動可執行檔本身之前呼叫它。注意: 沒有仍然某些 DLL 將具有已載入地址能保證有問題。如果不是所有相關的處理程序可以在預先決定的位址對應,他們可以在失敗,或嘗試新的地址。

    -或者-
  2. 所有處理程序牽涉到有交涉適當的地址。處理程序所有 [VirtualQuery() 函數可用來掃描其地址空間,直到一個常見的位址找到有一大每個處理程序中足夠的未保留的區塊。這需要涉及的所有處理序同時對應位址。開始之後判定此位址的處理程序必須在該位址對應,然後如果它無法這麼做會失敗。或者,流通程序可能會重複顯示,與在新的位址每個處理程序重新對應。然後,必須被 readjusted 對應到的所有指標。
第二種方法很多可能成功。也可以結合與,使其更有可能適當的地址將會快速地找到第一個。

當檢視表會對應至不同的地址在 Windows NT 下時,發生困難度儲存對應本身內對應的指標。這是因為在一個處理序中的指標未指向相同的位置內對應的另一個處理程序。若要克服此問題、 將位移,而不是指標儲存在對應並藉由將對應的基底位址加入位移計算每個處理程序中的實際位址。它也有可能使用的基底指標,並因此 [執行基底] + [隱含位移轉換]。簡短的 SDK 範例呼叫 BPOINTER 示範這項技術。

其他平台差異

執行時的額外限制檔案在 Windows 95 下的對應:
  1. MapViewOfFile() 和 MapViewOfFileEx() dwOffsetHigh 參數沒有使用,並且應該為零。Windows 95 會使用 32 位元的檔案系統。
  2. CreateFileMapping() dwMaximumSizeHigh 參數未使用,並且應該為零。這一次,是由於 32 位元的檔案系統。
  3. 不支援的 CreateFileMapping() fdwProtect 參數 SEC_IMAGE 和 SEC_NOCACHE 旗標。
  4. 如果 FILE_MAP_COPY 旗標用來對應的檔案對應物件檢視,必須有已建立物件使用 PAGE_WRITECOPY 保護。此外,命名的檔案,而不是系統分頁檔必須備份物件 (亦即是有效的檔案處理,不 (控點) 0xFFFFFFFF,必須為指定的 CreateFileMapping()) hFile 參數。如果要執行其中一項操作的故障導致 MapViewOfFile() 失敗,並 GetLastError() 傳回 ERROR_INVALID_PARAMETER (87)。
  5. 如果兩個或多個處理程序 (藉由例如使用具名的物件) 對應的相同的檔案對應物件 PAGE_WRITECOPY 檢視,它們將可以看到檢視對其他處理程序所做的變更。實際的磁碟檔案並沒有修改,不過。在 Windows NT 下如果其中一個處理序將寫入至檢視它便會接收它自己的複本的修改過的網頁並不會影響其他處理程序或磁碟檔案中的頁。

這篇文章中的資訊適用於:
  • Microsoft Win32 Application Programming Interface?應用於:
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows 95
    • Microsoft Win32s 1.3
關鍵字:?
kbmt KB125713 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:125713? (http://support.microsoft.com/kb/125713/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。