stringWithContentsOfFile bei File mit Nullbytes

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • stringWithContentsOfFile bei File mit Nullbytes

    Hallo,

    wenn ich ein File einlesen will, dann sollen die darin enthaltenen Null-Bytes einfach ignoriert werden. Da aber NSString eine Art C-String ist, bricht es bei Null-Bytes ab, dass heißt, was da nach kommt ist verschwunden. Wie bekomme ich denn die Null-Bytes arus.



    Gruß fiveyears
  • Okay, doch ist das dann effizienter Code ?

    Quellcode

    1. NSData* fileBytes = [NSData dataWithContentsOfFile:aFile];
    2. NSMutableData* newFileBytes = [NSMutableData dataWithCapacity:[fileBytes length]];
    3. for ( NSUInteger i = 0 ; i < [fileBytes length]; i++){
    4. Byte aByte = 0 ;
    5. [fileBytes getBytes:&aByte range:NSMakeRange(i,1)];
    6. if (aByte != 0) {
    7. [newFileBytes appendBytes:&aByte length:1];
    8. }
    9. }
    10. NSString* fileContent = [[NSString alloc]initWithData:newFileBytes encoding:NSUTF8StringEncoding];
  • gritsch schrieb:

    macmoonshine schrieb:

    for(const char *p = theBytes; p < theEnd; ++p) {
    if(*p) {
    [newFileBytes appendBytes:p length:1];
    }
    }


    wenns beliebt gehts auch noch effizienter ohne appendBytes ;)

    ... und mit einem Buffer, in etwa so:

    Quellcode

    1. NSMutableData* fileBytes = [NSMutableData dataWithContentsOfFile:aFile];
    2. uint8_t* base = [fileBytes mutableBytes];
    3. NSUInteger length = [fileBytes length];
    4. NSUInteger dstIdx = 0;
    5. for (NSUInteger srcIdx = 0; srcIdx < length; srcIdx++) {
    6. uint8_t val = base[srcIdx];
    7. if (val != 0) base[dstIdx++] = val;
    8. }
    9. [fileBytes setLength:dstIdx];
    10. NSString* fileContent = [[NSString alloc] initWithData:fileBytes encoding:NSUTF8StringEncoding];

    Persönlicher Geschmack: Ich finde die Array-Notation besser lesbar als am Pointer herumzufummeln. Performancetechnisch sollte es das gleiche sein, ist aber auch egal.
    Multigrad - 360°-Produktfotografie für den Mac
  • fiveyears schrieb:

    Hallo,

    wenn ich ein File einlesen will, dann sollen die darin enthaltenen Null-Bytes einfach ignoriert werden. Da aber NSString eine Art C-String ist, bricht es bei Null-Bytes ab, dass heißt, was da nach kommt ist verschwunden. Wie bekomme ich denn die Null-Bytes arus.



    Gruß fiveyears

    Das stimmt so nicht.

    NSString arbeitet nicht mit \0-Terminierung, sondern mit Längenkodierung. Wenn du den String ausgibst, werden dazu natürlich C-Funktionen des Systems benutzt und dabei verschwindet dann der Rest. Im String wird das aber "normal" behandelt und kann daher auch entfernt werden:

    Quellcode

    1. NSString *text = @"Amin\0Negm";
    2. NSLog(@"%@", text);
    3. NSLog(@"%ld", (long)[text length]);
    4. text = [text stringByReplacingOccurrencesOfString:@"\0" withString:@""];
    5. NSLog(@"%@", text);

    2013-04-24 11:38:03.516 Nullchecker[16870:303] Amin
    2013-04-24 11:38:03.519 Nullchecker[16870:303] 9
    2013-04-24 11:38:03.519 Nullchecker[16870:303] AminNegm

    Entscheidend ist also die Frage, wie das eingelesen wird, das heißt, ob und welche C-Funktionen dabei verwendet werden. Ist das das Problem (mit -length prüfen), dann in der Tat einfach mit NSData lesen und in einen String umwandeln. Das sollte gehen, weil es auf Cocoa-Ebene erfolgt. (Sonst einen Bugreport schreiben.)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Bei mir funktioniert das:

    Quellcode

    1. char *cData = "Amin\0Negm";
    2. NSData *data = [NSData dataWithBytes:cData length:9];
    3. // So sollte das in etwa gelesen aussehen
    4. NSString *text = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSASCIIStringEncoding];
    5. NSLog(@"%@", text);
    6. NSLog(@"%ld", (long)[text length]);
    7. text = [text stringByReplacingOccurrencesOfString:@"\0" withString:@""];
    8. NSLog(@"%@", text);
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?