Frage

Update 4
Per Gregs Vorschlag habe ich ein Paar von Bild / Text erstellt, das zeigt die Ausgabe von einem 37k Bild zu Base64 codiert, unter Verwendung von 100k Brocken. Da die Datei nur 37k ist ist es sicher die Schleife nur einmal durchlaufen zu sagen, also nichts angehängt wurde. Das andere Paar zeigt die Ausgabe aus dem gleichen Bild 37k Base64 codiert, unter Verwendung von 10K-Chunks. Da die Datei 37k ist die Schleife viermal wiederholt, und die Daten wurden auf jeden Fall angehängt.

Doing ein diff auf den beiden Dateien zeigt, dass auf der 10kb Chunk-Datei gibt es einen großen Unterschied, dass 640 auf der Leitung 214 und Enden auf der Leitung beginnt.

Update 3
Hier ist, wo mein Code jetzt. Gereinigt ein bisschen, aber immer noch die gleiche Wirkung erzeugt:

// Read data in chunks from the original file
[originalFile seekToEndOfFile];
NSUInteger fileLength = [originalFile offsetInFile];
[originalFile seekToFileOffset:0];
NSUInteger chunkSize = 100 * 1024;
NSUInteger offset = 0;

while(offset < fileLength) {
    NSData *chunk = [originalFile readDataOfLength:chunkSize];
    offset += chunkSize;

    // Convert the chunk to a base64 encoded string and back into NSData
    NSString *base64EncodedChunkString = [chunk base64EncodedString];
    NSData *base64EncodedChunk = [base64EncodedChunkString dataUsingEncoding:NSASCIIStringEncoding];

    // Write the encoded chunk to our output file
    [encodedFile writeData:base64EncodedChunk];

    // Cleanup
    base64EncodedChunkString = nil;
    base64EncodedChunk = nil;

    // Update progress bar
    [self updateProgress:[NSNumber numberWithInt:offset] total:[NSNumber numberWithInt:fileLength]];
}

Update 2
So sieht es aus wie Dateien, die größer als 100 KB erhalten verschlüsselt, aber Dateien unter 100 KB sind in Ordnung. Es ist offensichtlich, dass etwas auf meinem Puffer / math ausgeschaltet ist / etc, aber ich bin auf diesen einen verloren. Könnte Zeit es einen Tag zu nennen, aber ich würde schlafen gehen Liebe mit dieser gelöst werden.

Hier ist ein Beispiel:

Update 1
einige Tests Nachdem ich ich habe festgestellt, dass der gleiche Code in Ordnung für ein kleines Bild arbeiten, aber wird nicht funktionieren für ein großes Bild oder Video von jeder Größe. Auf jeden Fall sieht aus wie ein Puffer Problem, nicht wahr?


Hey, zu base64 versuchen kodieren eine große Datei von Schleifen und ein kleines Stück zu einer Zeit zu tun. Alles scheint zu funktionieren, aber die Dateien immer beschädigt enden. Ich war neugierig, wenn jemand darauf hinweisen könnte, wo ich könnte schief gehen hier:

    NSFileHandle *originalFile, *encodedFile;
    self.localEncodedURL = [NSString stringWithFormat:@"%@-base64.xml", self.localURL];

    // Open the original file for reading
    originalFile = [NSFileHandle fileHandleForReadingAtPath:self.localURL];
    if (originalFile == nil) {
        [self performSelectorOnMainThread:@selector(updateStatus:) withObject:@"Encoding failed." waitUntilDone:NO];
        return;
    }
    encodedFile = [NSFileHandle fileHandleForWritingAtPath:self.localEncodedURL];
    if (encodedFile == nil) {
        [self performSelectorOnMainThread:@selector(updateStatus:) withObject:@"Encoding failed." waitUntilDone:NO];
        return;
    }

    // Read data in chunks from the original file
    [originalFile seekToEndOfFile];
    NSUInteger length = [originalFile offsetInFile];
    [originalFile seekToFileOffset:0];
    NSUInteger chunkSize = 100 * 1024;
    NSUInteger offset = 0;
    do {
        NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;
        NSData *chunk = [originalFile readDataOfLength:thisChunkSize];
        offset += [chunk length];

        NSString *base64EncodedChunkString = [chunk base64EncodedString];
        NSData *base64EncodedChunk = [base64EncodedChunkString dataUsingEncoding:NSASCIIStringEncoding];

        [encodedFile writeData:base64EncodedChunk];

        base64EncodedChunkString = nil;
        base64EncodedChunk = nil;

    } while (offset < length);
War es hilfreich?

Lösung

Ich wünschte, ich Kredit GregInYEG geben konnte, weil sein ursprünglicher Punkt, um padding das zugrunde liegende Problem. Mit Base64, hat jeder Chunk ein Vielfaches von 3 sein, damit dieser das Problem behoben:

chunkSize = 3600

Nachdem ich das hatte, ging die Korruption weg. Aber dann lief ich in Fragen Speicherverlust, so dass ich den Autofreigabepool apprach von diesem Posten genommen hinzugefügt: http://www.cocoadev.com/index.pl?ReadAFilePieceByPiece

Endgültiger Code:

// Read data in chunks from the original file
[originalFile seekToEndOfFile];
NSUInteger fileLength = [originalFile offsetInFile];
[originalFile seekToFileOffset:0];

// For base64, each chunk *MUST* be a multiple of 3
NSUInteger chunkSize = 24000;
NSUInteger offset = 0;
NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init];

while(offset < fileLength) {
    // Read the next chunk from the input file
    [originalFile seekToFileOffset:offset];
    NSData *chunk = [originalFile readDataOfLength:chunkSize];

    // Update our offset
    offset += chunkSize;

    // Base64 encode the input chunk
    NSData *serializedChunk = [NSPropertyListSerialization dataFromPropertyList:chunk format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL];
    NSString *serializedString =  [[NSString alloc] initWithData:serializedChunk encoding:NSASCIIStringEncoding];
    NSRange r = [serializedString rangeOfString:@"<data>"];
    serializedString = [serializedString substringFromIndex:r.location+7];
    r = [serializedString rangeOfString:@"</data>"];
    serializedString = [serializedString substringToIndex:r.location-1];

    // Write the base64 encoded chunk to our output file
    NSData *base64EncodedChunk = [serializedString dataUsingEncoding:NSASCIIStringEncoding];
    [encodedFile truncateFileAtOffset:[encodedFile seekToEndOfFile]];
    [encodedFile writeData:base64EncodedChunk];

    // Cleanup
    base64EncodedChunk = nil;
    serializedChunk = nil;
    serializedString = nil;
    chunk = nil;

    // Update the progress bar
    [self updateProgress:[NSNumber numberWithInt:offset] total:[NSNumber numberWithInt:fileLength]];

    // Drain and recreate the pool
    [chunkPool release];
    chunkPool = [[NSAutoreleasePool alloc] init];
}
[chunkPool release];

Andere Tipps

Wie konvertieren Sie die Base64-Daten in ein Bild zurück? Einige Implementierungen begrenzen die maximale Leitungslänge werden sie akzeptieren. Versuchen Sie das Einfügen einer Zeile alle so viele Zeichen brechen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top