Search code examples
iosmacosfileionsfilemanager

Differences in File Characters between iOS and OSX


I have code I'm trying to make work across both OSX and iOS and running into a problem with file reads. I am trying to do file comparison at a byte level.

However, using the same PNG image file as a test (same problem for other file types) when I read characters at the same physical offsets within the image file I get different characters returned, depending whether I am on an iOS physical device (iPhone) or Mac (Simulator in this category as well).

I wrote some code to read a string of characters at the same offsets within the same file to verify this. Using the code below, I am reading a byte at a time from the same reference file to create a string that I then compare to a known value from a previous run on the other platform.

For the same input offsets within a file, e.g. NSString *definedOffsets = @"49510,37559,13642,49652,19950,21652"; I get different results when I run the code on OSX (or iPhone Simulator) versus the physical iPhone device, even though the input file is the same image file.

Can anybody explain why this is and how I can code round it ?

- (NSString *) readCharacters:(NSString *) dataline fromSource:(NSString *)datasource
{
  NSString *f=nil;

  if ([[NSFileManager defaultManager] fileExistsAtPath:datasource])
  {
    NSError *error=nil;
    //-- Read the image file into an NSData
    NSData *databuff = [NSData dataWithContentsOfFile:datasource options:NSDataReadingUncached error:&error];

    //-- Read the file offsets to compare
    NSArray *d = [dataline componentsSeparatedByString:@","];

    //-- Print Logs of inputs
    NSLog(@"[readCharacters Offsets]: %@",dataline);
#ifdef IPHONE_PLATFORM
    NSLog(@"[readCharacters Offset Count]: %d", d.count);
#else
    NSLog(@"[readCharacters Offset Count]: %ld", (unsigned long)d.count);
#endif

    //-- Get the characters from file
    int8_t oneByte;
    int knum;
    char na[65];
    for (int i=0;i<64;i++)
    {
      knum = [[d objectAtIndex:i] intValue];
      [databuff getBytes:&oneByte range:NSMakeRange(knum, 1)];
      na[i] = oneByte;
    }
    na[64]='\0';
    f = [NSString stringWithUTF8String:na];
  }
  else{
    NSLog(@"Cant Find File");
  }

  //-- Return the String of characters read for later comparison
  NSLog(@"[Characters]: %@",f);
  return f;
}

Solution

  • For iOS apps, the Xcode build process will run pngcrush over the PNG files to optimize them for the device's graphics card. This involves inserting an extra PNG chunk, stripping zlib headers and checksums, byte swapping from RGB to BGR, and pre-multiplying alpha values.

    Try renaming your image to use a ".dat" extension and see if you get different results. You can also disable this at a target or project level with the "Compress PNG Files" build setting:

    enter image description here