Вопрос

Обновление 4.
На предложение Грега, я создал одну пару изображения / текста, который показывает вывод из изображения 37K к Base64, кодируемую, используя 100K кусочки. Поскольку файл находится всего в 37К, безопасно сказать, что цикл только один раз, поэтому ничего не было добавлено. Другая пара показывает вывод из одного и того же изображения 37K в Base64, кодируемый, используя 10K кусочки. Поскольку файл 37K петля, повторяющийся четыре раза, и данные определенно добавили.

Делая различие в двух файлах показывает, что на файле Chunk 10Kb существует большая разница, которая начинается на линии 214 и заканчивается на линии 640.

Обновление 3.
Вот где мой код сейчас. Убран немного, но все еще создает тот же эффект:

// Читайте данные в кусках от исходного файла [Оригинал SeekteEndoffile]; Nsuinteger FileLence = [ОригиналFile OffsetInfile]; [ОригиналFile SeeptofileOffset: 0]; Nsuinteger Chunksize = 100 * 1024; Nsuinteger Offset = 0; В то время как (смещение <FileLLENGH) {NSDATA * CHUNK = [Оригинальная форматататататататататана: Chunksize]; Смещение + = Chunksize; // преобразовывать кусок в кодированную строку base64 и обратно в nsdata nsstring * base64encodedchunkstringsstring = [Chank Base64EncodedString]; NSDATA * BASE64ENCODEDDCHANKCHANK = [BASE64ENCODDEDCHAUNCHSTRING CASUSINGECHONDING: NSASCIASTINGINGODING]; // Написать кодированный кусок в наш выходной файл [EncodedFile aperitedata: base64encodedchunk]; // Cleanup Base64EncodedchunkString = Nil; base64encodedchunk = nil; // Обновление панели прогресса [самообслуживаниеPROGRESTPRESTALPROGRESE: [NSNUMBER NUMBERWITHINT: OFFSET] Всего: [NSNUMBER NUMBERWITHINT: FIDILLENGH]]; }

Обновление 2.
Таким образом, он выглядит как файлы, которые больше 100 КБ, затыкаются, но файлы до 100 КБ в порядке. Очевидно, что что-то на моем буфере / математике / и т. Д., Но я потерян на этом. Может быть время, чтобы называть это в день, но я бы хотел, чтобы спать с этим решил.

Вот пример:

Обновление 1.
После определения тестирования я обнаружил, что тот же код будет работать нормально для небольшого изображения, но не будет работать для большого изображения или видео любого размера. Определенно выглядит как проблема буфера, верно?


Эй, там, пытаясь Base64 кодировать большой файл, зацикливающую и делаю его один маленький кусок за раз. Кажется, все работает, но файлы всегда в конечном итоге повреждены. Мне было любопытно, если бы кто-нибудь мог указать, где я пойду не так:

 Nsfilehandle * ОригиналFile, * encodedFile; self.localencodedurl = [NSString StringWithFormat: @ "% @ - base64.xml", self.localurl]; // Откройте исходный файл для чтения оригиналаFile = [nsfilehandle filehandleforreadingathath: self.localurl]; Если (оригиналFile == Nil) {[Self ShareSelectorOnmaintHaintHeaint: @selector (Updatestatus :) withound: @ "кодирование не удалось". ждут: нет]; вернуть; } encodedfile = [nsfilehandle filehandleforwriingatpath: self.localencodedurl]; Если (encodedfile == nil) {[Self ShareSelectoronmaintHaintHeaint: @selector (Updatestatus :) с vourject: @ "кодировка не удалась." ждут: нет]; вернуть; } // читайте данные в кусках из исходного файла [Оригинал SeeCteendoffile]; Длина nsuinteger = [оригиналFile OffsetInfile]; [ОригиналFile SeeptofileOffset: 0]; Nsuinteger Chunksize = 100 * 1024; Nsuinteger Offset = 0; do {nsuinteger ischchuntsize = длина - смещение> Chunksize? Chunksize: длина - смещение; NSDATA * Chunk = [ОригиналFile ReadDataOfLength: stathchunksize]; смещение + = [длина кусочки]; NSString * Base64EncodedchunkStringString = [Chank Base64EncodedStringString]; NSDATA * BASE64ENCODEDDCHANKCHANK = [BASE64ENCODDEDCHAUNCHSTRING CASUSINGECHONDING: NSASCIASTINGINGODING]; [encodedfile aperiteata: base64encodedchunk]; Base64EncodedchunkString = Nil; base64encodedchunk = nil; } пока (смещение <длина);
Это было полезно?

Решение

Хотел бы я дать кредит Грегинугу, потому что его первоначальная точка о прокладке была основной проблемой. С Base64 каждый кусок должен быть кратным 3. Так что это решило проблему:

chunkSize = 3600

Однажды у меня было это, коррупция ушла. Но потом я столкнулся с проблемами утечки памяти, поэтому я добавил Autorelease Pool Permach, взятый с этого поста: http://www.cocoadev.com/index.pl?readafilelencimebym

Окончательный код:

// 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];

Другие советы

Как вы преобразуете резервное копирование данных BASE64 на изображение? Некоторые реализации ограничивают максимальную длину линии, которую они примут. Попробуйте вставить линию разбить каждый так много персонажей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top