NSURL
的文档指出:
NSURL
对象表示一个URL,可以潜在地包含远程服务器上资源的位置、本地磁盘上文件的路径,甚至是任意编码数据的一部分。
我有一块内存中的数据,想把它交给一个需要通过NSURL
加载资源的库。当然,我可以先将这个NSData
写入临时文件,然后从那里创建一个file://
NSURL
,但我更希望将URL直接指向我已经存在于内存中的缓冲区。
上面引用的文档似乎表明这是可能的,但我找不到如何实现的任何提示。我错过了什么吗?
NSURL
支持 data:// URL 方案 (RFC 2397)。
该方案允许您构建如下形式的 URL:
data://data:MIME-Type;base64,<data>
一个可工作的Cocoa示例如下:
NSImage* img = [NSImage imageNamed:@"img"];
NSData* imgData = [img TIFFRepresentation];
NSString* dataFormatString = @"data:image/png;base64,%@";
NSString* dataString = [NSString stringWithFormat:dataFormatString, [imgData base64EncodedStringWithOptions:0]];
NSURL* dataURL = [NSURL URLWithString:dataString];
由于base64编码的性质,使用数据URL传递大型二进制块可能会有些低效。
您还可以实现自定义 NSURLProtocol 处理您的数据。 苹果有一些示例代码,使用自定义协议传递图像对象:https://developer.apple.com/library/mac/samplecode/SpecialPictureProtocol/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003816
[NSString stringWithContentsOfURL:[NSURL URLWithString:@"data:text/plain;base64,aGVsbG8gd29ybGQ="] encoding:NSUTF8StringEncoding error:NULL];
可以给你 @"hello world"
。它并不太低效,只比 ASCII 多了 4 个字节。 - Abhi Beckertdata:
协议对于较小的缓冲区绝对是有效的(如果有人感兴趣,我在这里编写了一个微型协议:https://github.com/bzotto/NSURL-DataAdditions)。自定义 NSURLProtocol
的方式可能是这里最好的答案,因为第一个选项在内存方面会极其浪费(并需要大量编码)用于任何非平凡操作。 - Ben Zotto
[NSData dataWithContentsOfURL:myURLHere]
返回已经存在于RAM中的数据,而不是从文件中读取它? - Abhi BeckertNSData
的文档提到了data://
作为一种支持的 URL 协议,但我找不到关于它如何工作的任何文档。很可能它只是数据的十六进制字符串。 - Abhi Beckert