none
请问在VB.NET2008关于“流不可读”的问题 RRS feed

  • 问题

  •  

    在A窗体中写入以下代码

     

    Public CSFStream As FileStream
    
    CSFStream = New FileStream(Me.strCSFfile, FileMode.Open, FileAccess.Read)

     

    在B窗体中写入以下代码:

     

    strCsfName = ReadCSF(CSFStream)
    
    ‘ ReadCSF是一个过程,strCsfName是String

     

    用于读取流CSFStream,但当A窗体隐藏后,在B窗体中执行到strCsfName = ReadCSF(CSFStream)这句时会出错,提示“流不可读”,请问大家如何解决?

     

    2010年7月18日 9:57

答案

  • 现在的临时解决方案就是每次读一次流都重新打开一次文件

    CSFStream2 = New FileStream(frmMain.strCSFfile, FileMode.Open, FileAccess.Read)

    不过这样程序效率很低。

    难道打开的流都只能读一次就自动关闭吗?

    2010年7月26日 11:43

全部回复

  • 你好!

         你首先需要确保这里的CSFStream:

    Public CSFStream As FileStream

    CSFStream = New FileStream(Me.strCSFfile, FileMode.Open, FileAccess.Read)

         和这里的CSFStream:

    strCsfName = ReadCSF(CSFStream)

         是同一个对象。


    周雪峰
    2010年7月19日 6:30
    版主
  • frmMain.vb:
     Public CSFStream2 As FileStream
     CSFStream2 = New FileStream(Me.strCSFfile, FileMode.Open, FileAccess.Read)
    
    modReadUnitsList.vb:
     strCsfName = ReadCSF(frmMain.CSFStream2)
    
    modReadCsf.vb:(by YuriX)
    
    Imports System.Collections.Generic
    Imports System.IO
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    
    Module modReadCsf
     Public Const FID As Integer = 1129530912
     Public Const HID As Integer = 1279413280
     Public Const WID As Integer = 0
    
    
     Structure CsfHeader
     Public id As Integer
     Public flag1 As Integer
     Public count1 As Integer
     Public count2 As Integer
     Public zero As Integer
     Public flag2 As Integer
     End Structure
    
    
     Public Function ReadCSF(ByVal src As Stream) As Dictionary(Of String, KeyValuePair(Of String, String))
    
     Dim br As New BinaryReader(src, Encoding.ASCII)
    
    
     Dim header As CsfHeader
     Dim data1 As Object
    
    
     header.id = br.ReadInt32()
     If header.id = FID Then
      header.flag1 = br.ReadInt32()
      header.count1 = br.ReadInt32()
      header.count2 = br.ReadInt32()
      header.zero = br.ReadInt32()
      header.flag2 = br.ReadInt32()
    
    
      data1 = New Dictionary(Of String, KeyValuePair(Of String, String))(header.count1)
    
    
      For i As Integer = 0 To header.count1 - 1
      Dim id As Integer = br.ReadInt32()
    
    
      If id = HID Then
       Dim flag As Integer = br.ReadInt32()
    
    
       Dim len As Integer = br.ReadInt32()
       Dim chs As Char() = br.ReadChars(len)
       Dim key As String = New String(chs).ToUpper()
    
    
       If (flag And 1) <> 0 Then
       id = br.ReadInt32()
       ' label内容类型
       ' 读字符串(内容)
       len = br.ReadInt32()
       '长度
       Dim value As Byte() = br.ReadBytes(len * 2)
    
    
       Dim sb As New StringBuilder(len)
       For j As Integer = 0 To value.Length - 1 Step 2
        Dim sh As Integer = CInt((value(j) + value(j + 1) * 256))
    
    
        If sh > Int16.MaxValue Then
        Dim ch As Char = ChrW(UInt16.MaxValue + 1 + Not sh)
        sb.Append(ch)
        Else
        Dim ch As Char = ChrW(Not sh)
        sb.Append(ch)
        End If
    
    
       Next
    
    
       Dim val As String = sb.ToString()
    
    
       Dim ext As String = Nothing
       ' 读附加数据
       If id = WID Then
        len = br.ReadInt32()
        ext = New String(br.ReadChars(len))
       End If
    
    
       data1.Add(key, New KeyValuePair(Of String, String)(ext, val))
       Else
       data1.Add(key, New KeyValuePair(Of String, String)(String.Empty, String.Empty))
       End If
      End If
      Next
     Else
      Throw New FormatException(src.ToString())
     End If
    
     ReadCSF = data1
     br.Close()
     End Function
    End Module
    
    ----------------------------------------------------------------------------------------------
    感谢版主周雪峰关注我的问题!
    已更改CSFStream为CSFStream2,但还是不行!
    一执行到strCsfName = ReadCSF(frmMain.CSFStream2)这句
    就提示:
    未处理 ArgumentException 流不可读

    鼠标移到Dim br As New BinaryReader(src, Encoding.ASCII)这句的“src”上,即时提示:Length = {"无法访问已关闭的文件。"}

    请问如何解决?是不是跟br.Close()有关?
    2010年7月19日 11:14
  • 你好!

        你检查一下是否在其他地方已经把流关闭了,这样导致的不读。


    周雪峰
    2010年7月19日 12:13
    版主
  • 跟踪CSFStream2 = New FileStream(Me.strCSFfile, FileMode.Open, FileAccess.Read)
    执行没

    没什么不把frmMain.CSFStream2改成用模块级变量


    http://feiyun0112.cnblogs.com/
    2010年7月20日 6:58
    版主
  • 谢谢feiyun0112周雪峰

    我似乎没发现在其他地方已经把流关闭了,并已改用模块级变量,但问题未解决。


    请直接下载源代码(开源软件):

    http://www.dbank.com/download.action?t=40&k=NDI5Njg4NTk=&pcode=LCwxMzk3MjkxLDEzOTcyOTE=&rnd=4

     

    运行程序,从菜单“操作”\“打开”中按顺序打开“src\bin\rulesmd.ini”和“src\bin\ra2md.csf”。点击“步兵”,之后程序出错,提示“流不可读”。

    2010年7月21日 3:54
  • 你好!

        请检查一下这些文件的属性,是否允许读取?


    周雪峰
    2010年7月22日 13:29
    版主
  • 允许读取,我怀疑还是代码的问题。
    2010年7月23日 3:24
  • 现在的临时解决方案就是每次读一次流都重新打开一次文件

    CSFStream2 = New FileStream(frmMain.strCSFfile, FileMode.Open, FileAccess.Read)

    不过这样程序效率很低。

    难道打开的流都只能读一次就自动关闭吗?

    2010年7月26日 11:43
  • 没人知道?
    2010年7月30日 3:25