objective-c – NSStream不发送所有数据
发布时间:2020-12-16 07:32:45 所属栏目:百科 来源:网络整理
导读:我的情况很奇怪: 我几乎使用了示例“SimpleFTPSample”(类型的一些小变体[self.networkStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyFTPAttemptPersistentConnection];以避免保持连接活动WiFi / 3G)执行传输操作FTP文件
我的情况很奇怪:
我几乎使用了示例“SimpleFTPSample”(类型的一些小变体[self.networkStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyFTPAttemptPersistentConnection];以避免保持连接活动WiFi / 3G)执行传输操作FTP文件但是,尽管没有任何类型的错误,如果您使用ftp站点,则下载的文件已损坏:要解决此问题,只需添加一个睡眠(3)!必须在[self.networkStream close]之前执行此功能(睡眠); 警告:如果我改变了ftp站点,没有“sleep(3)”就没问题! 我什么都不懂……感谢任何类型的援助 我附上了我的示例代码. - (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; } } 解决方法
同样的问题在这里据我所知,问题是当你没有持久连接时,当你调用“关闭”时,与FTP服务器的连接立即关闭(在有效传输最后一块数据之前).问题是关闭不会执行数据的“刷新”.我也遇到了这个问题.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |