Update 4
sugestię Per Grega Utworzyłem jedną parę obraz/tekst, który pokazuje wyjścia z 37K obrazu do base64 kodowanych przy użyciu 100k kawałki. Ponieważ plik ma tylko 37 KB, można bezpiecznie powiedzieć, że pętla jest tylko iterowana raz, więc nic nie zostało dodane. Druga para pokazuje dane wyjściowe z tego samego obrazu 37k na kodowane base64, używając 10k porcji. Ponieważ plik ma rozmiar 37k, pętla wykonywana była czterokrotnie, a dane zostały ostatecznie dołączone.Base64 Kodowanie pliku Korzystanie NSData Kawałki
Doing diff na dwóch plików pokazuje, że plik 10kB bryłkach istnieje duża różnica, która zaczyna się na linii 214 i kończy się na linii 640.
- Small Image (37k) - 100k Chunks - Image output
- Small Image (37k) - 100k Chunks - Base64 Text output
- Small Image (37k) - 10k Chunks - Image output
- Small Image (37k) - 10k Chunks - Base64 Text output
Aktualizacja 3
Oto gdzie jest mój kod. Oczyścić trochę ale nadal produkował ten sam efekt:
// 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]]; }
Aktualizacja 2
Tak wygląda plików, które są większe niż 100 KB dostać jajecznicę, ale pliki poniżej 100 KB są w porządku. Jest oczywiste, że coś jest wyłączone na moim buforze/matematyce/etc, ale jestem zagubiony na tym. Być może nadszedł czas, aby nazwać to dzień, ale chciałbym iść spać z tym rozwiązanym.
Oto przykład:
Update 1
Po wykonaniu niektórych badań odkryłem, że ten sam kod będzie działać dobrze dla małego obrazka, ale nie będzie działać dla dużego obrazu lub wideo dowolny rozmiar. Zdecydowanie wygląda na problem z buforem, prawda?
Hej tam, próbując base64 zakodować duży plik, wykonując pętlę i wykonując jedną małą porcję na raz. Wszystko wydaje się działać, ale pliki zawsze są uszkodzone. Byłem ciekawy, czy ktoś może wskazać, gdzie może być nie tak tutaj:
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);
W jaki sposób wyjście uszkodzony? – Greg
Dla obu obrazów (JPEG) i wideo (QuickTime) pliki są nieczytelne. – frsh
Co prowadzi mnie do przekonania, że coś jest nie tak z moim offsetem. Kiedy używam tej samej kategorii base64 na NSData bez dzielenia jej na porcje, to działa dobrze. – frsh