2012-11-02 19 views
9

विवरण: मुझे HTTP पोस्ट पैरामीटर में बेस 64 एन्कोडेड स्ट्रिंग भेजने की आवश्यकता है जो अपलोड करने के लिए फ़ाइल का प्रतिनिधित्व करता है।आईओएस

वर्तमान विधि: मैं एक ASIFormDataRequest उपयोग कर रहा हूँ और इतने की तरह एक बेस 64 स्ट्रिंग में मेरी फाइल एन्कोडिंग:

NSData *data = [[NSFileManager defaultManager] contentsAtPath:@"my path here"]; 
NSString *base64Data = [data encodeBase64ForData]; 

लेकिन जब बड़ी फ़ाइलों को अपलोड करने के अनुप्रयोग स्मृति खत्म हो जाता है और एक भयंकर मौत मर जाता है!

प्रस्तावित समाधान: मैं कैसे के बारे में कहते हैं, जाना होगा, डिस्क से फ़ाइल को पढ़ने, यह HTTP अनुरोध में एक पैरामीटर के लिए मात्रा में बेस 64 तार को बदलने और परिवर्तित base64 स्ट्रिंग संलग्न अब किसी को भी करता है?

प्रभावशाली ढंग से किसी भी तरह से जो पूरी फ़ाइल को स्मृति में पढ़ने से बचाता है।

किसी भी इनपुट की सराहना की जाएगी!

मेरे http पूर्ण में अनुरोध कोड:

NSURL *url = [NSURL URLWithString:requestProgressURLString]; 
NSData *data = [[NSFileManager defaultManager] contentsAtPath:evidence.uri]; 
NSString *base64Data = [data encodeBase64ForData]; 
NSURL *fileURL = [[NSURL alloc] initWithString:evidence.uri]; 

request = [ASIFormDataRequest requestWithURL:url]; 

request.shouldAttemptPersistentConnection = false; 
[request setShowAccurateProgress:YES]; 

[request setPostValue:accessToken forKey:@"AccessToken"]; 
[request setPostValue:[[fileURL path] lastPathComponent] forKey:@"Filename"]; 
[request setPostValue:evidence.name forKey:@"Title"]; 
[request setPostValue:base64Data forKey:@"FileData"]; //wants string value (base64 encoded)   
[request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"]; 
[request setTimeOutSeconds:60]; 
[request setUploadProgressDelegate:self]; 
[request setDownloadProgressDelegate:self]; 
[request setDelegate:self]; 
[request setDidFinishSelector:@selector(requestDone:)]; 
[request setDidFailSelector:@selector(requestWentWrong:)]; 
+0

मैंने कभी भी एक क्रंकिंग बेस 64 कनवर्टर नहीं देखा है, लेकिन इसे ओपन सोर्स कार्यान्वयन लेने और इसे एक चंकने वाले में बदलने में बहुत मुश्किल नहीं होनी चाहिए। बेस 64 * वह * जटिल नहीं है। –

+1

क्या आपके पास वेब सर्वर का नियंत्रण भी है? मतलब क्या आप कोड को भी संशोधित कर सकते हैं? और जब आप बड़ी फाइल कहते हैं? कितना बड़ा? 100 एमबी? 500 एमबी? 1 जीबी? –

+0

फिलहाल अपलोड 100 एमबी तक सीमित हैं, हालांकि भविष्य में यह बढ़ सकता है। आदर्श रूप से समाधान अपलोड के आकार के बावजूद काम करना चाहिए, क्योंकि मुझे यकीन है कि यह कोड कई और परियोजनाओं में उपयोग किया जाएगा। मैं इस समय धाराओं पर एक नज़र डाल रहा हूं ... –

उत्तर

0

इसके बजाय एक हिट में फ़ाइल को पढ़ने के आप मात्रा में इसे पढ़ने के लिए

आप इस एप्पल कुछ है करने के लिए एक इनपुट स्ट्रीम का उपयोग कर सकते हैं here

पर जानकारी मूल रूप से आप एक NSInputStream उदाहरण के रूप में अपनी फ़ाइल की दिशा में रखे बनाने की जरूरत

- (void)setUpStreamForFile:(NSString *)path { 
    // iStream is NSInputStream instance variable 
    iStream = [[NSInputStream alloc] initWithFileAtPath:path]; 
    [iStream setDelegate:self]; 
    [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
     forMode:NSDefaultRunLoopMode]; 
    [iStream open]; 
} 

फिर आप NSStreamDelegate विधि का उपयोग कर मात्रा में डेटा को पढ़ सकता - (शून्य) धारा: (NSStream *) धारा handleEvent: (NSStreamEvent) eventCode

फिर एप्पल इस

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { 

    switch(eventCode) { 
     case NSStreamEventHasBytesAvailable: 
     { 
      if(!_data) { 
       _data = [[NSMutableData data] retain]; 
      } 
      uint8_t buf[1024]; 
      unsigned int len = 0; 
      len = [(NSInputStream *)stream read:buf maxLength:1024]; 
      if(len) { 
       [_data appendBytes:(const void *)buf length:len]; 
       // bytesRead is an instance variable of type NSNumber. 
       [bytesRead setIntValue:[bytesRead intValue]+len]; 

       // DO SOMETHING with DATA HERE 

      } else { 
       NSLog(@"no buffer!"); 
      } 
      break; 
     } 
का एक उदाहरण देता हूँ

आप के रूप में वहाँ जाहिर HTTP हेडर के साथ कुछ भूमि के ऊपर है स्मृति प्रदर्शन नेटवर्क के प्रदर्शन बनाम का एक संतुलन होने की आवश्यकता होगी चुनें मात्रा के आकार

तुम भी आगे अपने NSData dir भेजकर अनुकूलन कर सकते हैं ectly (और इसलिए बेस 64 भूमि के ऊपर बचाने के लिए) इस पोस्ट

File Upload to HTTP server in iphone programming

3

मैं इस समस्या को दो भागों में विभाजित हैं की जाँच करें: बड़ी फाइल Base64 को हिस्सा
2. अपलोड में

1. एनकोड उस फ़ाइल


1. एनकोड बड़े बेस 64 में फाइलों में फ़ाइल:

कुछ कोड खोजें जो बेस 64 पर NSData उदाहरणों को एन्कोड करते हैं।फिर खंडों में डेटा पढ़ने के लिए एक NSInputStream का उपयोग करें, इसे एन्कोड करें और अस्थायी फ़ाइल को लिखने के लिए NSOutputStream का उपयोग करें। मुझे यह प्रश्न/उत्तर मिला: Is it possible to base64-encode a file in chunks? खंड का आकार 3 में से एक बनाओ और इसे काम करना चाहिए। आप इसे पृष्ठभूमि धागे में ले जाना चाहते हैं।

महत्वपूर्ण: यह एक अस्थायी फ़ाइल तैयार करेगा, जो मूल से बड़ा है। उस पल के लिए डिवाइस पर पर्याप्त जगह होनी चाहिए। अपलोड करने के बाद आप इसे हटा सकते हैं।


2. अपलोड कि फाइल

ऐसा लगता है कि आप यह पहले से ही किया है। आप अपने उदाहरण में बिल्कुल ASIFormDataRequest का उपयोग कर सकते हैं। और चूंकि यह फ़ाइल की एक निजी प्रतिलिपि बनाता है (यह मल्टीपार्ट पोस्ट फ़ाइल बनाता है), आप अपनी प्रति हटा सकते हैं।

यदि आप इन चरणों को समानांतर करके अनुकूलित करना चाहते हैं, तो आपको मल्टीपार्ट फ़ाइल अपलोड करने का एक और तरीका ढूंढना होगा।