My case is rather strange: I practically used the example "SimpleFTPSample" (some small variations like [self.networkStream setProperty: (id) kCFBooleanFalse forKey: (NSString *) kCFStreamPropertyFTPAttemptPersistentConnection], so as not to support the connection in the WiFi / 3G network) to perform transfer operations FTP files, but despite the absence of any errors, your downloaded file is corrupted if you use the ftp site. To solve this problem, just add sleep (3)! This function (sleep) must be executed before [self.networkStream close]; Warning: if I change the ftp site, I have no problem without "sleep (3)"!
I didnβt understand anything ... Thanks for any help
I am attaching my sample code.
- (void)_startSend { BOOL success; NSURL * url; CFWriteStreamRef ftpStream; assert(self.networkStream == nil); // don't tap receive twice in a row! assert(self.fileStream == nil); // ditto assert(self.filePath == nil); // self.filePath rappresenta il percorso del file da inviare self.attendere.hidden = FALSE; // First get and check the URL. defaults = [NSUserDefaults standardUserDefaults]; NSString * Cartella_ZIP = [[defaults objectForKey:kIndirizzoIpUploadKey] stringByAppendingString:self.Nome_File_da_Inviare]; url = [[iSalesAgentAppDelegate sharedAppDelegate] smartURLForString:Cartella_ZIP]; success = (url != nil); // If the URL is bogus, let the user know. Otherwise kick off the connection. if ( ! success) { self.statuslabel.text = @"Indirizzo FTP non valido!"; } else { NSLog(@"nome file %@",self.Nome_File_da_Inviare); self.filePath = [self.Cartella_Lavoro stringByAppendingPathComponent:self.Nome_File_da_Inviare]; assert(self.filePath != nil); self.fileStream = [NSInputStream inputStreamWithFileAtPath:self.filePath]; assert(self.fileStream != nil); [self.fileStream open]; // Open a CFFTPStream for the URL. ftpStream = CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url); assert(ftpStream != NULL); self.networkStream = (__bridge NSOutputStream *) ftpStream; success = [self.networkStream setProperty:[defaults objectForKey:kUsernameFtpKey] forKey:(id)kCFStreamPropertyFTPUserName]; assert(success); success = [self.networkStream setProperty:[defaults objectForKey:kPasswordFtpKey] forKey:(id)kCFStreamPropertyFTPPassword]; assert(success); [self.networkStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyFTPAttemptPersistentConnection]; self.networkStream.delegate = self; [self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.networkStream open]; CFRelease(ftpStream); [self _sendDidStart]; } } - (void)_stopSendWithStatus:(NSString *)statusString { if (self.networkStream != nil) { [self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; self.networkStream.delegate = nil; [self.networkStream close]; self.networkStream = nil; } if (self.fileStream != nil) { [self.fileStream close]; self.fileStream = nil; } [self _sendDidStopWithStatus:statusString]; } - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { assert(aStream == self.networkStream); NSString * stringa_byte_letti =nil; NSString * stringa_filesize =nil; NSNumber * number = nil; self.filesize = [[[NSFileManager defaultManager] attributesOfItemAtPath:self.filePath error:nil] fileSize]; NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle]; [numberFormatter setGroupingSeparator:@"."]; switch (eventCode) { case NSStreamEventOpenCompleted: { // Added: Finally get filesize [self _updateStatus:@"Aperta Connessione"]; filesize = 0; byte_scritti = 0; } break; case NSStreamEventHasBytesAvailable: { [self _stopSendWithStatus:@"Network write error"]; assert(NO); // should never happen for the output stream } break; case NSStreamEventHasSpaceAvailable: { [self _updateStatus:@"Invio Ordine..."]; if (self.bufferOffset == self.bufferLimit) { NSInteger bytesRead; bytesRead = [self.fileStream read:self.buffer maxLength:kSendBufferSize]; if (bytesRead == -1) { [self _stopSendWithStatus:@"File read error"]; } else if (bytesRead == 0) { sleep(3); [self _stopSendWithStatus:nil]; } else { self.bufferOffset = 0; self.bufferLimit = bytesRead; } } // If we're not out of data completely, send the next chunk. if (self.bufferOffset != self.bufferLimit) { NSInteger bytesWritten; bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset]; assert(bytesWritten != 0); byte_scritti += bytesWritten; if (bytesWritten == -1) { [self _stopSendWithStatus:@"Network write error"]; } else { self.bufferOffset += bytesWritten; } } number = [NSNumber numberWithDouble:byte_scritti]; stringa_byte_letti = [numberFormatter stringForObjectValue:number]; number = [NSNumber numberWithInteger:self.filesize]; stringa_filesize = [numberFormatter stringForObjectValue:number]; [self _updateStatus:[NSString stringWithFormat:@"Invio File nr. %i di %i: Totale byte %@ - byte scritti : %@", [self.numero_file_da_inviare intValue]+1 ,[Array_FileZip count],stringa_filesize,stringa_byte_letti ]]; // Pull some data off the network. NSNumber * percentuale_progress = [NSNumber numberWithFloat: (float)byte_scritti / (float)self.filesize]; [self performSelectorOnMainThread:@selector(Aggiorna_ProgressBar:) withObject:percentuale_progress waitUntilDone:YES]; } break; case NSStreamEventErrorOccurred: { [self _stopSendWithStatus:@"File Dati non trovato!"]; } break; case NSStreamEventEndEncountered: { // evento ignorato } break; default: { [self _stopSendWithStatus:@"Network write error"]; assert(NO); } break; } }
objective-c ftp nsstream
micheledamato
source share