ndk文件操做問題及小結

      最近在作文件傳輸,發如今android下用f系列的C庫函數去讀取文件文件大小會受到2G大小的約束,查閱了好久,最後只能去看google的libc源碼,發現瞭如下幾個問題:html

     一、bionic的libc是谷歌基於bsd開發的,大約200k左右,比gnu的libc小一半左右,也比uClibc小,谷歌應該不僅是爲了規避LGPL的靜態連接約束才單獨開發的,多是爲了效率問題;android

     二、gnu的ftello等系列函數通常能夠用宏-D_FILE_OFFSET_BITS 64指定off_t的類型來控制函數是否支持2G以上的文件,也能夠用_LARGEFILE_SOURCE來支持ftello64位之類的函數。但這些宏在ndk裏失效,徹底不可用。ftello64在bionic裏是沒有聲明和定義的,有興趣能夠去看ftell.c的源碼,因此_LARGEFILE_SOURCE失效。那麼第一個宏爲什麼也會失效呢?先看下其聲明:ios

off_t ftello(FILE *fp)

  而後追蹤off_t的定義:ionic

#ifndef _OFF_T_DEFINED_
#define _OFF_T_DEFINED_
typedef __kernel_off_t       off_t;
#endif

  繼續追蹤__kernel_off_t,看其是否受宏-D_FILE_OFFSET_BITS的影響:ide

typedef long __kernel_off_t;

  到這裏就明瞭了,可能等谷歌出了64位的android系統纔會支持ftello之類的64位c庫函數吧。函數

      既然存在以上的問題,那麼如何讀取2G以上的文件呢?其實能夠繞開libc,用系統庫函數,固然因爲沒有緩衝區,效率固然就低一些。谷歌提供了lseek64,配合read和write,就能夠操做4G以上的文件了。看下lseek64的聲明:google

extern off64_t lseek64(int, off64_t, int);

  本身有興趣能夠追蹤off64_t,其實就是long long。spa

      雖然解決問題了,但我仍是想拓展一下,bionic對部分posix風格支持的也不太好,如C++ exceptions和wide chars。其實ios也同樣,都只是儘可能支持,但不徹底,因此我之前寫了一個mmap跨平臺程序在ios7如下版本正常,但在ios7直接崩潰,你們當心點就好。爲了效率,還能夠看看mmap如何操做大文件效率對比.net

相關文章
相關標籤/搜索