Yingtao Hua
Yingtao Hua

Reputation: 3

ios load large file use memory mapping failed

use below methods to mapping a large file failed.

NSData *mappedData = [NSData dataWithContentsOfFile:self.videoPath options:NSDataReadingMappedAlways error:&error];

or map:

int fd = open([path fileSystemRepresentation], O_RDONLY);
struct stat statbuf;
if (fstat(fd, &statbuf) == -1) {
    close(fd);
    return nil;
}

void *mappedFile;
mappedFile = mmap(0, statbuf.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
close(fd);
if (mappedFile == MAP_FAILED) {
    NSLog(@"Map failed, errno=%d, %s", errno, strerror(errno));
    return nil;
}

// Create the NSData
NSData *mappedData = [NSData dataWithBytesNoCopy:mappedFile length:statbuf.st_size freeWhenDone:NO];`

memory mapping failed , mappedData load whole file to RAM.

why failed? any other suggestion?

Upvotes: 0

Views: 2409

Answers (1)

Gihan
Gihan

Reputation: 2536

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSString *applicationDirectory = [NSString stringWithFormat:@"%@", [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]];

    NSString *filePath = [NSString stringWithFormat:@"%@%@", applicationDirectory, fileNameWithExtension];

   // NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSData *fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedAlways error:&error];

You can get a file to memory only using NsData. But You can use NSfileHandler if you need to cache read the file while not loading the whole thing to memory at once. Since it seems a file is a video file i prefer you buffer it using NSfilehandler.

Edited: + dataWithContentsOfFile:options:error: can be used in order to save memory you can use NSDataReadingMappedAlways is files to be mapped always or NSDataReadingMappedIfSafe to be safe. Refer to https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html

Upvotes: 1

Related Questions