笔记5:vb.net的FileStream操作




        FileStream派生于Stream类。


       在File类与FileInfo类中,提供的方法成员OpenRead,它返回只读的FileStream对象;

                                                   提供的方法成员OpenWrite,它返回可写的FileStream对象。

       下面是FileInfo提供的两个方法:

    Public Function OpenRead As FileStream
    Public Function OpenWrite As FileStream

       FileStream中,ReadByte与WriteByte每次读或写一个字节,位置自动加1。当读至文件末时,返回的是-1。


       下面是文件流FileStream中读或写字节的例子:

Imports System.IO
Imports System.Text
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '注意,下面是字节形式读写,因此若是汉字将是乱字符
        Dim s As String = "This is date" & vbCrLf _
                         & "This is date of next line"

        Dim fs As FileStream
        Dim btArray As Byte()
        Dim i As Int32 = 0 '数组索引

        '按字节读
        btArray = Encoding.ASCII.GetBytes(s)
        fs = File.OpenWrite("D:\11.txt")
        For i = 0 To UBound(btArray)
            fs.WriteByte(btArray(i))
        Next
        fs.Close()


        '按字节写
        Dim intByte As Int32 '每个字节
        i = 0

        fs = File.OpenRead("D:\11.txt")
        ReDim btArray(fs.Length)
        Do While intByte <> -1
            intByte = fs.ReadByte
            If intByte <> -1 Then
                btArray(i) = CByte(intByte)
                i += 1
            End If
        Loop
        TextBox1.Text = Encoding.ASCII.GetString(btArray)
        fs.Close()
    End Sub
End Class






一、创建FileStream对象

       1、利用上面返回值(File.OpenWrite,File.OpenRead),可以取得FileStream对象,再进行相关操作。


        2、利用FileStream类本身的New也可以创建FileStream对象:

Public Sub New ( _
	path As String, _
	mode As FileMode, _
	access As FileAccess _
)
           其中,参数前面接触过,FileMode枚举:Appen,CreateNew,Create,OpenOrCreate,Truncate.





二、字节(块)写入文件

        字节块由一个字节数组构成,充当缓冲和运输作用,如同公交车,一车一车向另一个目的地运送数据。

        

        FileSteam类提供将单一字节写入数据流的方法:WriteByte,

                           也提供了将一字节数据块写入数据流的方法:Write    

Public Overrides Sub Write ( _
	array As Byte(), _    '字节数组
	offset As Integer, _   '字节数组中起始位置
	count As Integer _     '从起始位置开始写几个字节
)

        参数都是描述字节数组的。


        例:将字节块写入文件:

Imports System.IO
Imports System.Text 'Encoding专用于编码转换
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fs As New FileStream("D:\11.txt", FileMode.Append, FileAccess.Write)
        Dim s As String = "This is my data block"
        Dim btArray As Byte()

        btArray = Encoding.ASCII.GetBytes(s) 
        fs.Write(btArray, 1, 3)
        fs.Close()
    End Sub
End Class

     注:对于一个文件流可以用CanWrite来判断是否可写






三、从文件中读取字节(块)

       同样,从文件流FileStream读取字节(块的方法是:ReadByte与Read。

Public Overrides Function Read ( _
	<OutAttribute> array As Byte(), _   '缓冲字节数组
	offset As Integer, _  '<span class="parameter" style="font-family:'Microsoft YaHei UI','Microsoft YaHei',SimSun,'Segoe UI','Lucida Grande',Verdana,Arial,Helvetica,sans-serif; font-style:italic; color:rgb(102,102,102); font-size:14px; line-height:18px">array</span><span style="color:rgb(102,102,102); font-family:'Microsoft YaHei UI','Microsoft YaHei',SimSun,'Segoe UI','Lucida Grande',Verdana,Arial,Helvetica,sans-serif; font-size:14px; line-height:18px"> 中的字节偏移量,将在此处开始读取字节</span>
	count As Integer _    '<span style="color:rgb(102,102,102); font-family:'Microsoft YaHei UI','Microsoft YaHei',SimSun,'Segoe UI','Lucida Grande',Verdana,Arial,Helvetica,sans-serif; font-size:14px; line-height:18px">最多读取的字节数</span>
) As Integer                  '读入缓冲区中的总字节数。 如果当前的字节数没有所请求那么多,则总字节数可能小于所请求的字节数;若已到达流的末尾则为零。
       简单地说:返回值就是读取的数据长度
        同Write一样,参数也是描述缓冲字节数组的。最后从数组中就可得到读出的字节


        例:从文件中读写:

Imports System.IO
Imports System.Text 'Encoding专用于编码转换
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim fs As New FileStream("D:\11.txt", FileMode.Append, FileAccess.Write)
        Dim s As String = "This is my data block"
        Dim btArray As Byte()

        btArray = Encoding.ASCII.GetBytes(s)
        fs.Write(btArray, 0, s.Length)
        fs.Close()


        fs = New FileStream("D:\11.txt", FileMode.Open, FileAccess.Read)
        ReDim btArray(fs.Length)
        fs.Read(btArray, 0, fs.Length) '一次读完(到缓冲数组中)
        TextBox1.Text = Encoding.ASCII.GetString(btArray)
        fs.Close()
    End Sub
End Class
         同样可以用CanRead来判断是否可读

        文件流占用一定资源,不用时可用Clos进行释放。

        Flush方法将缓冲区中的数据一次清空,且输出到数据流的底层文件。只有在Close没有调用又必须清空时才有意义。

       





四、文件的随机存取

       上面Read、Write等例子,是只读向前移动数据流的位置,字节在数据流中读写后,不能再回头进行重写读写。


        用Seek方法,可以重设当前数据流的位置(Position),这样可以随心所欲设置位置进行读写操作。

Public Overrides Function Seek ( _
	offset As Long, _          '相对SeekOrigin基准点的偏移量(可为负)
	origin As SeekOrigin _     '基准点
) As Long                          '移动后,流的新位置  

       origin基准点为枚举型:  Begin         指定流的开头。 

                                                  Current  指定流内的当前位置。       

                                                  End   指定流的结尾。


       注意:并不是所有文件流都支持Seek,因此,在使用Seek前先判断(下面例子没用CanSeek进行判断)

Imports System.IO
Imports System.Text
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim s As String = "This is what I want to insert text."

        Dim fs As New FileStream("D:\11.txt", FileMode.Open, FileAccess.Write)
        Dim btArray As Byte()
        btArray = Encoding.ASCII.GetBytes(s)

        fs.Seek(3, SeekOrigin.Begin) '设置当前流位置
        fs.Write(btArray, 0, btArray.Length) '注意:是此位置覆盖式,非插入式
        fs.Close()

        fs = New FileStream("D:\11.txt", FileMode.Open, FileAccess.Read)
        ReDim btArray(fs.Length)
        fs.Read(btArray, 0, fs.Length)
        TextBox1.Text = Encoding.ASCII.GetString(btArray)
        fs.Close()
    End Sub
End Class


          

          原文件是:123456,经写入后(从位置3)后面的456消失(被覆盖)






五、文件锁定

       几个程序同时对一个文件进行读或写时,就会造成无法预料的冲突或异常。

  

       为了避免这种情况,可实行锁定操作。Lock与UnLock,就是锁定与解除锁定。

Public Overridable Sub Lock ( position As Long, length As Long )
Public Overridable Sub Unlock ( position As Long, length As Long )

      下面用线程来代替不同程序操作同一个文件:

Imports System.IO
Imports System.Text
Imports System.Threading
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim read1 As Thread
        read1 = New Thread(AddressOf readone)
        Control.CheckForIllegalCrossThreadCalls = False
        read1.Start()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim read2 As Thread
        read2 = New Thread(AddressOf readtwo)
        Control.CheckForIllegalCrossThreadCalls = False
        read2.Start()
    End Sub

    Private Sub readone()
        Dim fs As New FileStream("D:\11.txt", FileMode.Open, FileAccess.Read)
        Dim bt As Int32
        Dim i As Int32 = 0

        fs.Lock(0, fs.Length)
        bt = fs.ReadByte()
        While bt <> -1
            bt = fs.ReadByte
            Thread.Sleep(500)
            i += 1
            TextBox1.Text = i.ToString
        End While
        TextBox1.Text = "over"
        fs.Unlock(0, fs.Length)

        fs.Close()
    End Sub

    Private Sub readtwo()
        Dim fs As New FileStream("D:\11.txt", FileMode.Open, FileAccess.Read)
        Dim bt As Int32
        Dim btArray As Byte()
        Dim i As Int32 = 0

        ReDim btArray(fs.Length - 1)
        Try
            bt = fs.ReadByte
            Do
                btArray(i) = bt
                bt = fs.ReadByte
                i += 1
                Thread.Sleep(100)
            Loop Until bt = -1
        Catch ex As Exception
            TextBox2.Text = ex.Message
        End Try
        TextBox2.Text = Encoding.ASCII.GetString(btArray)
        fs.Close()
    End Sub
End Class

         

         上面程序1进行读写(加入延时,以便利用这个时间来操作程序2)时,程序2再次操作锁定区域,将发生异常。

         这样有效保证了程序的正常读写。

 


以下是一个简单的VB.net程序,可以将hex文件转换为bin文件: ```vb.net Imports System.IO Public Class Form1 Private Sub btnConvert_Click(sender As Object, e As EventArgs) Handles btnConvert.Click '打开Hex文件 Dim hexFile As New StreamReader(txtHexFile.Text) '创建Bin文件 Dim binFile As New BinaryWriter(File.Open(txtBinFile.Text, FileMode.Create)) '读取每一行Hex数据 While Not hexFile.EndOfStream Dim hexData As String = hexFile.ReadLine() '跳过注释行 If Not hexData.StartsWith(":") Then Continue While End If '将Hex数据转换为字节数组 Dim hexBytes As Byte() = Enumerable.Range(0, hexData.Length).Where(Function(x) x Mod 2 = 0).[Select](Function(x) Convert.ToByte(hexData.Substring(x, 2), 16)).ToArray() '计算数据长度和地址 Dim dataLength As Integer = hexBytes(0) Dim address As Integer = (hexBytes(1) << 8) Or hexBytes(2) '将数据写入Bin文件 For i As Integer = 0 To dataLength - 1 binFile.Write(hexBytes(i + 4)) Next End While '关闭文件 hexFile.Close() binFile.Close() MessageBox.Show("转换完成!") End Sub Private Sub btnBrowseHex_Click(sender As Object, e As EventArgs) Handles btnBrowseHex.Click '选择Hex文件 If OpenFileDialog1.ShowDialog() = DialogResult.OK Then txtHexFile.Text = OpenFileDialog1.FileName End If End Sub Private Sub btnBrowseBin_Click(sender As Object, e As EventArgs) Handles btnBrowseBin.Click '选择Bin文件 If SaveFileDialog1.ShowDialog() = DialogResult.OK Then txtBinFile.Text = SaveFileDialog1.FileName End If End Sub End Class ``` 该程序需要三个控件:两个文本框用于选择Hex文件和保存Bin文件,一个按钮用于开始转换。在转换过程中,程序将逐行读取Hex文件,并将每一行数据转换为字节数组。然后,程序会计算数据长度和地址,并将数据写入Bin文件。最后,程序会关闭文件并显示一个消息框,提示转换已完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值