我手头有一个NSMutableData的实例,我想使用一个输入流(类似于Java的ByteArrayInputStream)读取它。
我注意到CFReadStream有一个initForReadingWithData方法,但我不知道如何使用它。
有没有人可以提供一个关于如何使用它的样例,或者如何拥有一个内存输入流?
发布于 2010-11-28 19:09:18
这是我得到的解决方案:
NSMutableData *msg;
CFReadStreamRef in = CFReadStreamCreateWithBytesNoCopy(nil, [msg mutableBytes], [_msg length], kCFAllocatorNull);
CFReadStreamOpen(in);
// read here as stream using CFReadStreamRead
CFRelease(in);发布于 2010-11-26 01:18:41
我注意到CFReadStream有一个initForReadingWithData方法,…
哈?CFReadStream没有方法;它有函数。NSInputStream有initWithData:。
对于NSInputStream,您需要成为流的委托,打开流,并响应其委托消息。其中大部分位于抽象类NSStream中,该类是NSInputStream和NSOutputStream的超类。
您可能会发现CFReadStream更易于使用,因为它允许您只调用一个函数来直接从流中读取数据,而不必遵守异步的“不调用我,我会调用你”的要求。对于从网络读取,我建议不要这样做,但既然您是从内存缓冲区读取的,那么它应该是无害的。
也就是说,创建流而不是自己遍历字节的主要原因是将其传递给可以接受任何流的东西,包括可以从网络读取的流。如果你正在实现这一端,你应该异步实现。
发布于 2015-11-24 04:01:59
这个问题的答案取决于您是希望以类似于NSStream管理其数据的方式读取数据并将其删除,还是希望进行软读取并能够再次读取数据。
对于第一种方法,最简单的方法是创建一个NSMutableData类别,该类别将读取的字节数作为参数,然后在删除数据后返回数据。
#import "NSMutableData+Queue.h"
@implementation NSMutableData (Queue)
- (NSData *)read:(NSUInteger)length
{
if(length <= self.length && length > 0)
{
NSData *data = [self subdataWithRange:NSMakeRange(0, length)];
[self replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];
return data;
}
return nil;
}
- (void)removeBytes:(NSUInteger)length
{
if(length <= self.length && length > 0)
{
[self replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];
}
}
@end第二种方法是编写一个类来管理NSData对象并对其执行软读取,同时维护对其偏移量的引用。
//
// CUDataReader.m
// Test
//
// Created by Abel Duarte on 10/28/15.
// Copyright © 2015 Abel Duarte. All rights reserved.
//
#import "CUDataReader.h"
@interface CUDataReader()
@property (nonatomic, assign) CUDataReaderEndianness endianness;
@property (nonatomic, retain) NSData *data;
@end
@implementation CUDataReader
#pragma mark - Init
- (id)initWithData:(NSData *)data
{
self = [super init];
if(self)
{
self.data = data;
self.offset = 0;
self.endianness = CUDataReaderDefaultEndian;
}
return self;
}
+ (id)dataReaderWithData:(NSData *)data
{
return [[CUDataReader alloc] initWithData:data];
}
- (void)dealloc
{
self.data = nil;
}
#pragma mark - Read
- (NSData *)read:(NSUInteger)length
{
NSUInteger readLength = self.offset + length;
if(readLength <= self.data.length && length > 0)
{
NSData *data = [self.data subdataWithRange:NSMakeRange(self.offset, length)];
self.offset += length;
return data;
}
return nil;
}
- (NSData *)readUntilData:(NSData *)data
{
NSRange dataRange = [self.data rangeOfData:data
options:0
range:NSMakeRange(self.offset, self.data.length - self.offset)];
if(dataRange.location != NSNotFound)
{
NSUInteger length = dataRange.location - self.offset;
return [self read:length];
}
return nil;
}
- (NSData *)readUntilDelimeter:(char)delimeter
{
NSData *data = [NSData dataWithBytes:&delimeter length:1];
return [self readUntilData:data];
}
#pragma mark - Endianess
- (void)setEndianness:(CUDataReaderEndianness)endianness
{
_endianness = endianness;
}
- (NSData *)endiannessDecodedData:(NSData *)data
{
if(self.endianness == CUDataReaderLittleEndian)
{
return data;
}
else
{
NSMutableData *endiannessDecodedData = [NSMutableData data];
NSUInteger length = data.length;
char *bytes = (char *)[data bytes];
for(NSInteger i = length - 1; i >= 0; i--)
{
char *byte = bytes + i;
[endiannessDecodedData appendBytes:byte length:1];
}
return endiannessDecodedData;
}
return data;
}
#pragma mark - Type utilities
- (BOOL)readBoolean
{
NSUInteger length = sizeof(BOOL);
return *(BOOL *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (char)readCharacter
{
NSUInteger length = sizeof(char);
return *(char *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (short)readShort
{
NSUInteger length = sizeof(short);
return *(short *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (int)readInteger
{
NSUInteger length = sizeof(int);
return *(int *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (float)readFloat
{
NSUInteger length = sizeof(float);
return *(float *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (double)readDouble
{
NSUInteger length = sizeof(double);
return *(double *)[[self endiannessDecodedData:[self read:length]] bytes];
}
- (long)readLong
{
NSUInteger length = sizeof(long);
return *(long *)[[self endiannessDecodedData:[self read:length]] bytes];
}
#pragma mark - Offset
- (void)rewind
{
self.offset = 0;
}
- (void)rewind:(NSUInteger)length
{
if(length <= self.offset)
{
self.offset -= length;
}
else
{
self.offset = 0;
}
}
- (void)setOffset:(NSUInteger)offset
{
if(offset <= self.data.length)
_offset = offset;
}
- (void)skip:(NSUInteger)offset
{
NSUInteger x = self.offset + offset;
[self setOffset:x];
}
- (NSUInteger)bytesRemaining
{
return self.data.length - self.offset;
}
@end有关更多信息,请查看https://github.com/abelduarte/CoreUtilities。
https://stackoverflow.com/questions/4275544
复制相似问题