2016-06-27 46 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)) 
相关问题