[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to Read a File Backwards?

Posted on 1998-06-28
7
Medium Priority
?
266 Views
Last Modified: 2010-05-03
I would like to Open a file, and read it backwards! How?
The file is regular text, no records with comma's or anything like that.
And, the text is much too big to use an Array to hold it all.

This is my problem:
I'm using a text artical as a Key in an encryption scheme. I would like the User to be
able to use the Key text backwards if they like. But I can't find a GOOD way to do this.
The text could be a complete novel or book. There is no way to use an Array to hold
it all. It must be read one line at a time, starting from the last line, without using
an Array or memory to store the whole text. The text is just regular text with no
comma's or seperation characters.
Any ideas?
0
Comment
Question by:jgore
  • 3
  • 2
  • 2
7 Comments
 
LVL 2

Expert Comment

by:seahpc
ID: 1464491
You can try this : Read the text, then write to a listbox .

open "c:\text.txt" for input as #1
do until eof(1)
     line input #1, record
     list1.additem record
loop
Close #1

index=  List1.listcount

while index > 0
         msgbox List1.List(index)
index = index + 1
wend
0
 
LVL 2

Expert Comment

by:seahpc
ID: 1464492
sorry it sould be index = index - 1
0
 

Author Comment

by:jgore
ID: 1464493
I don't think thats what I had in mind. It still puts the whole thing in memory
somewhere. A listbox is in memory I think. I don't think it could contain the
novel "War and Peace"!
I need to read the file backwards "one line at a time."
I think using a listbox would be just as bad as using an array.

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Accepted Solution

by:
alamo earned 400 total points
ID: 1464494
I don't see a solution other than opening the file at the end and moving back to the beginning, doing your own parsing into lines.

This isn't so tough to do, really - I'll post full code to do it as a comment within the next ten minutes. Hope this will do what you need... good luck!
0
 
LVL 6

Expert Comment

by:alamo
ID: 1464495
Global:

Dim strBuffer As String
Dim lFileOffset As Long
' BufferLength MUST be a power of 2 to work
Private Const BufferLength As Integer = 512

Private Sub Command1_Click()
    ' test program
    Dim iFile As Integer
    Dim strLine As String
    iFile = OpenBackwards("c:\autoexec.bat")
    Do
        strLine = ReadBackwards(iFile)
        If Len(strLine) = 0 Then Exit Do
        ctr = ctr + 1
        Debug.Print strLine;
    Loop
    Close iFile
End Sub

Public Function OpenBackwards(fname$) As Integer
' Opens the file for backwards read
' returns the file number if successful
' Caller must make sure the file exists before calling us
' We set the global variables lFileOffset and strBuffer
    Dim iFile As Integer
    iFile = FreeFile
    Open fname$ For Binary As #iFile
    lFileOffset = LOF(iFile)
    If lFileOffset = 0 Then
        Close iFile
        OpenBackwards = 0
        Exit Function
    End If
    ' Read in final block of file to "prime the pump"
    lFileOffset = (lFileOffset - 1) And Not BufferLength - 1
    strBuffer = Space$(LOF(iFile) - lFileOffset)
    Get #iFile, lFileOffset + 1, strBuffer
    ' After this we read BufferLength bytes at a time, for efficiency
    OpenBackwards = iFile
    If lFileOffset = 0 Then strBuffer = Chr$(13) + strBuffer
End Function

Public Function ReadBackwards(iFile As Integer) As String
' return the last unread line of the file (including the CR, and LF if present)
' when no more lines in the file we return a blank string
Dim strBuffer1 As String
Dim i, j, k As Integer
    ' First look in our buffer to see if there's a line there
    Do
        i = InStr(strBuffer, Chr$(13))
        If i > 0 Then
            j = InStr(i + 1, strBuffer, Chr$(13))
            If j > 0 Then
                Do
                    k = InStr(j + 1, strBuffer, Chr$(13))
                    If k = 0 Then
                        ' last one we found was last line, return it to caller
                        If Mid$(strBuffer, i + 1, 1) = Chr$(10) Then i = i + 1
                        ReadBackwards = Mid$(strBuffer, i + 1)
                        strBuffer = Left$(strBuffer, i)
                        Exit Function
                    End If
                    i = j
                    j = k
                Loop
            End If
        End If
        ' we need to read more of file
        If lFileOffset > 0 Then
            lFileOffset = lFileOffset - BufferLength
            strBuffer1 = Space$(BufferLength)
            Get #iFile, lFileOffset + 1, strBuffer1
            strBuffer = strBuffer1 + strBuffer
            If lFileOffset = 0 Then strBuffer = Chr$(13) + strBuffer
        Else
            ReadBackwards = Mid$(strBuffer, 2)  ' this is in case no cr on last line
            strBuffer = ""
            Exit Function
        End If
    Loop
End Function
0
 
LVL 6

Expert Comment

by:alamo
ID: 1464496
I wouldn't normally code the whole thing for a question here, but it's an interesting little problem to do it efficiently. After the very first read (which reads the very end of the file) it's reading backwards through the file 512 bytes at a time, with all reads aligned with the file block boundaries so it's reasonably quick.

It could use a little more error checking (for opening the file for example) but everyone does that their own way, so no real point adding it, you can do so :-)
0
 

Author Comment

by:jgore
ID: 1464497
Thanks!
I tried it and it worked!
I really thought there might be an easier way, like maybe I had missed
learning some command, or built-in function. Guess not!
Anyways, your code is pretty small and works great!
Thanks again!


0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses
Course of the Month19 days, 8 hours left to enroll

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question