二进制文件读写的知识点和练习

知识点

System.IO命名空间提供了BinaryReader和BinaryWriter类用来读写二进制文件
一、BinaryReader 类
[ComVisibleAttribute(true)]
public class BinaryReader : IDisposable

BinaryReader 类 构造函数 (Stream) 基于所提供的流,用 UTF8Encoding 初始化 BinaryReader 类的新实例。
public BinaryReader (
    Stream input
)
参数
input
流。

其中需注意的为
1、System.IO.Stream类  提供字节序列的一般视图。

(1)流涉及三个基本操作:

可以读取流。读取是从流到数据结构(如字节数组)的数据传输。

可以写入流。写入是从数据结构到流的数据传输。

流可以支持查找。查找是对流内的当前位置进行查询和修改。查找功能取决于流具有的后备存储区类型。例如,网络流没有当前位置的统一概念,因此一般不支持查找。

(2)Stream 是所有流的抽象基类。流是字节序列的抽象概念,例如文件、输入/输出设备、内部进程通信管道或者 TCP/IP 套接字。Stream 类及其派生类提供这些不同类型的输
入和输出的一般视图,使程序员不必了解操作系统和基础设备的具体细节。

(3)根据基础数据源或储存库,流可能只支持这些功能中的一部分。通过使用 CanRead、CanWrite 和 CanSeek 属性,应用程序可以查询流的功能。

Read 和 Write 方法读写各种不同格式的数据。对于支持查找的流,使用 Seek 和 SetLength 方法以及 Position 和 Length 属性可查询和修改流的当前位置和长度。

有些流实现执行基础数据的本地缓冲以提高性能。对于这样的流,Flush 方法可用于清除所有内部缓冲区并确保将所有数据写入基础数据源或储存库。

在 Stream 上调用 Close 将刷新所有经过缓冲处理的数据,本质上是为您调用了 Flush。Close 也会释放操作系统资源,如文件句柄、网络连接或用于任何内部缓冲的内存。
BufferedStream 类提供了将一个经过缓冲的流环绕另一个流的功能,以便提高读写性能。

如果需要不带后备存储区(即位存储桶)的流,请使用 Null。

(4)给实现者的说明 在实现 Stream 的派生类时,必须提供 Read 和 Write 方法的实现。异步方法 BeginRead、EndRead、BeginWrite 和 EndWrite 通过同步方法 Read 和
Write 实现。同样,Read 和 Write 的实现也将与异步方法一起正常工作。ReadByte 和 WriteByte 的默认实现创建一个新的单元素字节数组,然后调用 Read 和 Write 的实现。
当从 Stream 派生时,如果有内部字节缓冲区,则强烈建议重写这些方法以访问内部缓冲区,这样性能将得到显著提高。还必须提供 CanRead、CanSeek、CanWrite、Flush、
Length、Position、Seek 和 SetLength 的实现。

2、要注意的是FileStream 类 继承了Stream类

二、BinaryReader类提供的部分方法如下:
1、 Close  关闭当前阅读器及基础流。 
public virtual void Close ()

Close 的此实现调用传递 true 值的 Dispose 方法。

除非显式地调用 Flush 或 Close,否则,刷新流不会刷新其基础编码器。将 AutoFlush 设置为 true 意味着将数据从缓冲区刷新到流中,但不刷新编码器状态。这将允许编码器
保持其状态(不完全字符),以便它可以正确地对下一个字符块进行编码。此方案影响 UTF8 和 UTF7,这二者中,某些字符只能在编码器收到相邻的一个或多个字符后才能进行编
码。

2、Read  已重载。 从基础流中读取字符,并提升流的当前位置。 
BinaryReader.Read ()  从基础流中读取字符,并根据所使用的 Encoding 和从流中读取的特定字符,提升流的当前位置。 
public virtual int Read ()
返回值
输入流中的下一个字符,如果当前无可用字符则为 -1。

BinaryReader.Read (Byte[], Int32, Int32)  将 index 作为字节数组中的起始点,从流中读取 count 个字节。 
public virtual int Read (
    byte[] buffer,
    int index,
    int count
)
参数
buffer
要读入数据的缓冲区。

index
缓冲区中的起始点,在该处开始读入缓冲区。

count
要读取的字符数。

返回值
读入 buffer 的字符数。如果可用的字节没有请求的那么多,此数可能小于所请求的字节数;如果到达了流的末尾,此数可能为零。

BinaryReader.Read (Char[], Int32, Int32)  将 index 作为字符数组中的起始点,从流中读取 count 个字符。 
public virtual int Read (
    char[] buffer,
    int index,
    int count
)
参数
buffer
要读入数据的缓冲区。

index
缓冲区中的起始点,在该处开始读入缓冲区。

count
要读取的字符数。

返回值
读入缓冲区的总字符数。如果当前可用的字节没有请求的那么多,此数可能小于所请求的字符数;如果到达了流的末尾,此数可能为零。

2、ReadByte  从当前流中读取下一个字节,并使流的当前位置提升 1 个字节。 
   ReadBytes  从当前流中将 count 个字节读入字节数组,并使当前位置提升 count 个字节。 
public virtual byte[] ReadBytes (
    int count
)
参数
count
要读取的字节数。
返回值
包含从基础流中读取的数据的字节数组。如果到达了流的末尾,则该字节数组可能小于所请求的字节数。

3、ReadInt32  从当前流中读取 4 字节有符号整数,并使流的当前位置提升 4 个字节。 
public virtual int ReadInt32 ()

4、ReadString  从当前流中读取一个字符串。字符串有长度前缀,一次 7 位地被编码为整数。 
public virtual string ReadString ()

三、BinaryWriter类 BinaryWriter 以二进制形式将基元类型写入流,并支持用特定的编码写入字符串。
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class BinaryWriter : IDisposable

BinaryWriter 构造函数 (Stream)
public BinaryWriter (
    Stream output
)
参数
output
输出流。

四、BinaryWriter类 部分方法
1、Close  关闭当前的 BinaryWriter 和基础流。 
Close 的此实现调用传递 true 值的 Dispose 方法。

除非显式地调用 Flush 或 Close,否则,刷新流不会刷新其基础编
码器。将 AutoFlush 设置为 true 意味着将数据从缓冲区刷新到流中,但不刷新编码器状态。这将允许编码器保持其状态(不完全字符),以便它可以正确地对下一个字符块进行
编码。此方案影响 UTF8 和 UTF7,这二者中,某些字符只能在编码器收到相邻的一个或多个字符后才能进行编码。

2、 Flush  清理当前编写器的所有缓冲区,使所有缓冲数据写入基础设备。 

3、Seek  设置当前流中的位置。
public virtual long Seek (
    int offset,
    SeekOrigin origin
)
参数
offset
相对于 origin 的字节偏移量。

origin
SeekOrigin 的一个字段,指示获取新位置所依据的参考点。

4、Write  已重载。 将值写入当前流。
BinaryWriter.Write (String)  将有长度前缀的字符串按 BinaryWriter 的当前编码写入此流,并根据所使用的编码和写入流的特定字符,提升流的当前位置。 
BinaryWriter.Write (Int32)  将 4 字节有符号整数写入当前流,并将流的位置提升 4 个字节。 

 

练习

using System;
using System.IO;
using System.Text;
using System.Collections.Generic;

namespace BinaryReadWrite
{
    public class Program
    {
        static void Main()
        {
            try
            {
                string path = "c:\\binarytest\\test.txt";
                Stream st1 = File.Open(path, FileMode.Create, FileAccess.Write);//因为FileStream继承自Stream类,所以可以隐式转换成Stream类对象
                BinaryWriter bw = new BinaryWriter(st1);
                //bw.Write("hello C#!");//将字符串写入时,文件显示的还是字符串
                int i = 7;
                bw.Write(i);//写入流的是整型等,文件显示就不是元数字了,通过对应的Read方法,如ReadInt32()才能将原值读出来
                bw.Close();
                st1.Close();
                Console.ReadLine();
                Stream st2 = File.Open(path, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(st2);
                //Console.WriteLine(br.ReadString());
                Console.WriteLine(br.ReadInt32());
                br.Close();
                st2.Close();
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadLine();
        }
    }
}

转载于:https://www.cnblogs.com/365up/archive/2009/10/03/1577472.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值