【问题标题】:FileSize Problem - Cocoa文件大小问题 - Cocoa
【发布时间】:2011-04-27 00:38:32
【问题描述】:

我编写了一些方法来帮助我获取文件/文件夹的大小并将结果转换为人类可读的字符串。问题是,当这个大小超过 2.1GB 左右时,返回的数字会变成一个随机的负数,比如“-4324234423 字节”,这是没有用的。

我发现并解决了这个问题:

  • 32GB 仅限于此大小,所以我改为编译为 64 位。
  • 我尝试过同时使用 CGFloat 和 NSUInteger,但它们仍然返回与 NSInteger 相同的值。

我很沮丧,我不知道我错过了什么。这是我的方法:

- (NSString *)stringFromFileSize:(int)theSize
{
 CGFloat floatSize = theSize;
 if (theSize<1023)
  return([NSString stringWithFormat:@"%i bytes",theSize]);
 floatSize = floatSize / 1024;
 if (floatSize<1023)
  return([NSString stringWithFormat:@"%1.1f KB",floatSize]);
 floatSize = floatSize / 1024;
 if (floatSize<1023)
  return([NSString stringWithFormat:@"%1.2f MB",floatSize]);
 floatSize = floatSize / 1024;

 return([NSString stringWithFormat:@"%1.2f GB",floatSize]);
}

- (NSUInteger)sizeOfFile:(NSString *)path
{
 NSDictionary *fattrib = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
 NSUInteger fileSize = (NSUInteger)[fattrib fileSize];
 return fileSize;
}

- (NSUInteger)sizeOfFolder:(NSString*)folderPath
{
 NSArray *contents;
 NSEnumerator *enumerator;
 NSString *path;
 contents = [[NSFileManager defaultManager] subpathsAtPath:folderPath];
 enumerator = [contents objectEnumerator];
 NSUInteger fileSizeInt = 0;
 while (path = [enumerator nextObject]) {
  NSDictionary *fattrib = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:path] error:nil];
  fileSizeInt +=[fattrib fileSize];
 }
 return fileSizeInt;
}

我错过了什么? NSFileManager 是否返回 32 位值?这是什么原因造成的?

谢谢!

【问题讨论】:

    标签: cocoa floating-point 64-bit integer


    【解决方案1】:

    有点晚了,但您可以将这一行与正确的数字格式化程序一起使用:

    NSString *fileSizeStr = [NSByteCountFormatter stringFromByteCount:fileSize countStyle:NSByteCountFormatterCountStyleFile]; 
    

    【讨论】:

      【解决方案2】:

      唉,几乎所有系统的“int”都是 32 位的,即使您“编译为 64 位”也是如此。 (Windows、Mac 和 Linux 以这种方式工作)。见http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

      您可以将long 传递给stringFromFileSize 方法,也可以传递NSUInteger

      【讨论】:

      • 我认为 CGFloat 也是 64 位的?
      • 问题是,当您在“stringFromFileSize”中创建“CGFloat”时,该值已经是“int”(函数的参数),并且该值一定是错误的如果您正在处理大值,因为 int 不能存储大于 2G 的值(如果它们是 32 位签名的)。
      • 问题解决了。不敢相信我错过了,非常感谢! +1 以获得很好的答案!
      • 没问题,我曾经盯着完全相同的问题坐了好几个小时,所以我很高兴能帮上忙!我用于专业工作的第一个操作系统“tru64”,它现在已经停产了,使用 64 位的 int。我什至没有想到像 Linux、Mac、Windows 这样的现代操作系统只会在其 64 位版本上使用 32 位 int .... :(
      猜你喜欢
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 2013-05-07
      相关资源
      最近更新 更多