Solved

Unread a Line

Posted on 2002-06-19
14
241 Views
Last Modified: 2010-05-02
I have a sequential file open and using Line Input to read from it. Is there a way to "unread" a line in any way, so it can be Line Inputted again?

Thanks
0
Comment
Question by:afterburner
  • 5
  • 5
  • 4
14 Comments
 
LVL 22

Expert Comment

by:rspahitz
ID: 7093415
The only way I know is to either close the file and re-open, then read that many characters, or use a binary open.  With a binary open, you can read any character string you want, but you have to parse it yourself to determine where the end of line is located.

BUT--Why not just store the line input string and use it whenever you need it?
0
 

Author Comment

by:afterburner
ID: 7093435
Well its someone else's code and at the moment when it reads a file it uses a blank line in that file to signal the end of the reading for that particular section. I want it to use the flag line that starts the next section in the file being read to signal the end of the current section. Unfortunately, by the time this has been read in, the next routine which deals with the next section of the file has had its starting reference stolen by doing it this way, and there are several similar routines following along behind which read other sections of the file.
0
 
LVL 22

Accepted Solution

by:
rspahitz earned 50 total points
ID: 7093487
Ouch...weak or overly patched design.

Again, the only way I know is to close the file, re-open it, and jump ahead to that part of the file.
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
LVL 8

Expert Comment

by:DennisBorg
ID: 7094809
This is NOT the recommended way to process a file. To reread certain portions of the file can have a dramatic negative effect on efficiency.

However, you could always record the file position BEFORE reading the line, and if you need to reread that line, reposition the file pointer to the beginning of that line.

For example, assuming the following:

   Dim hFile   As Integer
   Dim FPos    As Long
   Dim strLine As String

   hFile = FreeFile()
   Open "somefile" For Input As #hFile
   FPos = Loc(hFile) 'Record the current file position
   'Read a line of text from the file
   Line Input #hFile, strLine
   Seek #hFile, FPos 'Set file pointer back to start of line
   'ReRead the same line again:
   Line Input #hFile, strLine
   Close #hFile


Again, to reread certain portions of the file is not the recommended course of action. But this is how you would go about doing so.

0
 

Author Comment

by:afterburner
ID: 7095156
Hi DennisBorg
>Seek #hFile, FPos 'Set file pointer back to start of line

This would be the way I would do it too. But as I understand it, you cant access sequential files by byte positioning with Seek - you can only do that with Binary and Random access(?) But please correct me if I am wrong.
0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 7095707
  >as I understand it, you cant access sequential
   >files by byte positioning with Seek - you can
   >only do that with Binary and Random access(?)
   >But please correct me if I am wrong.

Before submitting my solution, I tried it out to make sure it would work with files opened in INPUT mode; and it worked just fine for me.
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 7096579
Yes.  I think there USED to be an issue/difference with files open for INPUT, BINARY or RANDOM ACCESS.  It seems that they all now support the same command set (although I haven't verified this.)
0
 

Author Comment

by:afterburner
ID: 7096692
> It seems that they all now support the same command set (although I haven't verified this.)


I forgot to mention that I am working back in VB 5, not 6 or later. Would I need to go to 6 to get that feature then?
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 7096700
I think it was the same in 5, but you should be able to try a simple experiment to find out.  Just use DennisBorg's example above on a test file.

0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 7097638
  >I think it was the same in 5, but
   >you should be able to try a simple
   >experiment to find out.  Just use
   >DennisBorg's example above on a test file.

I concur; to be certain, try it out on a test file. You could read the first 5 lines, and then try to read and reread the 6th line.

Be sure to let us know how it turns out.
0
 

Author Comment

by:afterburner
ID: 7098272
The submitted solution does not work because fpos will return a byte position that is either random or based on the number of reads.

The only way to do this is to capture the length of the input lines and THEN do a Seek hFile, total_len_of_all_read_strLines.

Doing this, you have to add 2 for each read to allow for CR & LF.

OK, but this does not make use of Seek to read the position, only to set it. It cant be read usefully from a seq. file so you need to track string lengths. This isnt so clever because blank lines wtih CR LFs will cause a lot of pain.

0
 
LVL 22

Expert Comment

by:rspahitz
ID: 7099094
I'd have to say that the request for unreading a line cannot be done.  Anything we offer will be a workaround, and likely a weak one because it tries to overcome a design flaw.

The real answer is to rewrite the offending component rather than to try to write a complex work-around.

(I'm sure that's not what you want to hear, but ultimately it will save you time and reduce future changes that add to the confusion.)
0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 7102157
  >The submitted solution does not work
   >because fpos will return a byte position
   >that is either random or based on the
   >number of reads.
   >
   >The only way to do this is to capture the
   >length of the input lines and THEN do a
   >Seek hFile, total_len_of_all_read_strLines.
   >
   >Doing this, you have to add 2 for each read
   >to allow for CR & LF.

This does not make sense to me. You would not have to calculate the length of each line at all. Neither does the LOC() function return a random number.

If the file is opened in Random Access mode, LOC() returns the record number of the most recent record that was read/written to the file.

If the file is opened Binary mode, LOC() returns the position of the last byte read or written.

If the file is opened in Sequential mode, LOC() returns the current byte position divided by 128.

The whole idea was to bookmark the CURRENT FILE POSITION *BEFORE* reading the line the first time. THEN read the line. If you should *then* realize you need to reread that same line, then simply return to your already-recorded position (by using Seek).


You would actually want to open the file in BINARY mode, instead of in SEQUENTIAL mode (OPEN FOR FOR INPUT opens the file for sequential access)


Find a text file (or make one) that has more than 300 lines of text in it. You will have to change the "C:\NetLog.txt" to the actual name of your file.

Then try the following code:

   Dim hFile As Integer
   Dim FPos  As Long
   Dim Buff  As String
   Dim Index As Long
   
   hFile = FreeFile() 'Get next available file handle
   Open "C:\NetLog.txt" For Binary As #hFile

   'Read the first 299 lines
   For Index = 1 To 299
      Line Input #hFile, Buff
   Next 'Index
   
   'Bookmark the 300th line BEFORE reading it:
   FPos = Loc(hFile) + 1

   'Read the 300th line for the FIRST time:
   Line Input #hFile, Buff
   MsgBox Buff '<--- Display the 300th line

   'Read the 300th line 9 more times:
   For Index = 1 To 9
      'Move the file pointer to the beginning
      'of the 300th line
      Seek #hFile, FPos
      'Read the 300th line again:
      Line Input #hFile, Buff
      MsgBox Buff '<--- Display the 300th line
   Next 'Index

   Close #hFile 'Close the file


Each time, the very same line is reread and displayed. Calculating the total length of all preceeding lines is not necessary.

0
 

Author Comment

by:afterburner
ID: 7103132
I did ask for a solution to this when the file was open in sequential mode, however I admit I did not appreciate that it is possible to open a file in binary and then make sequential reads from it. If I had known it was that easy then I would have done it already.

The code I actually needed goes like this:


Private Sub Command1_Click()

  Dim hFile As Integer
  Dim FPos  As Long
  Dim Buff  As String
   
  hFile = FreeFile()
  Open "C:\somefile.txt" For Binary As #hFile

 
  Do While Buff <> "this line is the one I want to read again"
 
     
     Line Input #hFile, Buff
     FPos = Loc(hFile)
     
 
  Loop
 
 
     MsgBox Buff
     Seek #hFile, FPos - Len(Buff) - 1
     Line Input #hFile, Buff
     MsgBox Buff

  Close #hFile

End Sub


working on this file (c:\somefile.txt) as an example:

this is line number one
this is line number two
this is line number three
this is line number four
this is line five
this line is the one I want to read again
this is line seven
this is line number eight
0

Featured Post

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

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…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

773 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