2010-10-04 9 views
8

अद्यतन 4
प्रति ग्रेग के सुझाव का उपयोग करते हुए मुझे लगता है कि, इनकोडिंग बेस 64 के लिए एक 37k छवि से उत्पादन से पता चलता 100k मात्रा का उपयोग कर छवि/पाठ की एक जोड़ी बना लिया है। चूंकि फ़ाइल केवल 37k है, यह कहना सुरक्षित है कि लूप केवल एक बार फिर से चालू होता है, इसलिए कुछ भी जोड़ा नहीं गया था। दूसरी जोड़ी 10k भाग का उपयोग करके उसी 37k छवि से बेस 64 एन्कोडेड तक आउटपुट दिखाती है। चूंकि फ़ाइल 37k है, लूप चार बार पुनरावृत्त है, और डेटा निश्चित रूप से जोड़ा गया था।बेस 64 एन्कोड फ़ाइल NSData चंक्स

दो फ़ाइलों पर एक diff कर पता चलता है कि 10kb हिस्सा फाइल पर एक बड़ा अंतर यह है कि लाइन 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 KB के तहत 100 से अधिक KB तले हो, लेकिन फ़ाइलें हैं ठीक हैं की तरह लग रहा है। यह स्पष्ट है कि मेरे बफर/गणित/आदि पर कुछ बंद है, लेकिन मैं इस पर खो गया हूं। एक दिन इसे कॉल करने के लिए समय हो सकता है, लेकिन मुझे इस हल के साथ सोना अच्छा लगेगा।

यहाँ एक उदाहरण है:

अद्यतन 1
कुछ परीक्षण मैं पाया है कर रही है कि एक ही कोड एक छोटी सी छवि के लिए ठीक काम करेंगे, लेकिन एक बड़ी छवि या के वीडियो के लिए काम नहीं करेगा के बाद कुछ भी आकार। निश्चित रूप से एक बफर मुद्दे की तरह दिखता है, है ना?


अरे, एक समय में लूपिंग करके और इसे एक छोटे से हिस्से में करके एक बड़ी फ़ाइल को एन्कोड करने की कोशिश कर रहा है। सब कुछ काम करने लगता है लेकिन फाइलें हमेशा दूषित हो जाती हैं।

 
    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); 
+0

किस तरह से उत्पादन दूषित है? – Greg

+0

दोनों छवियों (जेपीईजी) और वीडियो (क्विकटाइम) के लिए, फ़ाइलें अपठनीय हैं। – frsh

+0

जो मुझे विश्वास दिलाता है कि मेरे ऑफसेट में कुछ गड़बड़ है। जब मैं एनएसडीटा पर समान बेस 64 श्रेणी का उपयोग करता हूं तो इसे टुकड़ों में विभाजित किए बिना, यह ठीक काम करता है। – frsh

उत्तर

2

मेरी इच्छा है कि मैं ग्रेगइनवायग को क्रेडिट दे सकता हूं, क्योंकि पैडिंग के बारे में उनका मूल बिंदु अंतर्निहित मुद्दा था।

chunkSize = 3600 

एक बार मैं था कि, भ्रष्टाचार दूर चला गया: बेस 64 के साथ, प्रत्येक हिस्सा 3. की ​​एक बहु तो यह समस्या हल हो हो गया है।लेकिन तब मैं स्मृति रिसाव मुद्दों में भाग गया, तो मैं autorelease पूल apprach इस पोस्ट से लिया कहा: http://www.cocoadev.com/index.pl?ReadAFilePieceByPiece

अंतिम कोड:

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

अरे @frsh ... उत्तर पोस्ट करने के लिए धन्यवाद लेकिन कोड अधूरा दिखता है (विशेष रूप से जबकि लूप) ... यदि आप कर सकते हैं तो कृपया पूरा कोड पोस्ट कर सकते हैं ... धन्यवाद ... –

1

कैसे आप एक छवि के लिए बेस 64 डेटा वापस परिवर्तित कर रहे हैं: यदि किसी का कहना है हो सकता है, जहां मैं गलत यहाँ जा रहे हैं मैं उत्सुक था? कुछ कार्यान्वयन अधिकतम लाइन लंबाई को सीमित करते हैं जिन्हें वे स्वीकार करेंगे। प्रत्येक इतने सारे पात्रों को लाइन ब्रेक डालने का प्रयास करें।

+0

बस प्रत्येक पाश के लिए एक नई लाइन जोड़ने की कोशिश की लेकिन इससे कोई फर्क नहीं पड़ता। – frsh

+0

लेकिन आपके लूप में प्रत्येक पुनरावृत्ति 25,000 से अधिक वर्ण लंबा है! प्रति पंक्ति 80 वर्णों की तरह कुछ कोशिश करें। – Aleph7

+0

ठीक है, बस हर 80 अक्षरों को नई लाइन जोड़ने की कोशिश की और एक ही परिणाम मिला। फिर भी सुझाव के लिए धन्यवाद! – frsh

संबंधित मुद्दे