首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将NSMutableData作为流读取

将NSMutableData作为流读取
EN

Stack Overflow用户
提问于 2010-11-25 17:36:45
回答 3查看 1K关注 0票数 0

我手头有一个NSMutableData的实例,我想使用一个输入流(类似于Java的ByteArrayInputStream)读取它。

我注意到CFReadStream有一个initForReadingWithData方法,但我不知道如何使用它。

有没有人可以提供一个关于如何使用它的样例,或者如何拥有一个内存输入流?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-11-28 19:09:18

这是我得到的解决方案:

代码语言:javascript
复制
NSMutableData *msg;
CFReadStreamRef in = CFReadStreamCreateWithBytesNoCopy(nil, [msg mutableBytes], [_msg length], kCFAllocatorNull);
CFReadStreamOpen(in);
// read here as stream using CFReadStreamRead
CFRelease(in);
票数 0
EN

Stack Overflow用户

发布于 2010-11-26 01:18:41

我注意到CFReadStream有一个initForReadingWithData方法,…

哈?CFReadStream没有方法;它有函数。NSInputStream有initWithData:

对于NSInputStream,您需要成为流的委托,打开流,并响应其委托消息。其中大部分位于抽象类NSStream中,该类是NSInputStream和NSOutputStream的超类。

您可能会发现CFReadStream更易于使用,因为它允许您只调用一个函数来直接从流中读取数据,而不必遵守异步的“不调用我,我会调用你”的要求。对于从网络读取,我建议不要这样做,但既然您是从内存缓冲区读取的,那么它应该是无害的。

也就是说,创建流而不是自己遍历字节的主要原因是将其传递给可以接受任何流的东西,包括可以从网络读取的流。如果你正在实现这一端,你应该异步实现。

票数 0
EN

Stack Overflow用户

发布于 2015-11-24 04:01:59

这个问题的答案取决于您是希望以类似于NSStream管理其数据的方式读取数据并将其删除,还是希望进行软读取并能够再次读取数据。

对于第一种方法,最简单的方法是创建一个NSMutableData类别,该类别将读取的字节数作为参数,然后在删除数据后返回数据。

代码语言:javascript
复制
#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对象并对其执行软读取,同时维护对其偏移量的引用。

代码语言:javascript
复制
//
//  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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4275544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档