Can I read a binary data file into struct?

Discussion in 'iOS Programming' started by mikezang, Sep 2, 2010.

  1. mikezang macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #1
    I have a binary data file in format as below:
    Code:
    struct {
        int32 day; // days since 1900-01-01
        int32 open;
        int32 high;
        int32 low;
        int32 close;
        double64 volume;
    } StockData;
    I know I can read this file by code as below:
    Code:
    StockData stockData; 
    NSArray StockList* = [[NSArray alloc] initWithObjects:stockData];
    NSData *data = [NSData dataWithContentsOfFile:myFile];
    // How to copy data to stockData of stockList
    
    My question is how can I copy data into stockData, so that I can use code as below to access them?
    Code:
    int day = [StockList objectAtIndex:0].day;
    int open = [StockList objectAtIndex:0].open;
    int high = [StockList objectAtIndex:0].high;
    int low = [StockList objectAtIndex:0].low;
    int close = [stockData objectAtIndex:0].close;
    float volume = [StockList objectAtIndex:0].volume;
    
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    I don't see what the difficulty is. NSData will give you a pointer to the bytes. Once you have that it's basic C pointer arithmetic an dereferencing.
     
  3. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #3
    Well, I will try it.
     
  4. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #4
    I used code as below to do this task, but I couldn't get correct result, can you help me?

    Code:
    struct Stock {
        int day;   // data in 4 bytes
        int open; // data in 4 bytes
        int high;  // data in 4 bytes
        int low;   // data in 4 bytes
        int close; // data in 4 bytes
        double volume;// data in 8bytes
    };
    
    -(IBAction) convert:(id)sender {
        NSError *error = nil;
        NSBundle *bundle = [NSBundle mainBundle];
        NSData *data = [NSData dataWithContentsOfFile:[bundle pathForResource:@"9984" ofType:@""] options:0 error:&error];
    	
        if (error) {
            NSLog(@"%@", error);
        }
        else {
            struct Stock *stock = (struct Stock*)[data bytes];
            void *last = stock + [data length];
    			  
            while ((void*)stock < last) {
                NSLog(@"%d, %d, %d, %d, %d, %.3f", stock->day, stock->open, stock->high, stock->low, stock->close, stock->volume);
    			
                stock += sizeof(struct Stock);
            }
        }
    }
    
     

    Attached Files:

  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    It is a simple and well known fact that you don't read/write structs from/to files. In order to implement this simple process you need to understand (1) struct padding and (2) endianness. Read/write the data member by member in order to avoid struct padding problems. Learn about endian issues to get that correct.
     
  6. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #6
    Can you show me detail way? I need to solve my problems, if I study from zero, I don't think I can do anything:)
     
  7. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #7
    Well, I got what I need as below:
    Code:
    struct Stock {
        int day;   // data in 4 bytes
        int open; // data in 4 bytes
        int high;  // data in 4 bytes
        int low;   // data in 4 bytes
        int close; // data in 4 bytes
        double volume;// data in 8bytes
    };
    
    -(IBAction) convert:(id)sender {
        NSError *error = nil;
        NSBundle *bundle = [NSBundle mainBundle];
        NSData *data = [NSData dataWithContentsOfFile:[bundle pathForResource:@"9984" ofType:@""] options:0 error:&error];
    	
        if (error) {
            NSLog(@"%@", error);
        }
        else {
            struct Stock *stock = (struct Stock*)[data bytes];
    			  
            while (stock->day > 0) {
                NSLog(@"%d, %d, %d, %d, %d, %.3f", stock->day, stock->open, stock->high, stock->low, stock->close, stock->volume);
    			
                stock++;
            }
        }
    }
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
  9. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #9
    It really isn't what I intended. I had assumed you'd step down the bytes reading an int or float off at a time and converting as required. But the above is correct: binary dumping structs to/from a file is really not a good idea.
     
  10. mikezang thread starter macrumors 6502a

    Joined:
    May 22, 2010
    Location:
    Tokyo, Japan
    #10
    You are right, I am doing to convert that file to SQLite3, I just use that file which made by other people.
     

Share This Page