2009-08-07 5 views
0

私はココアアプリケーションで使用されているIOメディアの自然なブロックサイズを知りたいと思います。私はIOMedia.cppの "getPreferredBlockSize()"という関数を見て、それはおそらく私のブロックサイズを私に与えるでしょう。私のアプリでこの関数を使用する方法や、基礎となるIOメディアの自然なブロックサイズを見つけるために使用する方法が他にもある場合は、皆さんに教えてください。ファイルハンドルで使用されているメディアの自然なブロックサイズを確認してください

おかげ

答えて

1

あなたはファイルディスクリプタとのstat構造体を取り、データとして構造体を埋めC libc機能を、使用することができます。 fstat() manページから

#include <sys/stat.h> 

/* ... */ 

struct stat info; 
blksize_t preferredBlockSize; 
int fd = [myFileHandle fileDescriptor]; 
if ((fstat(fd, &info)) == 0) { 
    preferredBlockSize = info.st_blksize; 
} else { 
    NSLog(@"Could not get file stats"); 
} 

/* Do what you want with preferredBlockSize */ 

:このようなコードは、(:私はこれを自分でテストしていない警告を)うまくいく

st_blocksizeはフィールドには、私は、効率的なファイルシステムのための「好ましい」ブロックサイズを与えます/ O。 (。小さなチャンク内のファイルへの書き込みは非効率的なリード・モディファイ・リライトを引き起こす場合があります)

+0

おかげで長い時間。 – King

+0

これはネイティブブロックサイズではありません。私のHDでは約13MBですが、ネイティブブロックサイズはわずか512kbです。 –

+0

私はあなたが条件付きでstat(fd、&info)を評価するfstat(fd、&info)を意味すると思います。 – Travis

1

ここでネイティブブロックサイズを取得するためのコードです:私はので、これを探していたmipadi

#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