如何确定使用 NSURLConnection 下载的文件的大小(以字节为单位)?
我需要知道使用 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);
}
I need to know the size of the file I am downloading (in bytes) into my app using NSURLConnection (GET). Here is my bytes recieved code below if it helps. What I need to know is how to get the filesize in bytes so that I can use it to show a 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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
[数据长度]确实返回数据的大小(以字节为单位),这应该为您提供您正在寻找的数字。
但是 NSData 提供了 -writeToFile:atomically: 和 -writeToFile:options:error 方法将数据写入磁盘,所以我不知道你为什么要编写自己的文件 I/O。
[data length] does return the size of the data in bytes which should give you the figure you're looking for.
But NSData provides -writeToFile:atomically: and -writeToFile:options:error methods for writing data to disk so I don't know why you're writing your own file I/O.
我相信该代码来自 Apple 的 SimpleURLConnections 示例代码。这里直接引用苹果的 NSURLConnection 方法“connection:didReceiveData:”
不提供增量写入文件的方法,它会一次性写入所有内容,因此我认为这种增量写入 NSOutputStream(此处名为 fileStream)的方法是正确的。在此代码中使用 dataLength 只会返回在一次调用“connection:didReceiveData:”中从 NSURLConnection 发送到委托的数据长度,而不是整个连接的数据总长度。为了实现此目的,我添加了额外的属性:
在连接中 。 :didReceiveResponse:我使用 NSURLResponse 方法预期内容长度来获取整个连接的接收数据文件大小的正确估计
在连接中:didReceiveData:我更改了以下内容:
在连接结束时,这应该是正确的:
这是:来自相同 SimpleURLConnections 代码的打印输出,经过我的修改以显示真正发生的情况:
此外,NSOutputStream 方法“write:maxLength:”返回“实际写入的字节数”,因此出于某种原因,它可能选择不写入所有数据在一次“connection:didReceiveData:”调用中立即执行,因此使用 do/while 循环来检查这一点。但在本例中,它在一次 do/while 迭代中写入所有数据。
另外,您可以使用 NSFileHandle 代替,这将始终写入每个连接发送的整个数据:didReceiveData:调用,而且它是增量的。但请注意 writeData: 是同步的。
I believe the code is from the SimpleURLConnections sample code from Apple. Here is a direct quote from Apple's NSURLConnection method "connection:didReceiveData:"
NSData does not provide methods to write incrementally to a file, it writes it all at once, so I think this method of writing incrementally to an NSOutputStream, here named fileStream, is correct. Using dataLength in this code will only return the length of the data that has been sent from the NSURLConnection to the delegate in a single call to "connection:didReceiveData:", not the overall length of the data for the entire connection. To achieve this I have added extra properties:
In connection:didReceiveResponse: I used the NSURLResponse method expectedContentLength to obtain the correct estimate of the receiving data's file size for the whole connection.
In connection:didReceiveData: I changed the following:
By the end of the connection, this should be true:
Here is the printout from the same SimpleURLConnections code with my modifications to show what is really happening:
Also, the NSOutputStream method "write:maxLength:" returns "the number of bytes actually written", so for some reason it may choose not to write all the data at once within a single call of "connection:didReceiveData:", thus the use of the do/while loop to check for this. But in this example it writes all the data in a single do/while iteration.
Also, you can use an NSFileHandle instead, and this will always write the whole data sent with each connection:didReceiveData: call, also it's incremental. Note however that writeData: is synchronous.