2016-06-27 68 views
1

當我將iOS設備設置爲例如越南,然後將下面的代碼失敗有時TFileStream.Create在某些設備語言的iOS上失敗

var 
    lFilePath: String 
... 
lFilePath := TPath.GetTempPath + '/MyDBfile.db'; 
lFileStream := TFileStream.Create(lFilePath, fmOpenReadWrite or fmShareExclusive or fmCreate); 

的TFileStream.Create調用產生的斷言:「EFCreateError:無法創建文件」/私營/無功/移動/集裝箱/數據/應用/ {數據筒} /tmp/MyDBfile.db「 沒有這樣的文件或目錄」。 只有當設備設置爲某些語言(包括越南語)時,纔會使用西歐語言提出斷言。

我跟蹤的創建代碼到該行的FileCreate功能的System.SysUtils

FileHandle := Integer(__open(M.AsAnsi(FileName, CP_UTF8).ToPointer, 
    O_RDWR or O_CREAT or O_TRUNC or Exclusive[(Mode and $0004) shr 2], Rights)); 

文件句柄爲-1時斷言提高。

什麼可能是錯的?

PS:在我試圖找出發生了什麼,我加了Fileexists電話:

lFilePath := TPath.GetTempPath + '/MyDBfile.db'; 
if Fileexists(lFilePath) then 
    System.Sysutils.DeleteFile(lFilePath); 
lFileStream := TFileStream.Create(lFilePath, fmOpenReadWrite or fmShareExclusive or fmCreate); 

現在,在代碼失敗的情況下,我有以下奇怪的發現: 在Xcode,這可以顯示容器的應用程序,它顯示文件tmp/MyDBfile.db在容器中,即該文件確實存在(該文件僅由引用的代碼創建,因此它創建了代碼成功的一次)。但是,Fileexists同時返回false。

該文件是一個SQLite文件,稍後將由sqlite3_open_v2打開並在關閉之後不久被sqlite3_close打開。 SQLite可能會將文件置於Fileexists返回false的狀態嗎? (該狀態在重新啓動應用程序後仍然存在)

+0

哪種類型有'lFilePath'? –

+0

@KeremD它是一個字符串,我只是更新了問題以包含它。事實上,我認爲我已經解決了這個問題,但正在等待越南客戶的最終確認,越南客戶在我發佈這個問題之前先報告了問題。從我發現的,它是TPath.GetTempPath使用錯誤的方式來獲取tmp路徑,只有越南語和其他幾種語言失敗... – Hans

回答

1

問題是當前實施的TPath.GetTempPath。它使用普通Posix方法ExpandFileName('~/tmp/')。但是,Apple推薦的方法是使用NSTemporaryDirectory

這兩種方法都返回到tmp目錄的路徑,但NSTemporaryDirectory也會創建該文件夾(如果它不存在) - 這似乎是不同之處。奇怪的是,Delphi實現只會在某些iOS設備語言(包括越南語)下失敗。我沒有進一步的調查,但對於現在的解決方案是簡單地用這個Delphi代碼替換TPath.GetTempPath

NSStrToStr(TNSString.Wrap(NSTemporaryDirectory)) 
相關問題