Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将文件直接下载到iPhone操作系统上的磁盘?_Iphone_Objective C_File_Download_Disk - Fatal编程技术网

如何将文件直接下载到iPhone操作系统上的磁盘?

如何将文件直接下载到iPhone操作系统上的磁盘?,iphone,objective-c,file,download,disk,Iphone,Objective C,File,Download,Disk,我想在iPhone操作系统上使用objective-c将文件直接从URL下载到磁盘 目前,我正在使用NSURLConnection发送synchronousRequest,将返回的NSData写入文件 我如何更改下载处理(请求仍然是同步的,它已经在后台线程中),将数据直接写入磁盘,而不使用内存变量存储完整的内容(仅小部分) 一个样本代码将不胜感激 提前感谢大家的回复 您可以这样做,但设置起来有点复杂。我是这样做的: 警告:以下代码是在浏览器中键入并在我脑海中编译的。此外,没有太多的错误处理。警告

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

目前,我正在使用NSURLConnection发送synchronousRequest,将返回的NSData写入文件

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

一个样本代码将不胜感激


提前感谢大家的回复

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

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

//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连接委托将连接接收到的任何数据直接传输到文件

您现在可以执行以下操作:

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);
}

不可能“直接将数据下载到磁盘”,因为操作系统没有“不经过内存就将数据从URL
a
复制到磁盘文件
b
”系统调用。数据将被缓冲在沿着线路的某个内存中。现在,您可能会发现一个提供“下载URL到文件”API的库,但在内部它仍然在内存中使用缓冲区。这是真的,David,但它不需要将整个文件内容存储在内存中,只需要在写入文件时使用小的缓冲区。这就是我要找的。好主意!一个无休止的循环(啊!;)使它同步。这是一个很好的解决方案,非常感谢!如果你真的把它完全写在浏览器上,这也是令人钦佩的:-)好吧,说实话,我上周不得不做类似的事情,而且正在偏离我所记得的…;)如果您注意到任何调用者都乐于在该函数内运行主运行循环(特别是,如果您在事件处理程序内,您将在当前事件处理完成之前处理其他事件。Eww。)@tc同意;我写这篇文章是为了在辅助线程上使用。在主线程上使用此选项不是一个好主意™.