0

fcntl(fd, F_GLOBAL_NOCACHE, 1);从磁盘读取文件而不是从缓存读取文件。读取文件后,我只能获取字符串数据。现在我想在读取文件后,将文件的字节数据获取到 NSMutableData。我怎样才能做到这一点?提前致谢。

   if (fd)

{
    fcntl(fd, F_GLOBAL_NOCACHE, 1);
    NSMutableData* myData = [[NSMutableData alloc] init];

    while(YES)
    {

        // store the length before addition
        NSUInteger previousLength = [myData length];

        // increase the length so we can write more bytes
        [myData increaseLengthBy:300];

        // read bytes from stream directly at the end of our data
        size_t len = fread([myData mutableBytes] + previousLength, 300, 1, fd);

        // set data length
        [myData setLength:previousLength + len];

        // if end-of-file exit the loop
        if (len == 0) {
            break;
        }
         [myData appendBytes:buffer length:len];
    }
    // use your 'myData'
    NSLog(@"dataFile: %@",myData);
    [myData release];

请给我建议?谢谢

UPDATE2: 现在我有另一个问题:我想直接从磁盘而不是从缓存中读取文件。我使用了下面的代码,但它似乎不起作用,它仍然从 Cache 读取:

     NSString *url= [NSString stringWithFormat:@"%@/demo.abc"];

        const char *c_sd_url = [url UTF8String];
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        FILE * fd = fopen(c_sd_url, "rb");

        if (fd)
        {

            fcntl(fd, F_GLOBAL_NOCACHE, 1);

            fseek(fd, 0, SEEK_END);
            long sz = ftell(fd);
            fseek(fd, 0, SEEK_SET);

            char *buf = malloc(sz);
            NSLog(@"before %s",buf);
            assert(buf != NULL);

            assert(fread(buf, sz, 1, fd) == 1);
            NSLog(@"after %s",buf);
            NSMutableData *data= [NSMutableData dataWithBytesNoCopy:buf length:sz freeWhenDone:YES];
            NSLog(@"%@",data);
}

fcntl(fd, F_GLOBAL_NOCACHE, 1);在 fopen() 之后使用。请给我任何建议。非常感谢

4

2 回答 2

1

我猜Hot Licks是对的,您可能只想简单地使用-[NSData dataWithContentsOfFile:],但如果您想使用 C 级 API,您可以这样做:

#define MY_BUFFER_SIZE 1024

FILE * fd = fopen(c_sd_url, "rb");

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

char buffer[MY_BUFFER_SIZE];

if (fd)

{
    fcntl(fd, F_GLOBAL_NOCACHE, 1);

    // if you can predict the capacity it's better for performance
    NSMutableData* myData = [NSMutableData dataWithCapacity:1024];

    while(fgets(buffer, MY_BUFFER_SIZE, fd) != NULL)
    {
        [myData appendBytes:buffer length:strlen(buffer)];
    }
}

// use your 'myData'

[pool release];

更新:为了避免无用的buffer数据复制,并遵循H2CO3的评论:

最好避免将数据写入缓冲区然后将其复制到 NSMutableData,我们可以使用-[NSData mutableBytes]它直接访问底层 C 结构。此外,H2CO3是完全正确的,使用fread要好得多,因为它为我们提供了读取字节的长度。

#define MY_BUFFER_SIZE 1024

FILE * fd = fopen(c_sd_url, "rb");

if (fd)
{
    fcntl(fd, F_GLOBAL_NOCACHE, 1);

    // if you can predict the capacity it's better for performance
    NSMutableData* myData = [[NSMutableData alloc] init];

    while(YES)
    {
        // store the length before addition
        NSUInteger previousLength = [myData length];

        // increase the length so we can write more bytes
        [myData increaseLengthBy:MY_BUFFER_SIZE];

        // read bytes from stream directly at the end of our data
        size_t len = fread([myData mutableBytes] + previousLength, 1, MY_BUFFER_SIZE, fd);

        // set data length
        [myData setLength:previousLength + len];

        // if end-of-file exit the loop
        if (len == 0) {
            break;
        }
    }

    // use your 'myData'
    NSLog(@"myData: %@", [[NSString alloc] initWithData:myData encoding:NSASCIIStringEncoding]);

    [myData release];
}

如果您想要\0终止 NSData,只需在末尾添加:

[myData appendBytes:"\0" length:1];

祝你好运 ;)

于 2013-08-26T04:01:00.270 回答
1

char在 C 中,至少按标准保证为 1 个字节。

什么是无符号字符?

因此,您可以将char*其视为具有适当大小乘法的字节数组,并且可以将其传递给-[NSData initWithBytes:length:]方法。

char buffer[300];
NSData* data0 = [[NSData alloc] initWithBytes:buffer length:300 * sizeof(char)];

有几种初始化方法,因此请检查它们以满足您的需要。有关NSMutableData程序样式的使用,请参见。

或者您可以使用NSData@HotLicks 所说的方法。

NSData* data0 = [NSData dataWithContentsOfFile:@"somefile" options:NSDataReadingUncached error:NULL];
于 2013-08-26T04:01:21.737 回答