使用dataoutputstream写二进制文件的主要步骤有

使用dataoutputstream写二进制文件的主要步骤有,第1张

使用dataoutputstream写二进制文件的主要步骤如下:

测试电脑:HONOR Magiclink,版本:22H2。

1、导入相关的类。

2、构造一个数据输入流对象

3、利用数据输入流类的方法读取二进制文件中的数据。

4、关闭数据输入流。

        流提供了一种简单的方式在不同和介质中交换数据,这种交换方式是与设备无关的。流是在通信路径中串行传输的连续的比特位序列。从编码的角度来看,流是单向的,因此流可以是输入流或输出流。除了基于文件的流外,其它形式的流都是不可查找的,这些流的数据一旦消耗完后,就无法从流对象中再次获取。 Cocoa中包含三个与流相关的类:NSStream、NSInputStream和NSOutputStream。NSStream是一个抽象基类,定义了所有流对象的基础接口和属性。NSInputStream和NSOutputStream是NSStream的子类,实现了输入流和输出流的默认行为。NSInputStream可以从文件、socket和NSData对象中获取数据;NSOutputStream可以将数据写入文件、socket、内存缓存和NSData对象中。这三处类主要处理一些比较底层的任务。流对象的大部分属性是用于处理网络安全和配置的,这些属性统称为SSL和SOCKS代理信息。其中两个比较重要的属性:

                NSStreamDataWrittenToMemoryStreamKey:允许输出流查询写入到内存的数据

                NSStreamFileCurrentOffsetKey:允许 *** 作基于文件的流的读写位置

      流对象可以设置代理, 代理需要遵守NSStreamDelegate代理协议, 协议里面只有一个方法stream:handleEvent:。如果没有指定,则流对象作为自己的代理。

       Cocoa中的流对象与CoreFoundation中的流对象是对应的。我们可以通过toll-free桥接方法来进行相互转换。NSStream、NSInputStream和NSOutputStream分别对应CFStream、CFReadStream和CFWriteStream。但这两者间不是完全一样的。CoreFoundation一般使用回调函数来处理数据。另外我们可以子类化NSStream、NSInputStream和NSOutputStream,来自定义一些属性和行为,而Core Foundation中的流对象则无法进行扩展。

      上面我们主要介绍了一下概念, 接下来我们看下流是如何使用的。

 从输入流中读取数据我们需要执行一下 *** 作:

    1. 从数据源中创建和初始化一个NSInputStream实例

    2.将流对象放入一个run loop中并打开流

    3.处理流对象发送到其代理的事件

    4.当没有更多数据可读取时,关闭并销毁流对象。

    要使用一个NSInputStream,必须要有数据源。数据源可以是文件、NSData对象和网络socket。创建好后,我们设置其代理对象,并将其放入到run loop中,然后打开流。

- (void)setUpStreamForFile:(NSString *)path

{

         // 创建输入流对象

         NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:path]

         // 设置代理

         inputStream.delegate = self

         // 将输入流放入当前的runLoop当中

        [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]

        // 打开输入流

         [inputStream open]

}

在流对象放入runloop且有流事件(有可读数据)发生时,流对象会向代理对象发送stream:handleEvent:消息。在打开流之前,我们需要调用流对象的scheduleInRunLoop:forMode:方法,这样做可以避免在没有数据可读时阻塞代理对象的 *** 作。我们需要确保的是流对象被放入正确的run loop中,即放入流事件发生的那个线程的run loop中。

         打开流后,我们可以使用streamStatus属性查看流的状态,用hasBytesAvailable属性检测是否有可读的数据,用streamError来查看流处理过程中产生的错误。流一旦打开后,将会持续发送stream:handleEvent:消息给代理对象,直到流结束为止。这个消息接收一个NSStreamEvent常量作为参数,以标识事件的类型。对于NSInputStream对象,主要的事件类型包括NSStreamEventOpenCompleted、NSStreamEventHasBytesAvailable和NSStreamEventEndEncountered。通常我们会对NSStreamEventHasBytesAvailable更感兴趣。

// 从流中获取数据的过程

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode

{

switch (eventCode) {

case NSStreamEventHasBytesAvailable:

{

if (!data) {

data = [NSMutableData data]

}

uint8_t buf[1024]

unsigned int len = 0

// 读取数据

len = [(NSInputStream *)aStream read:buf maxLength:1024]

if (len) {

[data appendBytes:(const void *)buf length:len]

}

}

break

}

}

        当NSInputStream在处理流的过程中出现错误时,它将停止流处理并产生一个NSStreamEventErrorOccurred事件给代理。我们同样的在上面的代理方法中来处理这个事件。

        当NSInputStream读取到流的结尾时,会发送一个NSStreamEventEndEncountered事件给代理,代理对象应该销毁流对象,此过程应该与创建时相对应。

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode

{

switch (eventCode) {

case NSStreamEventEndEncountered:

{

[aStream close]

[aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]

aStream = nil

}

break

}

}

写入数据到输出流, 需要下面几步:

  1.使用要写入的数据创建和初始化一个NSOutputStream实例,并设置代理对象。

  2.将流对象放到run loop中并打开流。

  3.处理流对象发送到代理对象中的事件。

  4.如果流对象写入数据到内存,则通过请求NSStreamDataWrittenToMemoryStreamKey属性来获取数据。

  5.当没有更多数据可供写入时,处理流对象。

        写入数据到输出流基本流程与输入流的读取差不多,我们主要介绍不同的地方。数据可写入的位置包括文件、C缓存、程序内存和网络socket。hasSpaceAvailable属性表示是否有空间来写入数据。

      如果NSOutputStream对象的目标是应用的内存时,在NSStreamEventEndEncountered事件中可能需要从内存中获取流中的数据。我们将调用NSOutputStream对象的propertyForKey:的属性,并指定key为NSStreamDataWrittenToMemoryStreamKey来获取这些数据。在stream:handleEvent:中主要处理NSStreamEventHasSpaceAvailable事件,并调用流的write:maxLength方法写数据。

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode

{

switch(eventCode) {

case NSStreamEventHasSpaceAvailable:

{

uint8_t *readBytes = (uint8_t *)[_data mutableBytes]

// readBytes是一个移动指针, byteIndex是移动的字节数

readBytes += byteIndex

int data_len = [_data length]

unsigned int len = ((data_len - byteIndex >= 1024) ?

1024 : (data_len-byteIndex))

uint8_t buf[len]

(void)memcpy(buf, readBytes, len)

len = [stream write:(const uint8_t *)buf maxLength:len]

byteIndex += len

break

}

}

}

      当代理接收到NSStreamEventHasSpaceAvailable事件而没有写入任何数据到流时,代理将不再从runloop中接收该事件,直到NSOutputStream对象接收到更多数据,这时runloop会重启NSStreamEventHasSpaceAvailable事件。

   

java通过InputStream读取和写入文件 *** 作实例代码

1. File to InputStream

File file = new File("file.xml")

InputStream inputStream = new FileInputStream(file)

2.InputStream to File

InputStream inputStream = new FileInputStream("file.xml")

OutputStream  outputStream = new FileOutputStream("file-new.xml")

int bytesWritten = 0

int byteCount = 0

byte[] bytes = new byte[1024]

while ((byteCount = inputStream.read(bytes)) != -1)

{

outputStream.write(bytes, bytesWritten, byteCount)

bytesWritten += byteCount

}

inputStream.close()

outputStream.close()


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11411238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存