繁体   English   中英

在Mac OS X中将CFSTR写入终端

[英]Writing a CFSTR to the terminal in Mac OS X

我将如何最好地输出以下代码

#include <CoreFoundation/CoreFoundation.h> // Needed for CFSTR
int main(int argc, char *argv[])
{
    char *c_string = "Hello I am a C String. :-).";
    CFStringRef cf_string = CFStringCreateWithCString(0, c_string, kCFStringEncodingUTF8);

    // output cf_string
    //

}

没有API可以将CFString直接写入任何文件(包括stdout或stderr),因为您只能将字节写入文件。 字符是(某种程度上)更理想的概念。 它们太高级了,无法写入文件。 就像说“我要写这些像素”一样; 您必须首先决定以哪种格式写入它们(例如PNG),然后以该格式对其进行编码,然后写入该数据。

字符也是如此。 您必须以某种格式将它们编码为字节,然后写入这些字节。

将字符编码为字节/数据

首先,您必须选择一种编码。 为了在终端上显示,您可能需要UTF-8,即kCFStringEncodingUTF8 为了写入文件……您通常需要UTF-8。 实际上,除非您特别需要其他东西,否则几乎总是需要UTF-8。

接下来,您必须将字符编码为字节。 创建C字符串是一种方法。 另一个是创建一个CFData对象; 还有一个方法是直接提取字节(不以null结尾)。

您说过要坚持使用CF,所以我们将跳过C字符串选项(无论如何,它效率不高,因为无论调用write还是必须调用strlen ),它更容易但更慢,尤其是在将其用于大串和/或频繁。 相反,我们将创建CFData。

幸运的是,CFString提供了一个API,可以根据CFString的内容创建CFData对象。 不幸的是,这仅适用于创建外部表示 您可能不想将其写入stdout。 仅适合作为常规文件的全部内容写出。

因此,我们需要降低一个级别并自己获取字节 该函数需要一个缓冲区(内存区域)以及该缓冲区的大小(以字节为单位)。

不要CFStringGetLength用作缓冲区的大小。 这是对字符而不是字节进行计数,并且字符数与字节数之间的关系并不总是线性的。 (例如,某些字符可以用UTF-8编码为单个字节…,但不是全部。不是几乎全部。对于其他字符,所需的字节数有所不同。)

正确的方法是两次调用CFStringGetBytes :一次没有缓冲区( NULL ),然后它将简单地告诉您它将给您多少字节(而无需尝试写入未分配给它的缓冲区); 然后,创建该大小的缓冲区,然后使用该缓冲区再次调用它。

可以使用malloc创建一个缓冲区,但是您想坚持使用CF东西,所以我们将采用这种方式: 创建一个CFMutableData对象,其容量为您从第一个CFStringGetBytes调用中获取的字节数, 将其长度增加为相同数量的字节,然后获取数据的可变字节指针 该指针是您需要写入缓冲区的指针。 它是您传递给第二次调用CFStringGetBytes的指针。

回顾到目前为止的步骤:

  • 调用CFStringGetBytes带缓冲区的CFStringGetBytes以找出缓冲区需要多大。
  • 创建具有该容量的CFMutableData对象,并将其长度增加到该大小。
  • 获取CFMutableData对象的可变字节指针,即您的缓冲区,并再次使用缓冲区再次调用CFStringGetBytes ,以将字符编码为数据对象中的字节。

写出来

要将字节/数据写入纯CF中的文件,必须使用CFWriteStream

可悲的是,没有像[NSFileHandle fileHandleWithStandardOutput]这样的漂亮的Cocoa API可以使用[NSFileHandle fileHandleWithStandardOutput] 创建到stdout的写流的唯一方法是使用包装在URL中的stdout路径来创建它。

您可以很容易地从路径创建URL。 标准输出设备的路径是/dev/stdout ,因此创建URL的过程如下所示:

CFURLRef stdoutURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/dev/stdout"), kCFURLPOSIXPathStyle, /*isDirectory*/ false);

(当然,就像您创建的所有内容一样,您需要释放它。)

有了URL,您就可以为这样引用的文件创建写流 然后,您必须打开流 ,然后可以向其中写入数据 (您将需要获取数据的字节指针 及其长度 ),最后关闭流

请注意,如果您写的内容不是以换行符结尾,则可能缺少/未显示文本。 NSLog代表您写入stderr时,会为您添加换行符。 当您自己写信给stderr时,您必须这样做(否则后果自负)。

所以:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM