Search code examples
iosswiftnsdata

Which NSDataReadingOptions should be used when reading a local file?


When reading a local file with NSData(contentsOfURL:options:), which one is the appropriate reading option?

Also there is a NSData(contentsOfURL:) without NSDataReadingOptions. Which reading option does it use by default?

For reference the Apple docs.


Solution

  • If you use the method:

    NSData dataWithContentsOfFile:(NSString *)path 
                          options:(NSDataReadingOptions)readOptionsMask 
                            error:(NSError * _Nullable *)errorPtr;
    

    The appropriate options depends on what you plan to do with the data; as stated in Apple Documentation :

    • NSDataReadingUncached : A hint indicating the file should not be stored in the file-system caches. (For data being read once and discarded, this option can improve performance.)
    • NSDataReadingMappedIfSafe : A hint indicating the file should be mapped into virtual memory, if possible and safe.
    • NSDataReadingMappedAlways : Hint to map the file in if possible. (This takes precedence over NSDataReadingMappedIfSafe if both are given.)

    Some explanations about mappedFiles : should only be used if the file is guaranteed to exist for the duration of the data object’s existence. It is generally safer to use the dataWithContentsOfFile: method.

    When using mappedFiles options, the method assumes mapped files are available from the underlying operating system. A mapped file uses virtual memory techniques to avoid copying pages of the file into memory until they are actually needed.

    The other method :

    NSData dataWithContentsOfFile:(NSString *)path;
    

    Is the equivalent of dataWithContentsOfFile:options:error with no options given.

    Conclusion

    If we put this together, you should use :

    • dataWithContentsOfFile: if you don't have particular needs for your data, or memory usage problems. It is the safer choice.
    • dataWithContentsOfFile:options:error with NSDataReadingUncached option if you will use the data only once
    • dataWithContentsOfFile:options:error with NSDataReadingMappedIfSafe option if you don't want to immediately load the entire file, and you are sure the file will exists during the whole lifetime of the NSData object.
    • dataWithContentsOfFile:options:error with NSDataReadingMappedAlways option - same as above, but less safeguards.

    Sources :

    Apple Documentation : NSReadingOptions

    Apple Documentation : dataWithContentsOfFile

    Apple Documentation : dataWithContentsOfFile:options:error