2010-02-05 2 views
3

NSURLConnection (GET)을 사용하여 응용 프로그램에 다운로드 할 파일의 크기 (바이트 단위)를 알아야합니다. 도움이된다면 여기에 내 바이트 수신 코드가 있습니다. 내가 알아야 할 것은 UIProgressView를 보여주기 위해 파일 크기를 바이트 단위로 가져 오는 방법이다.NSURLConnection을 사용하여 다운로드하는 파일의 크기 (바이트)를 결정하는 방법은 무엇입니까?

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data 
// A delegate method called by the NSURLConnection as data arrives. We just 
// write the data to the file. 
{ 
#pragma unused(theConnection) 
    NSInteger  dataLength; 
    const uint8_t * dataBytes; 
    NSInteger  bytesWritten; 
    NSInteger  bytesWrittenSoFar; 

    assert(theConnection == self.connection); 

    dataLength = [data length]; 
    dataBytes = [data bytes]; 

    bytesWrittenSoFar = 0; 
    do { 
     bytesWritten = [self.fileStream write:&dataBytes[bytesWrittenSoFar] maxLength:dataLength - bytesWrittenSoFar]; 
     assert(bytesWritten != 0); 
     if (bytesWritten == -1) { 
      [self _stopReceiveWithStatus:@"File write error"]; 
      break; 
     } else { 
      bytesWrittenSoFar += bytesWritten; 

    } while (bytesWrittenSoFar != dataLength); 
} 
+0

중복 : http://stackoverflow.com/questions/312796/how-to-integrate-nsurlconnection-with-uiprogressview – arul

답변

2

[데이터 길이]는 원하는 크기의 데이터를 바이트 단위로 반환합니다.

그러나 NSData는 -writeToFile : atomically : 및 -writeToFile : options : 디스크에 데이터를 쓰는 오류 메서드를 제공하므로 사용자가 자신의 파일 I/O를 쓰는 이유를 알 수 없습니다.

1

나는 코드가 애플에서 SimpleURLConnections 샘플 코드에서 믿습니다. 여기에 애플의있는 NSURLConnection 방식에서 직접 인용은 "연결 : didReceiveData :"

는 "각 데이터 객체의 내용을 연결해야 대리인이 URL 부하의 전체 데이터를 구축 을 전달했다."

NSData는 파일에 점진적으로 쓰기위한 메서드를 제공하지 않으므로 모든 내용을 한 번에 작성하므로 NSStreamStream에 점진적으로 파일 스트림을 쓰는 방법이 정확하다고 생각합니다. 이 코드에서 dataLength를 사용하면 전체 연결에 대한 데이터의 전체 길이가 아니라 "connection : didReceiveData :"를 한 번 호출하여 NSURLConnection에서 대리인에게 보낸 데이터의 길이 만 반환합니다. 관련하여

@property (nonatomic, assign) long long dataWrittenForWholeConnection; 
@property (nonatomic, assign) long long dataLengthOfWholeConnection; 

: didReceiveResponse :이 내가 추가 속성을 추가 한을 달성하기 위해 나는 모든 연결에 대한 수신 데이터의 파일 크기의 정확한 견적을 얻기 위해 NSURLResponse 방법 expectedContentLength을 사용했다. 관련하여

self.dataWrittenForWholeConnection = 0; 
self.dataLengthOfWholeConnection = [httpResponse expectedContentLength]; 

는 : didReceiveData 방법 :이 해당되어야 연결 단부 바이

// bytes written for current "connection:didReceiveData:" call 
bytesWrittenSoFar += bytesWritten; 
// cumulative data written for connection so far 
self.dataWrittenForWholeConnection += bytesWritten; 

// also update the progress bar 
if (self.dataLengthOfWholeConnection != NSURLResponseUnknownLength) { 
    self.progressView.progress = 
     ((float)self.dataWrittenForWholeConnection/(float)self.dataLengthOfWholeConnection); 
} 

: 여기서

assert(dataWrittenForWholeConnection == dataLengthOfWholeConnection); 

가 동일한로부터 출력 인 I는 다음 변경 내 수정을 SimpleURLConnections 코드는 정말 무슨 일이 일어나고 있는지 보여주는 :

connection:didReceiveResponse: 
Full size of data is 8789 bytes 

connection:didReceiveData: 
Data has 1408 bytes 
Progress bar is at: 0.160200 
1408 bytes of data were written, 1408 bytes so far 

connection:didReceiveData: 
Data has 1408 bytes 
Progress bar is at: 0.320401 
1408 bytes of data were written, 2816 bytes so far 

connection:didReceiveData: 
Data has 1408 bytes 
Progress bar is at: 0.480601 
1408 bytes of data were written, 4224 bytes so far 

connection:didReceiveData: 
Data has 1408 bytes 
Progress bar is at: 0.640801 
1408 bytes of data were written, 5632 bytes so far 

connection:didReceiveData: 
Data has 1408 bytes 
Progress bar is at: 0.801001 
1408 bytes of data were written, 7040 bytes so far 

connection:didReceiveData: 
Data has 1749 bytes 
Progress bar is at: 1.000000 
1749 bytes of data were written, 8789 bytes so far 

connectionDidFinishLoading: 
Connection Finished. 8789/8789 bytes of data were written. 
,

또한, NSOutputStream 방법 "쓰기 : 최대 길이 :"반환 "실제로 기록 된 바이트의 수"어떤 이유가의 단일 통화 내에서 한 번에 모든 데이터를 기록하지 않도록 선택할 수 있도록 "didReceiveData : 연결" 따라서 이것을 확인하기 위해 do/while 루프를 사용한다. 그러나이 예제에서는 모든 데이터를 단일 do/while 반복에 기록합니다.

또한, 당신은 대신 NSFileHandle을 사용할 수 있으며, 이것은 항상 각 연결로 전송되는 모든 데이터를 기록한다 : didReceiveData가 : 전화, 또한 증가합니다. 그러나 writeData :는 동기식입니다.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    // write data to file handler 
    unsigned long long dataLength = [data length]; 

    NSLog(@"Writing %qu bytes at %qu bytes", dataLength, [self.fileHandle offsetInFile]); 
    [self.fileHandle writeData:data]; 
    NSLog(@"Wrote %qu bytes, now at %qu bytes", dataLength, [self.fileHandle offsetInFile]); 
} 
관련 문제