在iOS中,在纯C中,这是获取本地文件路径的方法吗?

2024-04-27

我需要最终得到一个 cstring ...作为捆绑包中文件的本地路径。

First,

#include <CoreFoundation/CoreFoundation.h>

(这是纯C,对吧?..你不能使用Foundation)

and then

CFBundleRef mb = CFBundleGetMainBundle();
CFURLRef ur = CFBundleCopyResourceURL(mb, CFSTR("blah"), CFSTR("txt"), NULL);
CFStringRef imagePath = CFURLCopyFileSystemPath(ur, kCFURLPOSIXPathStyle);

CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
const char *filename = CFStringGetCStringPtr(imagePath, encodingMethod);

printf( "\n we did it! .. %s \n", filename );

假设“blah.txt”在你的包中,它就可以工作。

这是我知道的唯一方法 - 似乎很啰嗦。这是怎么回事?

  1. 我的代码是不是冗长、乏味、可悲?

  2. 这是从文件名获取 cstring 路径的正确且最佳的习惯用法吗?

(Note I 不要使其成为 obj-c 或 obj-cpp 文件。纯C.)


您的代码实际上不够长,并且有一些小错误:

  • 你必须CFRelease您拥有的所有物品。您可能在其他地方执行此操作,但这从代码中并不明显。
  • CFStringGetCStringPtr不承诺返回值。仅当字符串已以您想要的格式在内部存储时,它才返回一个值。那是probablytrue 在此代码中,在可能实际运行的每个系统上,但这不是安全的 CoreFoundation 实践。
  • 同样,传递结果也不安全CFStringGetSystemEncoding to CFStringGetCStringPtr,因为后者需要 8 位编码。这不是承诺,但是......
  • CFStringGetSystemEncoding无论如何,几乎从来不需要或不合适。您可能实际上并不需要 MacRoman(这就是您可能得到的,除非您可能配置为 Mac Japanese)。您可能需要 UTF8,所以您应该提出要求。

所以你应该这样做:

CFBundleRef mb = CFBundleGetMainBundle();
CFURLRef ur = CFBundleCopyResourceURL(mb, CFSTR("blah"), CFSTR("txt"), NULL);
CFStringRef imagePath = CFURLCopyFileSystemPath(ur, kCFURLPOSIXPathStyle);

// Now convert to a C-string
CFStringEncoding encoding = kCFStringEncodingUTF8;
CFIndex length = CFStringGetLength(imagePath);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, encoding);

char *filename = (char *)malloc(maxSize + 1); // +1 for \0

// Technically this can fail, but it really, really can't.
CFStringGetCString(imagePath, filename, maxSize, encoding);

printf( "\n we did it! .. %s \n", filename );

// Cleanup
free(filename); filename = NULL;
CFRelease(imagePath); imagePath = NULL;
CFRelease(ur); ur = NULL;

您可能会发现MYStringConversion https://github.com/iosptl/ios7ptl/blob/master/ch10-CoreFoundation/CoreFoundation/MYStringConversion.c功能有帮助。MYCFStringCopyUTF8String返回一个 malloc 缓冲区(即您需要freeit) 包含 cstring。 (这些来自《iOS 编程:突破极限》第 10 章。)

关于字符串缓冲区的旁注。人们经常倾向于使用基于以下内容的缓冲区PATH_MAX。请记住,macOS 允许名称长于PATH_MAX。我不知道 macOS 路径字符串的长度有任何硬性限制。在实践中,很少有实际路径超过PATH_MAX,但是当你创建一个软件时,看看有多少软件出了问题是很有趣的(实际上并不是很有趣)。

请注意,通常此代码不是必需的。在大多数 CoreFoundation 项目中,您只需使用ur直接,与处理原始 cstrings 相比,它非常好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在iOS中,在纯C中,这是获取本地文件路径的方法吗? 的相关文章

随机推荐