您好我想运行一个线程并检查当前下载的文件大小。
这就是我使用的
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"]]];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *jpegFilePath = [NSString stringWithFormat:@"%@/test.jpeg",docDir];
NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];//1.0f = 100% quality
[data2 writeToFile:jpegFilePath atomically:YES];
downloadStatus.text =[NSString stringWithFormat:@"size: %zd", malloc_size(data2)];
[image release];
我也尝试将malloc_size(data2)更改为图像,但这又不是真正的结果。我知道这个没有线程,也没有在下载过程中检查但是我应该在这里使用什么来查看文件大小?
答案 0 :(得分:5)
有几点意见:
您的问题假定您尝试检索NSData
的大小失败了。他们不是。获取NSData
大小的正确方法是length
。
但是,您的困惑源于一个错误的假设,即通过UIImage
和UIImageJPEGRepresentation
在往返时采用外部生成的JPEG会产生相同的NSData
。这种情况极不可能发生。有太多不同的JPG设置可能已更改(请参阅JPEG Wikipedia page)。我们当然不知道原始文件使用了什么设置。我知道UIImage
和/或UIImageJPEGRepresentation
更改了文件的颜色空间。我也打赌它还做了很多其他事情。
所以你的结果是正确的。原始文件是2.6mb,结果文件是4.5mb。如果将compressionQuality
从1.0更改为0.99,则生成的文件仅为1.4mb!但如果您想要原始文件,请先保存(如下所示)。
考虑以下代码,下载图像文件,保存,加载到UIImage
,通过UIImageJPEGRepresentation
重新提取,并保存图像的另一个副本:
// let's make filenames where we'll store the files
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *suncomboOrig = [documentsPath stringByAppendingPathExtension:@"suncombo1-orig.jpg"];
NSString *suncomboReprocessed = [documentsPath stringByAppendingPathExtension:@"suncombo1-reprocessed.jpg"];
// let's download the original suncombo1.jpg and save it in Documents and display the size
NSURL *url = [NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSLog(@"original = %d", [data length]);
[data writeToFile:suncomboOrig atomically:NO];
// let's load that into a UIImage
UIImage *image = [UIImage imageWithData:data];
// let's extract data out of the image and write that to Documents, too, also logging the size of that
NSData *data2 = UIImageJPEGRepresentation(image, 1.0);
NSLog(@"reprocessed = %d", [data2 length]);
[data2 writeToFile:suncomboReprocessed atomically:NO];
它的作用是报告:
2012-12-13 22:30:39.576 imageapp[90647:c07] original = 2569128 2012-12-13 22:30:40.141 imageapp[90647:c07] reprocessed = 4382876
所以我保存的第一个文件(我怀疑它与你服务器上的相同)是2.5mb,并且在进行往返UIImage
并通过4.3mb重新提取后的文件。如果我查看上述代码保存的两个文件,我可以确认这些NSData
尺寸是否正确。
我的原始答案是基于这样的假设,即OP无法检索NSData
的大小,或者说这个简单问题背后存在一些微妙的问题(例如想要在下载之前获得大小)开始)。无论如何,我已经扩展了上面的答案,但我会保留原来的答案用于历史目的:
原始答案:
NSData
属性length
告诉您下载了多少字节。例如。 [data2 length]
。
如果它真的很大,您可以使用NSURLConnection
异步下载它,这取决于您的Web服务器,可以在方法didReceiveResponse
开始下载之前提供总文件大小(使用{ NSHTTPURLResponse *response
参数中的{3}}属性。
关于NSURLConnection
下载的另一个好处是你不必在下载时将整个文件加载到内存中,而是可以将它直接传输到持久存储,这是特别有用的如果您同时下载多个大文件。如果你正在下载一个合理大小的文件,使用NSURLConnection
下载是过度的,但是在下载大文件并且你想要一个进度指示器(或者想要在下载开始之前获得文件大小)时它会很好。
但是,如果您只想知道已向NSData
下载了多少字节,请使用length
。
答案 1 :(得分:4)
您可以使用C FILE
类来获取文件大小。
FILE * handle = fopen([jpegFilePath UTF8String], "r");
fseek(handle, EOF); // seek to end of file
int size = ftell(handle); // returns position in bytes
fclose();
答案 2 :(得分:3)
因为你说“当前”大小并提到一个帖子,我猜你正试图确定收到的文件大小。在这种情况下,您可以从NSURLConnection
免费获取该帖子,并且您可以从收到的委托方法中获取数据大小......
为下载的数据创建实例变量:
@property (nonatomic, strong) NSMutableData *data;
创建并启动连接:
NSURL *url = [NSURL URLWithString:@"http://lasp.colorado.edu/home/wp-content/uploads/2011/03/suncombo1.jpg"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
self.data = [NSMutableData data];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
在NSURLConnectionDataDelegate中实施所需的方法。对于您的问题,特殊部分是:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.data appendData:data];
NSUInteger bytesSoFar = [self.data length];
// you're on the app main thread here, so you can do something
// to the UI to indicate progress
downloadStatus.text = [NSString stringWithFormat@"size: %d", bytesSoFar];
}
关于rest of the protocol is here的好文档。连接完成后,您可以像使用dataWithContentsOfURL
...
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
UIImage *image = [[UIImage alloc] initWithData:self.data];
downloadStatus.text = [NSString stringWithFormat@"size: %d", [self.data length]];
}