菜鸟教程小白 发表于 2022-12-13 05:20:53

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


                                            <p><p>我最终需要一个 cstring ... 作为包中文件的本地路径。</p>

<p>首先,</p>

<pre><code>#include &lt;CoreFoundation/CoreFoundation.h&gt;
</code></pre>

<p>(这是纯 C 对吗?.. 你不能使用 Foundation)</p>

<p>然后</p>

<pre><code>CFBundleRef mb = CFBundleGetMainBundle();
CFURLRef ur = CFBundleCopyResourceURL(mb, CFSTR(&#34;blah&#34;), CFSTR(&#34;txt&#34;), NULL);
CFStringRef imagePath = CFURLCopyFileSystemPath(ur, kCFURLPOSIXPathStyle);

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

printf( &#34;\n we did it! .. %s \n&#34;, 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(&#34;blah&#34;), CFSTR(&#34;txt&#34;), 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&#39;t.
CFStringGetCString(imagePath, filename, maxSize, encoding);

printf( &#34;\n we did it! .. %s \n&#34;, 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]
查看完整版本: ios - 在 iOS 中,在纯 C 中,这是获取本地文件路径的方法吗?