我有两个问题。
如何使用FILE *实例创建NSFileHandle对象?
如何使用void * instance?
对不起没有上下文的信息很少。
请参阅我最近提出的问题。 Weird behavior of fopen on ios我无法使用本机fopen函数创建内容或将内容写入文件。
因此,我只想在ios框架中使用api并包装fopen和fwrite以及此类人员的代码。所以我应该将FILE *对象转换为NSFileHandle或者可以操作文件的东西。此外,使用void *处理的内容应转换为可在ios框架中接受的数据格式。我认为NSData应该是首选。
答案 0 :(得分:3)
至于FILE *到NSFileHandle,我发现这个mailing list问题完全符合你的需要。相关代码:
FILE *fp;
NSFileHandle *p;
fp = fopen( "foo", "r");
p = [[[NSFileHandle alloc] initWithFileDescriptor:fileno( fp)
closeOnDealloc:YES] autorelease];
来自回答者的一个可爱警告:
小心不要从fp读取,因为stdio缓存。
编辑:对于NSData的void *,我认为你想要NSData's -initWithBytesNoCopy:Length:freeWhenDone:
。请参阅此related question了解如何使用它。
答案 1 :(得分:0)
您可以像在C中一样使用FILE *。例如......
- (id)initWithFileUrl:(NSURL *)url
{
if (self = [super init]) {
NSFileManager *fileManager = [[NSFileManager alloc] init];
[fileManager createDirectoryAtPath:[[url path] stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:0];
char const *path = [fileManager fileSystemRepresentationWithPath:url.path];
fp = fopen(path, "a");
if (!fp) {
[NSException raise:@"Can't open file for recording: " format:@"%s", strerror(errno)];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
}
return self;
}
- (void)writeBytes:(void const *)bytes length:(uint32_t)size
{
if (fp && fwrite(bytes, size, 1, fp) != 1) {
[NSException raise:@"File Write Error" format:@"%s", strerror(errno)];
}
}
- (void)writeBytes:(void const *)bytes andSize:(uint32_t)size
{
if (!fp) return;
if (fwrite(&size, sizeof size, 1, fp) != 1 || fwrite(bytes, size, 1, fp) != 1) {
[NSException raise:@"File Write Error" format:@"%s", strerror(errno)];
}
}
- (void)writeInt32:(int32_t)value
{
[self writeBytes:&value length:sizeof value];
}
- (void)writeInt64:(int64_t)value
{
[self writeBytes:&value length:sizeof value];
}
- (void)writeData:(NSData *)data
{
[self writeBytes:data.bytes andSize:data.length];
}
- (void)writeCGFloat:(CGFloat)value
{
[self writeBytes:&value length:sizeof value];
}
- (void)writeCGPoint:(CGPoint)point
{
[self writeBytes:&point length:sizeof(point)];
}