我需要确定我应用的文档目录中的文件是否是zip文件。文件名不能用于进行此确定。所以我需要能够读取MIME类型或找到一些仅适用于拉链的其他属性。
注意:需要将整个文件放入内存的解决方案并不理想,因为文件可能非常大。
答案 0 :(得分:8)
根据http://www.pkware.com/documents/casestudies/APPNOTE.TXT, ZIP文件以“本地文件头签名”
开头0x50, 0x4b, 0x03, 0x04
所以读取前4个字节就足以检查文件是否可能是ZIP文件。 只有在您真正尝试提取文件时才能做出明确的决定。
有许多方法来读取文件的前4个字节。你可以使用NSFileHandle, NSInputStream,打开/读取/关闭,....所以这只应作为一个可能的例子:
NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/file"];
NSData *data = [fh readDataOfLength:4];
if ([data length] == 4) {
const char *bytes = [data bytes];
if (bytes[0] == 'P' && bytes[1] == 'K' && bytes[2] == 3 && bytes[3] == 4) {
// File starts with ZIP magic ...
}
}
Swift 4版本:
if let fh = FileHandle(forReadingAtPath: "/path/to/file") {
let data = fh.readData(ofLength: 4)
if data.starts(with: [0x50, 0x4b, 0x03, 0x04]) {
// File starts with ZIP magic ...
}
fh.closeFile()
}
答案 1 :(得分:0)
试试这个
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSString *description = [ws localizedDescriptionForType:[ws typeOfFile:@"/full/path/to/file" error:nil]];
或者对于mime这个
+ (NSString*) mimeTypeForFileAtPath: (NSString *) path {
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
return nil;
}
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL);
CFStringRef mimeType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
CFRelease(UTI);
if (!mimeType) {
return @"application/octet-stream";
}
return [NSMakeCollectable((NSString *)mimeType) autorelease];
}
答案 2 :(得分:0)
我只使用文件,然后grep,如果它有文本“zip”或“Zip Archive”是安全的。
if file -q $FILENAME | grep "Zip archive"; then
echo "zip";
else
echo "not zip";
fi
答案 3 :(得分:0)
由于.zip和.xlsx都具有相同的魔术数,因此我找不到有效的zip文件(如果已重命名)。
因此,我已经使用Apache Tika查找确切的文档类型。
即使将文件类型重命名为zip,它也会找到确切的类型。