如何在 iPhone os 上将文件直接下载到磁盘? [英] How to download files directly to disk on the iPhone os?

查看:28
本文介绍了如何在 iPhone os 上将文件直接下载到磁盘?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 iPhone 操作系统上使用 Objective-c 将文件直接从 URL 下载到磁盘.

I would like to download files directly from an URL to the disk using objective-c on the iPhone os.

目前我使用 NSURLConnection 发送一个同步请求,将返回的 NSData 写入文件.

Currently I am using NSURLConnection to send a synchronousRequest, writing the returned NSData into a file.

如何更改下载处理(仍然有请求同步,它已经在后台线程中)将数据直接写入磁盘,而不是使用内存变量来存储完整内容(仅小部分)?

How can I change the download handling (still having the request beeing synchronous, it is already in a background thread) to write the data directly to disk, not using memory variables to store the complete content (only small parts)?

示例代码将不胜感激.

提前感谢大家的回复!

推荐答案

您可以这样做,但设置起来有点复杂.这是我的做法:

You can do this, but it's a bit complicated to set up. Here's how I'd do it:

警告:以下代码是在浏览器中输入并在我脑海中编译的.此外,没有很多错误处理.警告实施者.

//NSURLConnection+DirectDownload.h
@interface NSURLConnection (DirectDownload)

+ (BOOL) downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError **)error;

@end

//NSURLConnection+DirectDownload.m
@implementation NSURLConnection (DirectDownload)

+ (BOOL) downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError **)error {
  NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];
  //configure the request, or leave it as-is

  DirectDownloadDelegate * delegate = [[DirectDownloadDelegate alloc] initWithFilePath:localPath];
  NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate];
  [delegate autorelease];
  [request release];

  while ([delegate isDone] == NO) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
  }

  [connection release];

  NSError * downloadError = [delegate error];
  if (downloadError != nil) {
    if (error != nil) { *error = [[downloadError retain] autorelease]; }
    return NO;
  }

  return YES;
}

//DirectDownloadDelegate.h
@interface DirectDownloadDelegate : NSObject {
  NSError *error;
  NSURLResponse * response;
  BOOL done;
  NSFileHandle * outputHandle;
}
@property (readonly, getter=isDone) BOOL done;
@property (readonly) NSError *error;
@property (readonly) NSURLResponse * response;

@end

//DirectDownloadDelegate.m
@implementation DirectDownloadDelegate
@synthesize error, request, done;

- (id) initWithFilePath:(NSString *)path {
  if (self = [super init]) {
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
      [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    }
    [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
    outputHandle = [[NSFileHandle fileHandleForWritingAtPath:path] retain];
  }
  return self;
}

- (void) dealloc {
  [error release];
  [response release];
  [outputHandle closeFile];
  [outputHandle release];
  [super dealloc];
}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)anError {
  error = [anError retain];
  [self connectionDidFinishLoading:connection];
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)someData {
  [outputHandle writeData:someData];
}

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse {
  response = [aResponse retain];
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
  done = YES;
}

基本思想是你创建一个标准的NSURLConnection,它通常是异步的,但只是通过自己旋转runloop来阻塞线程,直到连接完成.您还可以使用自定义 url 连接委托将连接接收的任何数据直接通过管道传输到文件.

The basic idea is that you create a standard NSURLConnection, which is normally asynchronous, but just block the thread by spinning the runloop yourself until the connection is done. You also use a custom url connection delegate to just pipe any data the connection receives directly to a file.

您现在可以:

NSError * downloadError = nil;
BOOL ok = [NSURLConnection downloadItemAtURL:someURL toFile:someFile error:&downloadError];
if (!ok) {
  NSLog(@"ack there was an error: %@", error);
} else {
  NSLog(@"file downloaded to: %@", someFile);
}

这篇关于如何在 iPhone os 上将文件直接下载到磁盘?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆