2017-02-22 7 views
0

私は大きな一次元uint8_t配列を持っています。最初にNSDataに変換せずにバイナリファイルに効率的に送信する方法はわかりません。配列をファイルに変換するより効率的な方法がありますか?objective-cでは、uint8_t配列をバイナリファイルに書き込む効率的な方法はありますか?

おかげで、 デール

EDIT:(のviewDidLoadで)答えのためのテストコードは、これはまた、ARRAYをuint8_tに直接ファイルから読み取ります。

filemgr= [NSFileManager defaultManager]; 
    dirPaths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    dataDir= dirPaths[0]; 
    NSLog(@"Data dir is %@",dataDir); 
    dataPath = [NSString stringWithFormat:@"%@/junk.bin",dataDir]; 
    report_memory(); 
    [self read_file]; 
    report_memory(); 
    [filemgr removeItemAtPath: dataPath error: Nil]; //TODO remove after test 
    if (![filemgr fileExistsAtPath:dataPath]){ 
    memset(ONOFFrecords,0xFF,8388608); //set all bytes of ONOFFrecords to 0xFF 
    [[NSData data] writeToFile:dataPath atomically:YES]; //make empty file 
    report_memory(); 
    double strt= CACurrentMediaTime(); 
    NSData* ONOFFdata = [NSData dataWithBytesNoCopy:&ONOFFrecords[0] length:sizeof(ONOFFrecords) freeWhenDone:NO]; 
    NSFileHandle *handle= [NSFileHandle fileHandleForWritingAtPath:dataPath]; 
    [handle seekToFileOffset:0]; 
    [handle writeData:ONOFFdata]; 
    [handle closeFile]; 
    NSLog(@"8 MB file of uint8_t's created and saved in %f secs to all 0xFF's", CACurrentMediaTime()-strt); 
    report_memory(); 
    } else { 
    report_memory(); 
    //lets read that file and put it in uint8_t ONOFFrecords 
    [self read_file]; 
    report_memory(); 
    } 
    //TODO remove below after test 
    //lets read that file and put it in uint8_t ONOFFrecords 
    report_memory(); 
    [self read_file]; 
    report_memory(); 
    //lets change some of that data 
    ONOFFrecords[0] = 0x03; 
    //and save write all data to the same file 
    report_memory(); 
    double strt= CACurrentMediaTime(); 
    NSData *ONOFFdata = [NSData dataWithBytesNoCopy:&ONOFFrecords[0] length:sizeof(ONOFFrecords) freeWhenDone:NO]; 
    NSFileHandle *handle= [NSFileHandle fileHandleForWritingAtPath:dataPath]; 
    [handle seekToFileOffset:0]; 
    [handle writeData:ONOFFdata]; 
    [handle closeFile]; 
    NSLog(@"Updated 8 MB file of uint8_t's WRITE in %f secs with first uint8_t = %u", CACurrentMediaTime()-strt,ONOFFrecords[0]); 
    report_memory(); 
    //lets read that file and put it in uint8_t ONOFFrecords 
    report_memory(); 
    [self read_file]; 
    report_memory(); 

とREAD_FILE機能:

- (void) read_file 
{ 
    NSInteger result; 
    uint8_t buffer[4096]; 
    uint32_t pos = 0; 
    uint8_t haderr = 0; 
    double strt= CACurrentMediaTime(); 
    NSInputStream *iStream = [[NSInputStream alloc] initWithFileAtPath:dataPath]; 
    [iStream open]; 
    while ((result = [iStream read:buffer maxLength:4096]) != 0){ 
    if (result>0){ 
     memcpy(ONOFFrecords+pos, buffer, result); 
     pos+=result; 
    }else{ 
     haderr=1; 
     NSLog(@"Error %@",[iStream streamError]); 
     break; 
    } 
    } 
    [iStream close]; 
    if (haderr==0){ 
    NSLog(@"8 MB file of uint8_t's READ in %f secs with first uint8_t = %u last pos %u", CACurrentMediaTime()-strt,ONOFFrecords[0],pos); 
    } 
} 

また、report_memory()関数(#importも必要):

#import <mach/mach.h> 

// ...

void report_memory(void) 
{ 
    struct mach_task_basic_info info; 
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT; 
    kern_return_t kerr = task_info(mach_task_self(), 
              MACH_TASK_BASIC_INFO, 
              (task_info_t)&info, 
              &size); 
    if(kerr == KERN_SUCCESS) { 
    NSLog(@"Memory in use (in bytes): %llu", info.resident_size); 
    } else { 
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); 
    } 
} 

AND出力:

2017-02-23 12:17:41.530929 HaloLog[2107:1026526] Data dir is /var/mobile/Containers/Data/Application/C448DBF6-5FF8-4272-BA57-6595D07AB6E5/Documents 
2017-02-23 12:17:41.531127 HaloLog[2107:1026526] Memory in use (in bytes): 29302784 
2017-02-23 12:17:41.532333 HaloLog[2107:1026526] Error Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory" UserInfo={_kCFStreamErrorCodeKey=2, _kCFStreamErrorDomainKey=1} 
2017-02-23 12:17:41.532425 HaloLog[2107:1026526] Memory in use (in bytes): 29306880 
2017-02-23 12:17:41.583930 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.604554 HaloLog[2107:1026526] 8 MB file of uint8_t's created and saved in 0.020386 secs to all 0xFF's 
2017-02-23 12:17:41.604748 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.604899 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.635276 HaloLog[2107:1026526] 8 MB file of uint8_t's READ in 0.030260 secs with first uint8_t = 255 last pos 8388608 
2017-02-23 12:17:41.635422 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.635460 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.652201 HaloLog[2107:1026526] Updated 8 MB file of uint8_t's WRITE in 0.016660 secs with first uint8_t = 3 
2017-02-23 12:17:41.652303 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.652342 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
2017-02-23 12:17:41.678894 HaloLog[2107:1026526] 8 MB file of uint8_t's READ in 0.026464 secs with first uint8_t = 3 last pos 8388608 
2017-02-23 12:17:41.679007 HaloLog[2107:1026526] Memory in use (in bytes): 29392896 
(lldb) 
+0

なぜあなたはそれを処理するためにCを使いませんか? –

+0

まだ私は初心者であり、変換を行うことは私が把握できるすべてであったためです。しかし、それは8 MBの長さであるため、私はそれを行うことが実際には効率的ではないようです。 – KiloOne

+0

uintを整数(文字通り数字の入ったテキストファイル)として書くことを意味しますか? – Prientus

答えて

1

あなたがたNSDataのdataWithBytesNoCopy:length:freeWhenDone:を使用することができます。あなたのデータを参照するが、それをコピーすることなく、NSDataオブジェクトが返されます。 freeWhenDoneNOを必ず渡してください。そうしないと、NSDataオブジェクトは、割り当てが解除されたときに渡したバイトを解放しようとします。これはおそらく望みません。

uint8_t myArray[] = { 
    0x01, 0x02, 0x03, 0x04, 0x05 
}; 

NSData* theData = [NSData dataWithBytesNoCopy:&myArray[0] 
             length:sizeof(myArray) 
           freeWhenDone:NO]; 

そして恐らくNSFileManager又はNSFileHandleNSDataを書き込むためにどのような方法を使用。

+0

ありがとう、それは私が求めたものです。元の投稿に追加したテストコードについてコメントしていただけますか?私はそれを正しく使用していますか?配列データを変更してテストコードのように定期的に保存するとメモリに問題はありますか? – KiloOne

+0

また、これを 'reverse'で行う方法はありますか?つまり、ファイルからデータを読み込んで、それを私のuint8_t配列に直接置きますか? – KiloOne

関連する問題