2009-06-22 82 views
2

如果我使用mmap來編寫uint32_t's,我是否會遇到大端/小端公約的問題?特別是,如果我在大端機器上編寫一些數據mmap,我會在嘗試在小端機器上讀取數據時遇到問題嗎?mmap big endian與little endian

回答

2

是的。

mmap映射原始文件數據以處理地址空間。它不知道什麼是原始數據,更不用說爲你轉換它。如果您在具有不同字節順序的體系結構上映射相同的文件,則必須自己進行必要的轉換。

作爲一種跨計算機的便攜式數據格式,我會考慮具有更高抽象層次的東西,比如JSON甚至是XML,它不會將數據格式與特定實現綁定。但它確實取決於您的具體要求。

5

如果你使用mmap,你可能會關心速度和效率。你基本上有幾個選擇。

  1. 用htonl,htons,ntohl,ntohs函數包裝所有的讀寫操作。在Windows上調用htonl(主機到網絡)命令會將數據從小端轉換爲大端。在其他架構上,這將是一個noop。這些轉換確實存在開銷,但取決於您的運營情況,它們可能很重要,也可能不重要。 AFAIK,這是SQLite使用的方法
  2. 您的其他選擇是始終以主機格式寫入數據,並在用戶需要跨平臺遷移數據時提供例程。數據庫通常以主機格式讀寫數據,但提供像bcp這樣的工具,可以寫入ASCII或網絡字節順序。
  3. 您可以使用字節順序標記標記文件的標題。當你的程序啓動時,它會將它的字節順序與文件的字節順序進行比較,並在需要時提供任何翻譯。對於簡單的數據格式(如UTF-16)而言,這通常很有用,但對於具有多種可變長度類型的格式不適用。

此外,如果您要做的事情如提供長度前綴或文件偏移量,則可能會混合使用32位和64位指針。 32位平臺無法創建大於4GB的mmap視圖,因此您不太可能支持大於4 GB的文件大小。像rrdtool這樣的程序採用這種方法,並在64位平臺上支持更大的文件大小。這意味着如果您在文件中使用了平臺指針大小,那麼您的二進制文件將不會跨平臺兼容。

我的建議是預先忽略所有字節順序問題,並設計系統在您的平臺上快速運行。如果/當您需要將數據移至其他平臺時,請選擇最簡單/最快/最合適的方法。如果你試圖創建一個獨立於平臺的數據格式,那麼你通常會犯錯誤,之後必須回去修正這些錯誤。當99%的數據是正確的字節順序時,這是特別有問題的,其中1%是錯誤的。這意味着修復數據轉換代碼中的錯誤會破壞所有平臺上的現有客戶端。

在編寫代碼以支持多個平臺之前,您需要進行多平臺測試設置。

+0

除了我們確定英特爾字節排序是最自然的數據存儲方式之外,我們有類似的問題:幾乎所有客戶都運行Linux(Intel)服務器或Windows(當然是英特爾)服務器。大端已經過時了。 – 2009-09-10 01:17:21