이렇게 할 수는 있지만 설정하는 데 약간 복잡합니다. 어떻게해야합니까 :
경고 : 다음 코드는 브라우저에 입력되어 있으며 내 머리 속에 집계되었습니다. 또한 오류 처리가 많지 않습니다. 주의 사항 구현 자.
//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);
}
OS 디스크 파일에 A``URL에서 "복사 데이터가 없기 때문에 말 그대로"직접 디스크에 "데이터를 다운로드하는 것이 가능하지 않을 것
메모리를 거치지 않고'b' 시스템 콜. 데이터는 라인 어딘가에있는 메모리에 버퍼링됩니다. 이제는 "파일로 다운로드 URL"API를 제공하지만 내부적으로 메모리에 버퍼를 사용하는 라이브러리를 찾을 수 있습니다. –
사실 David 다.하지만 전체 파일 내용을 메모리에 저장할 필요는 없으며 파일에 쓰는 동안 작은 버퍼 만 사용해야한다. 그게 내가 찾고있는거야. – favo