Cocoa 查找文件句柄使用的介质的自然块大小

Cocoa 查找文件句柄使用的介质的自然块大小,cocoa,Cocoa,我想了解cocoa应用程序中使用的IO介质的自然块大小。我在IOMedia.cpp中看到了一个名为“getPreferredBlockSize()”的函数,该函数可能会给出我的块大小。请你们解释一下如何在我的应用程序中使用这个功能,或者是否有其他方法可以让我找到底层IO媒体的自然块大小 谢谢您可以使用Clibc函数,它接受一个文件描述符和一个stat结构,并用数据填充结构。这样的代码可以工作(警告:我自己没有测试): #包括 /* ... */ 结构统计信息; blksize\u t首选块大小;

我想了解cocoa应用程序中使用的IO介质的自然块大小。我在IOMedia.cpp中看到了一个名为“getPreferredBlockSize()”的函数,该函数可能会给出我的块大小。请你们解释一下如何在我的应用程序中使用这个功能,或者是否有其他方法可以让我找到底层IO媒体的自然块大小


谢谢

您可以使用C
libc
函数,它接受一个文件描述符和一个stat结构,并用数据填充结构。这样的代码可以工作(警告:我自己没有测试):

#包括
/* ... */
结构统计信息;
blksize\u t首选块大小;
int fd=[myFileHandle fileDescriptor];
如果((fstat(fd和info))==0){
preferredBlockSize=info.st_blksize;
}否则{
NSLog(@“无法获取文件统计数据”);
}
/*使用preferredBlockSize执行您想要的操作*/
fstat()
手册页:

st_blksize字段给出了高效文件系统I/O的“首选”块大小(以较小的块写入文件可能会导致低效的读-修改-重写)


以下是获取本机块大小的代码:

#include <sys/stat.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <CoreFoundation/CoreFoundation.h>

// look up device number with stat
struct stat stats;
if (stat(path, &stats) != 0) {
    return;
}
// use st_rdev instead of st_dev if
// the path is a device (/dev/disk0)
int bsd_major = major(stats.st_dev);
int bsd_minor = minor(stats.st_dev);

CFTypeRef keys[2] = { CFSTR(kIOBSDMajorKey), CFSTR(kIOBSDMinorKey) };
CFTypeRef values[2];
values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bsd_major);
values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bsd_minor);

CFDictionaryRef matchingDictionary;
matchingDictionary = CFDictionaryCreate(kCFAllocatorDefault,
                                        &keys, &values,
                                        sizeof(keys) / sizeof(*keys),
                                        &kCFTypeDictionaryKeyCallBacks,
                                        &kCFTypeDictionaryValueCallBacks);

CFRelease(values[0]);
CFRelease(values[1]);
// IOServiceGetMatchingService uses up one reference to the dictionary
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                   matchingDictionary);

if (!service) {
    return;
}
CFNumberRef blockSizeProperty;
blockSizeProperty = (CFNumberRef)IORegistryEntryCreateCFProperty(service,
                                        CFSTR(kIOMediaPreferredBlockSizeKey),
                                        kCFAllocatorDefault, 0);
if (!blockSizeProperty) {
    return;
}

int blockSize;
CFNumberGetValue(blockSizeProperty, kCFNumberIntType, &blockSize);
CFRelease(blockSizeProperty);

// blockSize is the native block size of the device
#包括
#包括
#包括
#包括
#包括
//使用stat查找设备编号
结构统计;
如果(状态(路径和状态)!=0){
返回;
}
//如果需要,请使用st_rdev而不是st_dev
//路径是一个设备(/dev/disk0)
int bsd_major=major(stats.st_dev);
int bsd_minor=minor(stats.st_dev);
CFTypeRef键[2]={CFSTR(kIOBSDMajorKey),CFSTR(kIOBSDMinorKey)};
CFTypeRef值[2];
值[0]=CFNumberCreate(kCFAllocatorDefault、kCFNumberIntType和bsd_major);
值[1]=CFNumberCreate(kCFAllocatorDefault、kCFNumberIntType和bsd_minor);
CFDictionaryRef匹配字典;
matchingDictionary=CFDictionaryCreate(kCFAllocatorDefault,
&键和值,
sizeof(键)/sizeof(*键),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(值[0]);
CFRelease(值[1]);
//IOServiceGetMatchingService最多使用一个字典引用
io_service_t service=IOServiceGetMatchingService(kIOMasterPortDefault,
匹配词典);
如果(!服务){
返回;
}
CFNumberRef blockSizeProperty;
blockSizeProperty=(CFNumberRef)IORegistryEntryCreateCFProperty(服务,
CFSTR(kIOMediaPreferredBlockSizeKey),
kCautoOrDefault,0);
如果(!blockSizeProperty){
返回;
}
整块大小;
cfNumberTargetValue(blockSizeProperty、kCFNumberIntType和blockSize);
CFRelease(blockSizeProperty);
//blockSize是设备的本机块大小

谢谢mipadi,我已经搜索了很长时间了。这不是本机块大小。对于我的HD,它大约是13MB,但是本地块大小只有512kb。我想你指的是fstat(fd,&info),其中你计算stat(fd,&info)。
#include <sys/stat.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <CoreFoundation/CoreFoundation.h>

// look up device number with stat
struct stat stats;
if (stat(path, &stats) != 0) {
    return;
}
// use st_rdev instead of st_dev if
// the path is a device (/dev/disk0)
int bsd_major = major(stats.st_dev);
int bsd_minor = minor(stats.st_dev);

CFTypeRef keys[2] = { CFSTR(kIOBSDMajorKey), CFSTR(kIOBSDMinorKey) };
CFTypeRef values[2];
values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bsd_major);
values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &bsd_minor);

CFDictionaryRef matchingDictionary;
matchingDictionary = CFDictionaryCreate(kCFAllocatorDefault,
                                        &keys, &values,
                                        sizeof(keys) / sizeof(*keys),
                                        &kCFTypeDictionaryKeyCallBacks,
                                        &kCFTypeDictionaryValueCallBacks);

CFRelease(values[0]);
CFRelease(values[1]);
// IOServiceGetMatchingService uses up one reference to the dictionary
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                   matchingDictionary);

if (!service) {
    return;
}
CFNumberRef blockSizeProperty;
blockSizeProperty = (CFNumberRef)IORegistryEntryCreateCFProperty(service,
                                        CFSTR(kIOMediaPreferredBlockSizeKey),
                                        kCFAllocatorDefault, 0);
if (!blockSizeProperty) {
    return;
}

int blockSize;
CFNumberGetValue(blockSizeProperty, kCFNumberIntType, &blockSize);
CFRelease(blockSizeProperty);

// blockSize is the native block size of the device