سؤال

تحديث 4
لكل اقتراح Greg ، قمت بإنشاء زوج واحد من الصور/النص الذي يعرض الإخراج من صورة 37K إلى Base64 مشفرة ، باستخدام قطع 100 ألف. نظرًا لأن الملف يبلغ 37 ألفًا فقط ، فمن الآمن أن نقول الحلقة المتكررة مرة واحدة فقط ، لذلك لم يتم إلحاق أي شيء. يعرض الزوج الآخر الإخراج من نفس صورة 37K إلى Base64 المشفر ، باستخدام قطع 10K. نظرًا لأن الملف هو 37 ألفًا ، تم تكرار الحلقة أربع مرات ، وتم إلحاق البيانات بالتأكيد.

يوضح القيام بفرق على الملفين أنه في ملف قطعة 10 كيلو بايت ، يوجد فرق كبير يبدأ في السطر 214 وينتهي على السطر 640.

تحديث 3
هنا هو مكان الكود الخاص بي الآن. تم تنظيفه قليلاً ولكن لا يزال ينتج نفس التأثير:

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

تحديث 2
لذلك يبدو أن الملفات التي تزيد عن 100 كيلو بايت تتعثر ، لكن الملفات التي تقل عن 100 كيلو بايت على ما يرام. من الواضح أن هناك شيئًا ما في المخزن المؤقت/الرياضيات/إلخ ، لكنني ضائع في هذا. قد يكون الوقت قد حان للاتصال به يوميًا ، لكنني أحب أن أنام مع حل هذا.

هذا مثال:

تحديث 1
بعد إجراء بعض الاختبارات ، وجدت أن نفس الرمز سيعمل بشكل جيد لصورة صغيرة ، ولكن لن يعمل مع صورة أو مقطع فيديو كبير من أي حجم. بالتأكيد يبدو وكأنه مشكلة عازلة ، أليس كذلك؟


مرحبًا ، في محاولة لإعداد 64 تشفير ملف كبير عن طريق الحلق والقيام به قطعة صغيرة واحدة في كل مرة. يبدو أن كل شيء يعمل ولكن الملفات تفسد دائمًا. شعرت بالفضول إذا تمكن أي شخص من الإشارة إلى أين قد أخطأ هنا:

    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);
هل كانت مفيدة؟

المحلول

أتمنى أن أعطي الفضل في Greginyeg ، لأن وجهة نظره الأصلية حول الحشو كانت القضية الأساسية. مع BASE64 ، يجب أن يكون كل قطعة مضاعفة من 3. لذلك هذا يحل المشكلة:

chunkSize = 3600

بمجرد أن حصلت على ذلك ، ذهب الفساد بعيدا. ولكن بعد ذلك واجهت مشكلات تسرب الذاكرة ، لذلك أضفت Autorelease Pool Apprach مأخوذ من هذا المنشور: http://www.cocoadev.com/index.pl؟readafilepieceBIPINE

الرمز النهائي:

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