我正在使用 NSInputStream 读取一个非常大的文件并将它们以数据包的形式发送到设备。如果接收方没有收到数据包,我可以将数据包编号发送回发送方,该编号表示丢失数据包的起始位置(以字节为单位)。
我知道 NSInputStream 不能倒带和抓取数据包,但是有没有另一种方法来抓取请求的字节范围而不将整个大文件加载到内存中?
如果有一个 [NSData dataWithContentsOfFileAtPath:inRange] 方法,那就完美了。
我正在使用 NSInputStream 读取一个非常大的文件并将它们以数据包的形式发送到设备。如果接收方没有收到数据包,我可以将数据包编号发送回发送方,该编号表示丢失数据包的起始位置(以字节为单位)。
我知道 NSInputStream 不能倒带和抓取数据包,但是有没有另一种方法来抓取请求的字节范围而不将整个大文件加载到内存中?
如果有一个 [NSData dataWithContentsOfFileAtPath:inRange] 方法,那就完美了。
我不认为有一个标准函数可以做到这一点,但你可以自己编写一个,使用类别和 C stdio API:
@interface NSData(DataWithContentsOfFileAtOffsetWithSize)
+ (NSData *) dataWithContentsOfFile:(NSString *)path atOffset:(off_t)offset withSize:(size_t)bytes;
@end
@implementation NSData(DataWithContentsOfFileAtOffsetWithSize)
+ (NSData *) dataWithContentsOfFile:(NSString *)path atOffset:(off_t)offset withSize:(size_t)bytes
{
FILE *file = fopen([path UTF8String], "rb");
if(file == NULL)
return nil;
void *data = malloc(bytes); // check for NULL!
fseeko(file, offset, SEEK_SET);
fread(data, 1, bytes, file); // check return value, in case read was short!
fclose(file);
// NSData takes ownership and will call free(data) when it's released
return [NSData dataWithBytesNoCopy:data length:bytes];
}
@end
然后你可以这样:
// Read 100 bytes of data beginning at offset 500 from "somefile"
NSData *data = [NSData dataWithContentsOfFile:@"somefile" atOffset:500 withSize:100];
您可以使用 NSInputStream 倒带:
[stream setProperty:[NSNumber numberWithInt:offset]
forKey:NSStreamFileCurrentOffsetKey];