none
How do I get the "FIleGet" Function to retrieve the record text of a random access file? RRS feed

  • Question

  • Greetings everyone, as a brief introductory, I’m quite the noob to Visual Studio, so please try to be gentle with any responses you might have.  Overall, I have programs that I wrote back in the days of DOS oriented "Quick basic" that I am rewriting in visual studio for compatibility with the newer windows as using an old copy of windows xp in a virtual environment is becoming more and more impractical, especially for others that wish to use my programs.  In the beginning, I was very overwhelmed with the structure of visual studio and how to get things to work in it at all... and though I am still smashing into tree stumps, I am overcoming these obstacles a little at a time… on to my dilemma.

     

    Before posting this, I read the material(s) about how to post in here, and I did note that it stated not to duplicate posts from different forums … however, I asked a question in the General Windows Forms forum and I am not sure how to go about “transferring” the question to this forum, but it was indicated by “Kyle” that my question seemed to be more of a VB question than a WF… so here I am and hopefully duplicating the question here won’t cause any problems.

     

    I seem to be having some difficulty in reading records from random access files - using the random mode with the FileOpen fuction, I am able to create files and write (using FilePut) records to them, but the FileGet function is either not reading the records, or it’s not assigning the text in the record to the variable …

     

    Here’s a small program I put together for testing purposes followed by an explanation of what I believe should be resulted from the code.

     

    Public Class Form1
    
        Public Change As Integer = 0
        Public Fdir As String = "F:\TestDirectory\"
        Public Fnam As String = ""
        <VBFixedString(128)> Public DataS As String
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Label1.Text = "CURRENT DIRECTORY IS:"
            Label2.Text = Fdir    ' THIS IS CURRENT DIRECTORY
            Label3.Text = "SUGGESTED GAME DATA PATH IS:"
            Label4.Text = Fdir + "GameData\"
            Label5.Text = "Enter the desired game data path below:     << maximum path length is 128 characters >>"
            FileOpen(1, Fdir + "GameDataPath.dat", OpenMode.Random, , , 128)
            Label6.Text = Str(LOF(1))
            '<VBFixedString(128)> Public DataS As String
            If LOF(1) > 0 Then FileGet(1, DataS, 1, True)
            TextBox1.Text = Trim(DataS) : Fnam = TextBox1.Text
            FileClose(1)
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TextBox1.Text <> Nothing Then
                If Microsoft.VisualBasic.Right(TextBox1.Text, 1) <> "\" Then TextBox1.Text = TextBox1.Text & "\"
                If TextBox1.Text <> Fnam Then Change = 1
                If Change = 1 Then
                    If MsgBox("Confirm the Desired Game Data Path as " + UCase(TextBox1.Text), MsgBoxStyle.YesNo, "Confirmation") = MsgBoxResult.No Then Exit Sub
                    Try : MkDir(TextBox1.Text)
                    Catch ex As Exception '<Directory already exists>
                    End Try
                    DataS = LSet(TextBox1.Text, 128)
                    FileOpen(1, Fdir + "GameDataPath.dat", OpenMode.Random, , , 128)
                    FilePut(1, DataS, 1, True)
                    FileClose(1)
                End If
            End If
            'Since this button is actualy a continue button, at this point the code directs the program to its main processes...
            'but for purposes of this test, the program is set to close (exit) upon completion/clicking
            Me.Close()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'this button is used to Delete the data file created above and then Close the program
            Kill(Fdir + "~GameDataPath.dat")
            Me.Close()
        End Sub
    
    End Class
    
     

    Starting at the top, the initial variable declarations (I dont think i need to describe anything here)

     

                    Under the form1 loader

    I don’t think I need to describe the labels or the textbox functions

    ... Upon the first time the program is run, the "FileOpen" function initially creates the data file, which means at this point the LOF is 0[zero] - for testing purposes, I used label6 to verify the file length during run time.  At this point, because LOF=0, nothing is read from the data file, this is reflected in the textbox during runtime as it is set to the null string value of DataS (which displays nothing).

     

                    Under Button1 Click

    the first line ensures it does nothing if nothing is typed in the Textbox.

    the second line ensures the data path that is entered ends with a backslash.

    third line identifies any change to the contents of the textbox.

    upon confirmation of any changes, it creates the directory if it does not already exist, and then puts the directory path the user entered into the first record of the data file using the FilePut function - after which, the program is closed ...

     

    Running the program a second time ... Under the form1 loader

    the FileOpen function opens the data file, which now has a length greater than 0, so it employs the FileGet Function... which is set to read the first record of the file, problem is that the textbox (and any other variable or label i've tried) shows nothing, and (as is obvious) I dont understand why...

     

    initially I tried reading the record into a standard variable length string, but sorting thru Microsoft's Visual Studio Document for visual basic, I read that the string value of a FileGet function needed to be read into a fixed length string - I attempted to declare a fixed length variable "DataS". but this still did not work, I tried to insert this declaration just before the fileGet function, but it wouldn't allow it... I also tried to use the "Lset" function just previous to the FIleGet to set a length to the DataS variable, but that didn't work either (I didn't actually think this would work, but I was desperate to try anything!)

     

    I did check the data file itself, opened it in word pad and the text was in the file exactly as I entered it (in the textbox during runtime) and the end of the record was at the 128th place, when the file was opened with the program's second run, the label6 text verified the file length of 128, so the FilePut (set with all the same parameters as instructed by the microsoft documentation, and the same as the FIleGet parameters) functioned properly... Hence, I'm at wit's end ... all these things verify the record text is there and the file is open - and all the syntax of all the "file" operations are correct and working as they should, except for the FileGet ... Is there something wrong with the syntax of my code?  Or am I missing some code somewhere, for example, is there additional code that needs to be added for the FileGet function to work?

     

    Also, Kyle, from the General Windows Forms Forum provided (as a solution) a link to Docs >> .Net >> Visual Basic Code >> Developing Applications >>  “Reading From Files”  … … I scanned down and read the information on “reading from fixed width text files”.  Though the information in this link could be helpful as one possible solution, it would be rather impractical, as the files are quite extensive and this solution indicates a “sequential” reading style, which means the entire file would have to be read, and written to each time a single record is changed, I need to be able to read and write records independently for the program(s) to function quickly and smoothly.

     

    Other Facts

    OS = Windows 10 Home, Ver1803, Build 17134.885

    Using Visual Studio 2013 Pro, Ver12, Update4 - .Net Framework, Ver 4.7

    Using Visual Basic – Windows Forms Application

     

    Thursday, July 11, 2019 2:54 AM

Answers

  • Hi,

    FileSystem.FileGet Method Reads data from an open disk file into a variable. The My feature gives you better productivity and performance in file I/O operations than FileGet,see the following link:

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.filesystem?view=netframework-4.8

    Do you want to read a dat file?try my code:

     Dim fileReader As String
     fileReader = My.Computer.FileSystem.ReadAllText("D:\test.dat")

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Diomtus Monday, July 15, 2019 7:02 AM
    Thursday, July 11, 2019 5:53 AM
    Moderator

All replies

  • Hello everyone, It's me, "totally baffled" ... ... ... again...

    I can't seem to wrap my head around why I am not able to read records from a file with the same program that created the file... ... ...

    Public Class Form1
    
        Public Change As Integer = 0
        Public Fdir As String = "F:\TestDirectory\"
        Public Fnam As String = ""
        <VBFixedString(128)> Public DataS As String
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Fdir = My.Computer.FileSystem.CurrentDirectory
            'If Microsoft.VisualBasic.Right(Fdir, 1) <> "\" Then Fdir = Fdir + "\"
            Label1.Text = "CURRENT DIRECTORY IS:"
            Label2.Text = Fdir    ' THIS IS CURRENT DIRECTORY
            Label3.Text = "SUGGESTED GAME DATA PATH IS:"
            Label4.Text = Fdir + "GameData\"
            Label5.Text = "Enter the desired game data path below:     << maximum path length is 128 characters >>"
            'Label6.Text = "On first run, the above data path defaults to the suggested game data path, thereafter defaults to the last path entered."
            FileOpen(1, Fdir + "GameDataPath.dat", OpenMode.Random, , , 128)
            Label6.Text = Str(LOF(1))
            '<VBFixedString(128)> Public DataS As String
            If LOF(1) > 0 Then FileGet(1, DataS, 1, True)
            TextBox1.Text = Trim(DataS)
            FileClose(1)
            'If Fnam = "" Then Fnam = Fdir + "GameData\" : Change = 1
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TextBox1.Text <> Nothing Then
                If Microsoft.VisualBasic.Right(TextBox1.Text, 1) <> "\" Then TextBox1.Text = TextBox1.Text & "\"
                If TextBox1.Text <> Fnam Then Change = 1
                If Change = 1 Then
                    If MsgBox("Confirm the Desired Game Data Path as " + UCase(TextBox1.Text), MsgBoxStyle.YesNo, "Confirmation") = MsgBoxResult.No Then Exit Sub
                    Try : MkDir(TextBox1.Text)
                    Catch ex As Exception '<Directory already exists>
                    End Try
                    DataS = LSet(TextBox1.Text, 128)
                    FileOpen(1, Fdir + "GameDataPath.dat", OpenMode.Random, , , 128)
                    FilePut(1, DataS, 1, True)
                    FileClose(1)
                End If
            End If
            'Since this button is actualy a continue button, at this point the code directs the program to its main processes...
            'but for purposes of this test, the program is set to close (exit) upon completion/clicking
            Me.Close()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'this button is used to Delete the data file created above and then Close the program
            Kill(Fdir + "~GameDataPath.dat")
            Me.Close()
        End Sub
    
    End Class
    

    A detailed description...
    the initial variable declarations (dont think i need to describe anything here)

        Under the form1 loader
    the first two lines were commented out, i set the "Fdir" string in the declaration segment for purposes of testing
    dont think i need to describe the labels or the textbox functions
    ... the first time the program is run, the "FileOpen" function initially creates the data file, which means at this point the LOF is 0[zero] - for testing purposes, i used label6 to verify the filelength during run time.  At this point, because LOF=0, nothing is read from the data file, this is reflected in the textbox during runtime as it is set to the null string value of DataS (which displays nothing).

        Under Button1 Click
    the first line ensures it does nothing if nothing is typed in the Textbox.
    the second line ensures the data path that is entered ends with a backslash.
    third line identifies any change to the contents of the textbox.
    upon confirmation of any changes, it creates the directory if it does not already exist, and then puts the directory path into the first record of the data file using the FilePut function - after which, the program is closed ...

    Running the program a second time ... Under the form1 loader
    the FileOpen function opens the data file, which now has a length greater than 0, so it employs the FileGet Function... which is set to read the first record of the file, problem is that the textbox (and any other variable or label i've tried) shows nothing, and i dont understand why...

    initially I tried reading the record into a standard variable length string, but sorting thru Microsoft's Visual Studio Document for visual basic, I read that the string value of a FileGet function needed to be read into a fixed length string... which took me back to the days of quick basic where field statements were required after the open statement and before the Get/Put statement(s) -  these field statements defined both the string variable and its length. Though there is no field statement for Visual Basic Studio, I did try to declare a fixed length variable "DataS". but this still did not work, I tried to insert this declaration just before the fileGet function, but it wouldn't allow it... I also tried to use the "Lset" function just previous to the FIleGet to set a length to the DataS variable, but that didn't work either (I didn't actually think this would work, but i was desperate to try anything!)

    I did check the data file itself, opened it in word pad and the text was in the file exactly as i entered it (in the textbox during runtime) and the end of the record was at the 128th place, when the file was opened with the program's second run, the label6 text verified the file length of 128, so the FilePut (set with all the same parameters as instructed by the microsoft documentation, and the same as the FIleGet parameters) functioned properly... Hence, i'm at wit's end and totally baffled,  I don't get it... all these things verify the record text is there and the file is open - and all the syntax of all the "file" opperations are correct and working as they should, except the FileGet ... what am i doing wrong? is there something i am missing?

    Other Facts
    Using Visual Studio 2013 Pro
    Using Visual Basic
    Using Windows Forms Application
    Wednesday, July 10, 2019 1:43 AM
  • Hi Diomtus,

    Have you tried to set the "OpenMode" to "Output"? Or, maybe you can achieve writing&read by following this documents.

    Reading from Files in Visual Basic,

    Writing to Files in Visual Basic.

    Besides, this seems to be a totally VB.Net issue. It will be more appropriate to ask your question at Visual Basic.

    Thank you for your understanding.

    Regards,

    Kyle


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 10, 2019 5:24 AM
  • Hi,

    FileSystem.FileGet Method Reads data from an open disk file into a variable. The My feature gives you better productivity and performance in file I/O operations than FileGet,see the following link:

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.filesystem?view=netframework-4.8

    Do you want to read a dat file?try my code:

     Dim fileReader As String
     fileReader = My.Computer.FileSystem.ReadAllText("D:\test.dat")

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Diomtus Monday, July 15, 2019 7:02 AM
    Thursday, July 11, 2019 5:53 AM
    Moderator
  •     well folks... where to begin... Initially I began trying to discover what was going wrong with the FILEGET function (for RANDOM ACCESS data files) ... To presummarize my findings, it seems that the particular syntax i was using, although exactly as documented by microsoft, didn't quite function they way I perceive it was supposed to.
        Below is a short program of what became a result of my research of not only how the function needs to be used (for my specific needs), but also shows how i went about to fix the problem ... fortunately, in my case, the total number of data files I needed to revise wasn't an issue, hopefully, if anyone has a similar dilemma, fixing (converting/revising) old files can be as simple.

    Public Class Form1
    
        Public FdirS As String = "F:\TESTDIRECTORY\SOURCE\"
        Public FdirD As String = "F:\TESTDIRECTORY\DESTINATION\"
        Public Fnam As String
        Public Flen As Long
        Public Fstr As String
        Public Rlen As Integer = 0
        Public Rtot As Integer = 0
        Public Rstr As String
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Label1.Text = "CURRENT SOURCE DIRECTORY IS: " + FdirS
            Label2.Text = "CURRENT DESTINATION DIRECTORY IS: " + FdirD
            Label3.Text = "Enter the FILENAME.EXT to Revise"
            Label4.Text = "Enter the Record Length"
            TextBox1.Text = "" : TextBox2.Text = ""
            Button2.Enabled = False
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TextBox1.Text = "" Or TextBox2.Text = "" Then Exit Sub
            Fnam = Trim(TextBox1.Text) : Label5.Text = "FileName: " + Chr(34) + Fnam + Chr(34)
            Rlen = Val(TextBox2.Text) : Label6.Text = "RecLength: " + Chr(34) + Trim(Str(Rlen)) + Chr(34)
            FileOpen(1, FdirS + Fnam, OpenMode.Random, , , Rlen)
            Flen = LOF(1) : FileClose(1)
            Label7.Text = "Total FileLength: " + Str(Flen)
            Rtot = Flen / Rlen : Label8.Text = "Total Number of Records: " + Str(Rtot)
            If Rtot > 0 Then Button2.Enabled = True
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Label9.Text = "Now Revising " + Fnam
            Fstr = My.Computer.FileSystem.ReadAllText(FdirS + Fnam)
            FileOpen(2, FdirD + Fnam, OpenMode.Random, , , Rlen + 2)
            For Rnum = 1 To Rtot
                Rstr = Mid(Fstr, ((Rnum - 1) * Rlen) + 1, Rlen)
                FilePut(2, Rstr, Rnum)
            Next Rnum
            FileClose(1)
            Label10.Text = Fnam + " Revising Complete"
            Label11.Text = "Enter Next FileName and RecordLength to Revise"
            TextBox1.Text = ""
            TextBox2.Text = ""
            Kill(FdirS + Fnam)
            Button2.Enabled = False
        End Sub
    
        'Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        '    FileOpen(1, Fdir + "GameDataPath.BLN", OpenMode.Random, , , RecLen)
        '    FileOpen(2, Fdir + "GameDataPath.BLN", OpenMode.Random, , , RecLen + 2)
        '    DataS = LSet("Third Record", RecLen) : FilePut(2, DataS, 3) ' FilePut(1, DataS, 3, True)
        '    DataS = LSet("First Record", RecLen) : FilePut(2, DataS, 1) ' FilePut(1, DataS, 1, True)
        '    DataS = LSet("Second Record", RecLen) : FilePut(2, DataS, 2) 'FilePut(1, DataS, 2, True)
        '    If LOF(1) > 0 Then
        '        'FileGet(1, DataS, 2, True) : Label2.Text = Trim(DataS)
        '        'FileGet(1, DataS, 3, True) : Label3.Text = Trim(DataS)
        '        'FileGet(1, DataS, 1, True) : Label1.Text = Chr(34) + DataS + Chr(34)
        '        FileGet(2, DataS, 2) : Label2.Text = Trim(DataS)
        '        FileGet(2, DataS, 3) : Label3.Text = Trim(DataS)
        '        FileGet(2, DataS, 1) : Label1.Text = Chr(34) + DataS + Chr(34)
        '    End If
        '    FileClose(2)
        '    '===== Delete the data file created above and then Close the program ====
        '    Kill(Fdir + "GameDataPath.BLN")
        '    Me.Close()
        'End Sub
    
    End Class
    


        To start with the main issue to be resolved, let's take a look at the syntax I was using initially - If you skip down to the button3 sub (which is completely commented out), you will find, specifically, three functions associated with file number 1 - FileOPEN (line 1), FilePUT (at the end of lines 3,4,5), and FileGET (lines 7,8,9).  The syntax of filenumber1 was, by the documentation, used for what was to be "fixed-length strings".  Notice that the Record length (the last parameter) in the FileOPEN function is set the the same length as the strings that would be placed (or retreived) from the file.  Also notice that the Put and Get functions have a 4th bolean parameter, which is set to TRUE.  According to the documentation, this parameter is used to indicate the record is a fixed length, and therefore, no delimiters are placed between the records.  This is the way the original program created the files (without delimiters).  Long story made short, the OPEN and PUT functions worked just fine, but the GET function would always return a null string.  After doing all kinds of research (trials and errors)... I found that the only way for all three functions to work properly together was to use the syntax that would place a delimiter between each record - this is reflected in the functions associated with file number 2 (in the same button3 sub) - notice the record length of the FileOPEN function (line 2) is set as 2 bytes longer than the records in the PUT and GET functions, this delimiter offset is described in the documentation under the FileGet function.  Also notice that the FilePUT functions (lines 3,4,5) and FileGET functions (lines 10,11,12) only have 3 parameters, the last bolean parameter is omitted, allowing (or causing) delimiters to be placed/read with each record.
        Since this was going to change the format of how the records are stored(read) into(from) the files, the next hurdle was going to be revising the data files that the records were stored in - in my case, the number of files was relatively small, and I knew the type of information each file stored, which means I also knew the record lengths used for each file.  But altering the files manually would take, um, probably years.... one file, for example, has 9,900 records in it... imagine inserting a delimiter between each record manually !!! Hence, the "file revision" program, this is the program your actually looking at above.  Following is a (somewhat) brief discription of how i did this semi-automatic file revision process.

    Declarations = I am pressuming you already know what this part is

    FORM1 LOADER = as you can see, I used this portion to preset text to labels for visual purposes during runtime.  It also nullifies the 2 textboxes to ready them for user input, and disables button2 (the "proceed" button).

    BUTTON1_CLICK = this button is the "evalute" button.  first you enter the name of the file (including extension) you want to revise in textbox1, and then put the record length value in textbox2, then press the evaluate button - this mainly allows you to see all the information on the file to help confirm you entered the 2 pieces of information correctly - if so, the file size and total number of records will also be set in this step.  If the file name entered is incorrect, a zero-length file will be created in the source directory as it was entered, and it will need manual removal.  Finally, if the designated file has the possibility of at least one record, it will allow you to "proceed" with the revision process (enables button2).

    BUTTON2_CLICK = since i cannot use the FileGET function to retrieve records from the old files (without delimiters), I had to use the "ReadAllText" function to read the entire file into a single string, then i used a for...next...loop to read each record out of the file text (using the MID string function) and place it into the new revised file (using FilePUT function with delimiters). After the revision is complete, it closes the new file, deletes the old source file, and resets (re-nullifies) the textboxes for the entry of the next file name and record length value.  [I copied the original files into a temporary source directory, this way if some went awry, the actual original file(s) would still be intact in the original directory.]

    Also, thank you Alex, although your solution idea doesn't quite suit my needs for the program I am developing, it did direct me toward something that really worked well for rewriting all my data files from the previous program into something that will work with the program in current development.

    Hope this information is useful...

    Blain (Diomtus)
    Monday, July 15, 2019 7:05 AM