ios - 在 iOS 中,在纯 C 中,这是获取本地文件路径的方法吗?
<p><p>我最终需要一个 cstring ... 作为包中文件的本地路径。</p>
<p>首先,</p>
<pre><code>#include <CoreFoundation/CoreFoundation.h>
</code></pre>
<p>(这是纯 C 对吗?.. 你不能使用 Foundation)</p>
<p>然后</p>
<pre><code>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 );
</code></pre>
<p>假设“blah.txt”在你的包中,它可以工作。</p>
<p>这是我知道的唯一方法 - 似乎很啰嗦。有什么关系?</p>
<ol>
<li><p>我的代码是不是冗长、三色堇、可怜?</p></li>
<li><p>这是从文件名中获取 cstring 路径的正确和最佳习惯用法吗?</p></li>
</ol>
<p>(注意我<strong><em>不希望</em></strong>将其设为 obj-c 或 obj-cpp 文件。纯 C。)</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>您的代码实际上不够长,并且有一些小错误:</p>
<ul>
<li>你必须<code>CFRelease</code>你拥有的所有对象。您可能会在其他地方执行此操作,但这从代码中并不明显。</li>
<li><code>CFStringGetCStringPtr</code> 不 promise 返回值。如果字符串已经以您想要的格式在内部存储,它只会返回一个值。这<em>可能</em>在每个可能实际运行的系统上的代码中都是正确的,但它不是安全的 CoreFoundation 做法。</li>
<li>同样,将 <code>CFStringGetSystemEncoding</code> 的结果传递给 <code>CFStringGetCStringPtr</code> 也是不安全的,因为后者需要 8 位编码。这不是 promise 的,但是....</li>
<li><code>CFStringGetSystemEncoding</code> 几乎从不需要或不合适。您可能实际上并不想要 MacRoman(这可能是您得到的,除非您可能配置了 MacJapanese)。您可能需要 UTF8,因此您应该提出要求。</li>
</ul>
<p>所以你会这样做:</p>
<pre><code>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;
</code></pre>
<p>您可以找到 <a href="https://github.com/iosptl/ios7ptl/blob/master/ch10-CoreFoundation/CoreFoundation/MYStringConversion.c" rel="noreferrer noopener nofollow">MYStringConversion</a>功能有帮助。 <code>MYCFStringCopyUTF8String</code> 为您返回一个包含 cstring 的 malloc 缓冲区(即您需要 <code>free</code> 它)。 (这些来自 iOS 编程的第 10 章:挑战极限。)</p>
<p>关于字符串缓冲区的一个侧面说明。人们经常倾向于使用基于 <code>PATH_MAX</code> 的缓冲区。请记住,macOS 允许名称比 <code>PATH_MAX</code> 长得多的路径。我不知道对 macOS 路径字符串的长度有任何硬性限制。在实践中,很少有真正的路径超过 <code>PATH_MAX</code>,但是当你创建一个路径时,看看有多少软件中断是有趣的(实际上并不有趣)。</p>
<p>请注意,通常不需要此代码。在大多数 CoreFoundation 项目中,您只需直接使用 <code>ur</code>,这与使用原始 cstrings 相比非常好。</p></p>
<p style="font-size: 20px;">关于ios - 在 iOS 中,在纯 C 中,这是获取本地文件路径的方法吗?,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/54099589/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/54099589/
</a>
</p>
页:
[1]