Click here to Skip to main content
15,880,796 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Some of my RA datafiles remain hung "open". I have not been able to find how this is happening yet and I don't know what the file number is

Is there a way to absolutley "close" a file using a My.Computer.FileSystem method?

Is there a way to determine what the file number is for a given data file?
Posted
Comments
[no name] 5-Oct-12 14:27pm    
You mean like FileSystem.FileClose?
[no name] 5-Oct-12 17:22pm    
If you omit FileNumbers, all active files opened by the FileOpen function are closed.
KevinBrady57 5-Oct-12 17:31pm    
What do you mean by "omit FileNumbers"? I don;t understand.
Sergey Alexandrovich Kryukov 5-Oct-12 20:18pm    
Not enough information. If it happens, it means you have some bugs. A code sample could help. Make it as short as possible; try to reproduce only this problem and do nothing else in such a sample application.
--SA

Can you explain how you are creating a random access file?
Is it via VB6 - FileGet and FilePut etc. You refer to FileNumbers which suggests you are using VB6 and FreeFile.

Can I suggest you use NET and use standard FileStream methods. You can then develop a class that then creates the different fields.
 
Share this answer
 
Comments
KevinBrady57 9-Oct-12 17:49pm    
Yes, I am using the old VB6 FileGet and FilePut. The .ney version of the program that I am currenyly working on was converted to VB2010 from VB6. It is a pretty large, class based program with 15 different modules.

I tried to use filestream methods when I converted all my programming efforts to VB.Net earlier this year. The problem that I encountered was that I could not get it to correctly read & write unicode characters, like ß (eszet in German). If you could tell me how to use uncode characters with filestream methods, that would be great.
try this
VB
Imports System.Text

   Public Function FnLStr(ByVal a As String, ByVal i As Integer, Optional ByVal s As Integer = 32) As String
      If a Is Nothing Then a = ""
      Return a.PadRight(i, Chr(s))
   End Function

   Public Function Encode(ByVal bt() As Byte, ByVal bg As Integer, ByVal s As String, ByVal len As Integer) As Byte()
      s = FnLStr(s, len)
      Dim unicode As Encoding = Encoding.Unicode
      Dim b() As Byte = unicode.GetBytes(s)
      For i = 0 To len * 2 - 1
         bt(bg + i) = b(i)
      Next
      Return bt
   End Function

   Public Function Decode(ByVal bt() As Byte, ByVal bg As Integer, ByVal len As Integer) As String
      Dim ea As Encoding = Encoding.ASCII
      Dim eu As Encoding = Encoding.Unicode
      Dim b(len * 2 - 1) As Byte
      For i = 0 To len * 2 - 1
         b(i) = bt(i + bg)
      Next
      b = Encoding.Convert(eu, ea, b)
      For i = 0 To UBound(b)
         If b(i) = 0 Then b(i) = 32
      Next
      Dim a(ea.GetCharCount(b, 0, b.Length) - 1) As Char
      ea.GetChars(b, 0, b.Length, a, 0)
      Return New String(a).Trim
   End Function


as you can see, you need twice as many characters to store Unicode
 
Share this answer
 
Comments
KevinBrady57 9-Oct-12 18:59pm    
Stuart, thanks very much for the quick response. Can you please provide an example of using the above for filestream read and write events.

I would have thought that unicode support would have been "built-in" to .NET?
Here is a typical class:-
VB
Public Class MyClass
 Private bt(1234) As Byte
#Region " Properties "
   Public Property Bytes() As Byte()
      Get
         Return bt
      End Get
      Set(ByVal value As Byte())
         bt = value
      End Set
   End Property
   Public Property Access() As Integer
      Get
         Return bt(0)
      End Get
      Set(ByVal Value As Integer)
         bt(0) = CByte(Value)
      End Set
   End Property
   Public Property ChargeExpenses() As Byte
      Get
         Return bt(1)
      End Get
      Set(ByVal value As Byte)
         bt(1) = value
      End Set
   End Property
   Public Property ChargeExpensesValue() As Integer
      Get
         Return bt(2) + bt(3) * cn256
      End Get
      Set(ByVal value As Integer)
         bt(3) = CByte(value \ cn256)
         bt(2) = CByte(value - bt(3) * cn256)
      End Set
   End Property
   Public Property ChargeVat() As Boolean
      Get
         Return bt(7) = 1
      End Get
      Set(ByVal value As Boolean)
         If value Then bt(7) = 1 Else bt(7) = 0
      End Set
   End Property
   Public Property Cost() As Double
      Get
         Return FnBytesToReal(bt, 8) ' my own conversion function
      End Get
      Set(ByVal Value As Double)
         bt = FnRealToBytes(bt, 8, Value)
      End Set
   End Property
   Public Property Created() As String
      Get
         Dim a As String
         Try
            a = New Date(bt(20) + l_Times.BaseYear, bt(19), bt(18)).ToShortDateString
         Catch ex As Exception
            Try
               a = New Date(bt(18) + l_Times.BaseYear, bt(19), bt(20)).ToShortDateString
            Catch ex1 As Exception
               a = ""
            End Try
            a = ""
         End Try
         If a = "" Then Return CStr(Today) Else Return a
      End Get
      Set(ByVal Value As String)
         Dim v As Date = CDate(Value)
         bt(18) = CByte(v.Day)
         bt(19) = CByte(v.Month)
         bt(20) = CByte(v.Year - l_Times.BaseYear)
      End Set
   End Property
    Public Property Description(ByVal Index As Integer) As String
      Get
         Dim k As Integer
         Select Case Index
            Case 0 : k = 163
            Case 1 : k = 227
            Case 2 : k = 291
            Case 3 : k = 355
         End Select
         Dim a As String = Decode(bt, k, 32)
         Return a.Trim
      End Get
      Set(ByVal value As String)
         Dim k As Integer
         Select Case Index
            Case 0 : k = 163
            Case 1 : k = 227
            Case 2 : k = 291
            Case 3 : k = 355
         End Select
         bt = Encode(bt, k, value, 32)
      End Set
   End Property 
Now you need to read the file and put it into this class.
Start with class RandomFile
#Region " Read File "
   Public Function OpenReader() As e_ioRead ' my enum
      If File.Exists(fpath) Then ' fPath setup in New
         Dim r As Integer
         Do
            Try
               r += 1
               fs = New FileStream(fpath, FileMode.Open, FileAccess.Read, FileShare.None)
               Exit Do
            Catch ex As Exception
               If r > 256 Then Return e_ioRead.Lock
            End Try
         Loop
         sr = New BinaryReader(fs)
         Return e_ioRead.OK
      Else
         Return e_ioRead.Err
      End If
   End Function
   Public Function ReadBytes(ByVal Record As Integer) As Byte()
      Try
         fs.Seek(LineWidth * Record + hk, SeekOrigin.Begin) ' linewidth is width of record x2 if using Encoding
         Dim b() As Byte = sr.ReadBytes(LineWidth)
         Return b
      Catch ex As Exception
         Return Nothing
      End Try
   End Function
   Public Sub CloseReader()
      sr.Close()
      fs.Close()
      fs.Dispose()
   End Sub
#End Region
Now somewhere else have something like this:-
VB
Private Function OpenforRead(ByVal path As String) As Boolean
   mfs = New RandomFile(path)
   Select Case mfs.OpenReader(-1)
      Case e_ioRead.OK
         K = mfs.Count
         Return True
      Case e_ioRead.Lock
         MsgBox(path & " is locked!")
      Case Else
         K = -1
         Return False
   End Select
End Function

Public Function Read() As MyClass
      If OpenforRead() Then
         With mfs
            Try
               CurrentJd = New MyClass
               CurrentJd.Bytes = .ReadBytes(cJob)
            Catch ex As Exception
               MsgBox(ex.Message)
            End Try
            .CloseReader()
         End With
      End If
      Return CurrentJd
   End Function

Hope you get the idea
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900