2010-02-05 57 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

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

回答

2

[数据长度]确实返回数据的大小,以字节为单位,它应该给你你想要的数字。

但NSData提供了-writeToFile:atomically:和-writeToFile:options:用于将数据写入磁盘的错误方法,所以我不知道为什么要编写自己的文件I/O。

1

我相信代码来自Apple的SimpleURLConnections示例代码。下面是来自苹果的NSURLConnection的方法直接引用“连接:didReceiveData:”

“的代表应串连每个数据对象的 内容交付 建立完整的数据为 URL负载。”

的NSData不提供方法来逐步写入到一个文件中,一次写入这一切,所以我觉得逐步写入一个NSOutputStream的这种方法,这里命名文件流,是正确的。在此代码中使用dataLength将只将单次调用中从NSURLConnection发送到委托的数据长度返回为“connection:didReceiveData:”,而不是整个连接的数据总长度。要做到这一点我已经添加额外的属性:

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

下面是来自同一个打印输出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方法“write:maxLength:”返回“实际写入的字节数”,因此出于某种原因,它可能会选择不在“connection:didReceiveData:”的单个调用中一次写入所有数据,因此使用do/while循环来检查这一点。但在这个例子中,它将所有的数据写入一个do/while迭代中。

此外,您可以改为使用NSFileHandle,并且这将始终写入每个连接发送的全部数据:didReceiveData:call,也是递增的。但请注意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]); 
} 
相关问题