如何确定NSData对象的MIME类型?我打算让用户从他们的iPhone上传视频/图片,并将该文件包装在NSData类中。
我想知道是否可以从NSData中获取MIME类型。这个问题只有很少的答案,最近的一个是2010年(4年前!)。谢谢!
NSData *data; // can be an image or video
NSString *mimeType = [data getMimetype]; // how would I implement getMimeType
如何确定NSData对象的MIME类型?我打算让用户从他们的iPhone上传视频/图片,并将该文件包装在NSData类中。
我想知道是否可以从NSData中获取MIME类型。这个问题只有很少的答案,最近的一个是2010年(4年前!)。谢谢!
NSData *data; // can be an image or video
NSString *mimeType = [data getMimetype]; // how would I implement getMimeType
+ (NSString *)mimeTypeForData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
break;
case 0x89:
return @"image/png";
break;
case 0x47:
return @"image/gif";
break;
case 0x49:
case 0x4D:
return @"image/tiff";
break;
case 0x25:
return @"application/pdf";
break;
case 0xD0:
return @"application/vnd";
break;
case 0x46:
return @"text/plain";
break;
default:
return @"application/octet-stream";
}
return nil;
}
Swift:
static func mimeType(for data: Data) -> String {
var b: UInt8 = 0
data.copyBytes(to: &b, count: 1)
switch b {
case 0xFF:
return "image/jpeg"
case 0x89:
return "image/png"
case 0x47:
return "image/gif"
case 0x4D, 0x49:
return "image/tiff"
case 0x25:
return "application/pdf"
case 0xD0:
return "application/vnd"
case 0x46:
return "text/plain"
default:
return "application/octet-stream"
}
}
这段代码只处理主要文件类型,但你可以根据需要进行完善:所有文件的签名都在这里提供,只需使用与我相同的模式即可。
附注:所有对应的MIME类型在这里提供。
❤️ Swift
extension Data {
private static let mimeTypeSignatures: [UInt8 : String] = [
0xFF : "image/jpeg",
0x89 : "image/png",
0x47 : "image/gif",
0x49 : "image/tiff",
0x4D : "image/tiff",
0x25 : "application/pdf",
0xD0 : "application/vnd",
0x46 : "text/plain",
]
var mimeType: String {
var c: UInt8 = 0
copyBytes(to: &c, count: 1)
return Data.mimeTypeSignatures[c] ?? "application/octet-stream"
}
}
你说你正在上传这个数据,那么你应该已经知道它的MIME类型了。你创建了数据对象,你知道数据来自哪里,并且存在有限数量的MIME类型。所以使用适用于您的数据的任何一个。对于图像,可能是image/jpeg
或image/png
。对于视频,有许多video/
类型。您可以在Mac上的/etc/apache2/mime.types
中找到长列表的MIME类型字符串。根据您拥有的视频类型选择一个或多个。
确定MIME类型是一个棘手的问题;NSData
可以编码任何类型的二进制数据。唯一确定编码的方法是检查字节。这反过来意味着必须对不同文件类型中存在的字节流有一些了解。在许多(但不是所有)情况下,可以使用查找字典,而针对常见文件类型可能会有开源实现。为了了解涉及的内容,请在Mac上尝试man file
并查看/usr/share/file/magic/
中各种文件类型的识别方式(file
命令不生成MIME类型,但它分析文件内容以尝试识别文件类型,因此原理相同)。
application/octet-stream
表示“某种二进制数据”。如果你需要更具体的类型,最好的方法可能是将其加载到 AVFoundation
类(例如 AVAsset
)中,然后查看元数据以选择 MIME 类型。 - Tom HarringtonNSData
只是一个包装字节数组的数据对象:
...所以我想到的一种方法是检查字节本身,然后从中推断出类型,如果您想发现它的MIME类型。这里有一个例子:从NSData或UIImage中查找图像类型的方法
我还发现了这个:确定从文件加载的NSData的MIME类型;它引用了一些内部数据库(我猜),可用于MIME类型查找。
但正如Tom Harrington在他的回答中所说,这可能会变得棘手,这取决于您正在处理什么。
编辑...
当然,第二种解决方案依赖于文件扩展名,显然您没有,但我相信您已经注意到了这一点。