- 使用
NSInputStream
和NSOutputStream
进行逐块读取和写入
- 内存管理:这种方式不会一次性将整个大文件读入内存,而是按块读取,极大地减少了内存占用。
- 性能优化:通过合理设置缓冲区大小,能够提高读写效率。例如,设置一个适当大小的缓冲区(如4KB或8KB),可以减少系统调用次数。
- 具体类和方法:
NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:bigFilePath];
NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationFilePath append:NO];
[inputStream open];
[outputStream open];
uint8_t buffer[4096]; // 4KB缓冲区
NSInteger bytesRead;
while ((bytesRead = [inputStream read:buffer maxLength:sizeof(buffer)]) > 0) {
[outputStream write:buffer maxLength:bytesRead];
}
[inputStream close];
[outputStream close];
- 使用
NSFileHandle
- 内存管理:
NSFileHandle
同样支持对文件的逐块操作,避免一次性加载大文件到内存。
- 性能优化:它提供了更底层的文件操作接口,在一些场景下性能优于
NSInputStream
和NSOutputStream
。
- 具体类和方法:
NSFileHandle *inputFileHandle = [NSFileHandle fileHandleForReadingAtPath:bigFilePath];
NSFileHandle *outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:destinationFilePath];
NSData *data;
while ((data = [inputFileHandle readDataOfLength:4096])) {
[outputFileHandle writeData:data];
}
[inputFileHandle closeFile];
[outputFileHandle closeFile];
- 使用
NSOperationQueue
进行异步处理
- 内存管理:在后台线程处理文件操作,避免阻塞主线程,并且通过控制并发数,可以进一步优化内存使用。
- 性能优化:利用多核处理器的优势,提高整体处理速度。
- 具体类和方法:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 2; // 设置并发数
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:bigFilePath];
NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:destinationFilePath append:NO];
[inputStream open];
[outputStream open];
uint8_t buffer[4096];
NSInteger bytesRead;
while ((bytesRead = [inputStream read:buffer maxLength:sizeof(buffer)]) > 0) {
[outputStream write:buffer maxLength:bytesRead];
}
[inputStream close];
[outputStream close];
}];
[queue addOperation:operation];
- 使用
dispatch_io
(基于GCD的IO操作)
- 内存管理:
dispatch_io
在底层对内存管理进行了优化,自动处理缓冲区等相关操作,减少了开发者手动管理的负担。
- 性能优化:它利用了GCD的优势,能够高效地利用系统资源,实现高性能的异步IO操作。
- 具体类和方法:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
int fd = open([bigFilePath fileSystemRepresentation], O_RDONLY);
dispatch_io_t input = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue, ^(int error) {
close(fd);
});
fd = open([destinationFilePath fileSystemRepresentation], O_WRONLY | O_CREAT | O_TRUNC, 0644);
dispatch_io_t output = dispatch_io_create(DISPATCH_IO_STREAM, fd, queue, ^(int error) {
close(fd);
});
dispatch_io_set_high_water(input, 4096);
dispatch_io_set_high_water(output, 4096);
dispatch_io_read(input, 0, 4096, queue, ^(bool done, dispatch_data_t data, int error) {
if (!done && data) {
dispatch_io_write(output, 0, data, queue, ^(bool done, int error) {});
}
});