_wfopen等价在MacOSX环境下

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (32)

我期待的是相当于Windows的_wfopen()在Mac OS X下有什么想法吗?

我需要这个来移植一个Windows库,该库使用wchar*它的文件接口。由于这是一个跨平台库,我无法依赖客户端应用程序如何获取文件路径并将其提供给库。

提问于
用户回答回答于

MacOSX中的POSIX API可用于UTF-8字符串.为了转换wchar_T字符串到UTF-8,可以使用MacOSX中的CoreFoundation框架。

下面是一个类,它将从wchar包装一个Utf-8生成的字符串。

class Utf8
{
public:
    Utf8(const wchar_t* wsz): m_utf8(NULL)
    {
        // OS X uses 32-bit wchar
        const int bytes = wcslen(wsz) * sizeof(wchar_t);
        // comp_bLittleEndian is in the lib I use in order to detect PowerPC/Intel
        CFStringEncoding encoding = comp_bLittleEndian ? kCFStringEncodingUTF32LE
                                                       : kCFStringEncodingUTF32BE;
        CFStringRef str = CFStringCreateWithBytesNoCopy(NULL, 
                                                       (const UInt8*)wsz, bytes, 
                                                        encoding, false, 
                                                        kCFAllocatorNull
                                                        );

        const int bytesUtf8 = CFStringGetMaximumSizeOfFileSystemRepresentation(str);
        m_utf8 = new char[bytesUtf8];
        CFStringGetFileSystemRepresentation(str, m_utf8, bytesUtf8);
        CFRelease(str);
    }   

    ~Utf8() 
    { 
        if( m_utf8 )
        {
            delete[] m_utf8;
        }
    }

public:
    operator const char*() const { return m_utf8; }

private:
    char* m_utf8;
};

用法:

const wchar_t wsz = L"Here is some Unicode content: éà€œæ";
const Utf8 utf8 = wsz;
FILE* file = fopen(utf8, "r");

这将适用于读取或写入文件。

用户回答回答于

只想使用可能包含Unicode字符的路径打开文件句柄,对吗?只要把小径往里走就行了文件系统表示fopen

  • 如果路径来自股票MacOSX框架(例如,一个开放面板,不管是Carc还是Cocoa),将不需要对其进行任何转换,并且可以按原样使用它。
  • 如果自己生成部分路径,应该从路径创建一个CFStringRef,然后在文件系统表示中将其传递给POSIX API,如openfopen

一般来说,对于大多数应用程序来说,不需要做很多这样的工作。例如,许多应用程序可能有存储用户应用程序支持目录的辅助数据文件,但是只要这些文件的名称是ASCII,并且使用标准的MacOSXAPI来定位用户的应用程序支持目录,就不需要对用这两个组件构造的路径进行大量偏执的转换。

编辑后添加:我强烈警告抗衡任意地将所有内容转换为UTF-8,使用如下所示wcstombs因为文件系统编码不一定与生成的UTF-8相同。MacOSX和Windows都对文件系统路径中使用的编码使用了特定的(但不同的)规范分解规则。

例如,他们需要决定“é”将被存储为一个或两个代码单元(LATIN SMALL LETTER E WITH ACUTELATIN SMALL LETTER E紧随其后COMBINING ACUTE ACCENT这将导致两个不同的、不同长度的字节序列,MacOSX和Windows都会避免将多个名称相同的文件(用户认为它们的名称)放在同一个目录中。

如何执行规范分解的规则可能会变得非常复杂,因此,与其自己尝试实现它,不如把它留给系统框架为您提供的函数来完成。

扫码关注云+社区

领取腾讯云代金券