2014-10-06 205 views
2

我试图同时使用这个代码从我自己的服务器下载中心同时几个文件:未捕获的异常“NSFileHandleOperationException”

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    // create 
    [[NSFileManager defaultManager] createFileAtPath:strFilePath contents:nil attributes:nil]; 
    _file = [NSFileHandle fileHandleForUpdatingAtPath:strFilePath];// read more about file handle 
    if (_file) { 
     [_file seekToEndOfFile]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)receivedata 
{ 
    //write each data received 
    if(receivedata != nil){ 
     if (_file) { 
      [_file seekToEndOfFile]; 
     } 
     [_file writeData:receivedata]; 
    } 
} 

- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection { 
    //close file after finish getting data; 
    [_file closeFile]; 
} 

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    //do something when downloading failed 
} 
- (IBAction)downloadFromServer:(id)sender { 

     NSLog(@"File now being downloaded"); 
    while (i<=3) { 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    NSURL *strFileURL =[NSURL URLWithString:[NSString stringWithFormat:@"SomePath/pic%d.png", i]]; 

    [request setURL:strFileURL]; 
    NSURLConnection *conection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
    [conection start]; 
    strFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"pic%d.png", i]]; 

    } 

} 

我有3张图片,pic1.png,pic2.png和pic3.png。现在,如果我运行此代码,该应用程序将只保存一个名为pic3.png的损坏文件并自动崩溃。我需要下载所有三个文件,任何指向哪里我错了?

回答

0

的这样做实际上是把在一个zip文件中的所有图片,下载并使用此代码解压它在实际设备上最好的办法:

dispatch_queue_t queue = dispatch_get_global_queue(
                 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 
     NSURL *url = [NSURL URLWithString:@"someDirectory/newPics.zip"]; 
     NSError *error = nil; 
     // 2 
     NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error]; 

     if(!error) 
     { 
      // 3 
      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
      NSString *path = [paths objectAtIndex:0]; 
      NSString *zipPath = [path stringByAppendingPathComponent:@"newPics.zip"]; 

      [data writeToFile:zipPath options:0 error:&error]; 

      if(!error) 
      { 

       ZipArchive *za = [[ZipArchive alloc] init]; 
       // 1 
       if ([za UnzipOpenFile: zipPath]) { 
        // 2 
        BOOL ret = [za UnzipFileTo: path overWrite: YES]; 
        if (NO == ret){} [za UnzipCloseFile]; 

        // 3 
        NSString *imageFilePath = [path stringByAppendingPathComponent:@"newPics/pic1.png"]; 
        //[self removeImage:zipPath]; 


        [[NSFileManager defaultManager] removeItemAtPath:zipPath error: &error]; 

        dispatch_async(dispatch_get_main_queue(), ^{ 

          NSURL *fileURL = [NSURL fileURLWithPath:imageFilePath]; 
          [_webV loadRequest:[NSURLRequest requestWithURL:fileURL]]; 



        }); 

       } 

      } 
      else 
      { 
       NSLog(@"Error saving file %@",error); 
      } 
     } 
     else 
     { 
      NSLog(@"Error downloading zip file: %@", error); 
     } 

    }); 

这是做到这一点的最佳方式,快速和可靠。

0

这很明显,这是行不通的。您启动三个异步操作。每次启动异步操作后,您都会将文件名存储在未知位置,但可能位置相同。那么当第一个异步操作完成时将使用什么文件名?提示:不是你认为会使用的人。

+0

感谢您的回复......这是我第一次处理这种情况......您能帮我解决一个代码片段吗?非常感谢您的时间 – 2014-10-06 09:30:36

+0

这是你的软件,你写的代码。 – gnasher729 2014-10-06 09:31:47

+0

我不是要你给我写我的软件,我只是要求一个片段,可以澄清你的观点,以帮助我,因为它是我第一次在这些情况下 – 2014-10-06 09:33:21

0

不要使用简单的while循环迭代REQUEST操作的次数。事实上,苹果公司自己拥有如此多的内置库。所以这里最好的一个我建议你试试“NSOPERATION QUEUE”。所以,你可以更好的与苹果的开发者网站的注意事项检查,然后你会得到一个明确的想法:[1] https://developer.apple.com/library/IOs/documentation/Cocoa/Reference/NSOperationQueue_class/index.html

对于如何处理使用的NSOperation的不同要求 - 像AddOperation,或RemoveOperation,WaitUntilItFinishTheThread ..