我需要使用NSURLConnection(GET)知道我正在下载的文件大小(以字节为单位)到我的应用程序中。如果有帮助的话,下面是我收到的字节代码。我需要知道的是如何以字节为单位获取文件大小,以便我可以使用它来显示UIProgressView。
- (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 :(得分:2)
[数据长度]会返回以字节为单位的数据大小,它可以为您提供所需的数字。
但NSData提供了-writeToFile:atomically:和-writeToFile:options:将数据写入磁盘的错误方法,所以我不知道你为什么编写自己的文件I / O.
答案 1 :(得分:1)
我相信代码来自Apple的SimpleURLConnections示例代码。以下是Apple的NSURLConnection方法“connection:didReceiveData:”
的直接引用“代表应该连接 交付的每个数据对象的内容 为a建立完整的数据 网址加载。“
NSData没有提供逐步写入文件的方法,它会立即写入所有内容,因此我认为这种以增量方式写入NSOutputStream的方法(此处名为fileStream)是正确的。在此代码中使用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);
以下是来自相同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]);
}