Counting the lines of text, but upwards...

  • Thread starter Thread starter peraklo
  • Start date Start date
P

peraklo

Hello,

there is another problem i am facing. i have a text file which is
about 15000 lines big. i have to cut the last 27 lines from that file
and create a new text file that contans those 27 lines. and after that
save both of those files... since that is a big block of text (15000
lines) i thint that it is a big job to look for a keyword... so my
question is this exactly:

how do i do this:

- open a existing text file
- go to the end of that file
- count the last 27 lines of text
- cut that 27 lines and paste it into a new text file (so CUT, not
copy from the original file)
- save both files

counting from the beginning is not an option because he original file
is always different... the number 15000 is an approximation...

Thanks in advance...
 
Hello,

there is another problem i am facing. i have a text file which is
about 15000 lines big. i have to cut the last 27 lines from that file
and create a new text file that contans those 27 lines. and after that
save both of those files... since that is a big block of text (15000
lines) i thint that it is a big job to look for a keyword... so my
question is this exactly:

how do i do this:

- open a existing text file
- go to the end of that file
- count the last 27 lines of text
- cut that 27 lines and paste it into a new text file (so CUT, not
copy from the original file)
- save both files

counting from the beginning is not an option because he original file
is always different... the number 15000 is an approximation...

Thanks in advance...

You can't jump around in a text stream, so you would have to open it as
a binary stream. You can read a block of data into a buffer, but you
have to locate the line breaks yourself so that you can decode the bytes
between them into strings.
 
Or just read in the whole file, take off the last 27 lines, then write it
back out. Here's an untested version.

Dim lines() as String = File.ReadAllText("c:\data.txt").Split(crlfs,
StringSplitOptions.None)
Dim numOfLines = lines.Length

Then use WriteAllText to output the data.

Dim newText as String = String.Join(ControlChars.CrLf, lines, 0,
lines.length - 27)
File.WriteAllText("c:\output.txt",newText,False)

Robin S.
Ts'i mahnu uterna ot twan ot geifur hingts uto.
---------------------------------------------------------
 
Read each line of the file into a FIFO queue that is 27 elements deep.
When you get to the end iterate through he stack and write each line out to
the new file.
 
If you do that, don't you just get the 27 lines he wanted removed from the
original file?
Robin S.
--------------------------------
 
If the original author is willing to do a little labor I'd suggest starting
by reading this thread:

http://groups.google.com/group/micr...tleylan+copier+vb+net&rnum=1#127beee5cee8da15

At the end of it I supplied a class named Copier to produce the results
another guy wanted (never heard from him.) But clearly it is a simple
matter to use this class as a starting point adding a method (named Splitter
perhaps) which takes three parameters. Two strings representing the two
parts of the file and a numeric representing the number of lines desired in
the first file.

The Copy method I supplied will copy a fixed number of lines to a file so
the only required adjustment is to open a second file (the parameter
contains the name) and to copy the remaining lines to it. At the end you
have the original file intact along with two new files split at the line
number specified. If it is necessary to specify the number of lines to be
placed in the second file (rather than the first) then simply add another
method that returns the number of lines in the original file and do the math
to calculate how many lines should be written to the first file.

And it appears that I failed to call Dispose() on the FileStreams in that
code so one might want to add that not that it wouldn't work without it.
 
Yeah, I did not read that he also wants to save the lines that are not the
last 27 to another file. In this case I would write a custom FIFO stack that
writes the lines that get pushed off the bottom to a file (so you get the
ones - the 27 that remain in the stack) and then write the ones left in the
stack to another file :)
 
Hello,

there is another problem i am facing. i have a text file which is
about 15000 lines big. i have to cut the last 27 lines from that file
and create a new text file that contans those 27 lines. and after that
save both of those files... since that is a big block of text (15000
lines) i thint that it is a big job to look for a keyword... so my
question is this exactly:

how do i do this:

I provided a reply in March 2006 to another person with a similar
request, and while I didn't intend to write your entire solution, I have
done just that below (watch for line-wrapping) -

Dim blPossibleEOL As Boolean = False
Dim byTemp As Byte = 0
Dim iFileNum As UInt16 = FreeFile()
Dim sInputFileName As String = "YOUR INPUT FILENAME HERE!!"
Dim sTextLines As String = ""
Dim iCounter As UInt16 = 0

Dim iFileEnd As Integer = FileLen(sInputFileName) - 2
Dim iFileSeekPosition As Integer = iFileEnd
FileOpen(iFileNum, sInputFileName, OpenMode.Binary, OpenAccess.Read)

Do
FileGet(iFileNum, byTemp, iFileSeekPosition)
If blPossibleEOL Then
If byTemp = &HD Then
iCounter += 1
If iCounter = 27 Then 'Change this for whatever number of lines
you are wanting.
Exit Do
Else
blPossibleEOL = False
End If
Else
blPossibleEOL = False
End If
ElseIf byTemp = &HA Then
blPossibleEOL = True
Else
blPossibleEOL = False
End If
iFileSeekPosition -= 1
Loop

sTextLines = StrDup(iFileEnd - (iFileSeekPosition + 1), " ")
FileGet(iFileNum, sTextLines, iFileSeekPosition + 2)
FileClose(iFileNum)

My.Computer.FileSystem.WriteAllText("CUT-LINES OUTPUT FILENAME HERE!!",
sTextLines, False)

Dim srInput As New IO.StreamReader(sInputFileName)
Dim srOutput As New IO.StreamWriter("TRIMMED-LINES OUTPUT FILENAME HERE!!")

iFileEnd = iFileSeekPosition
iFileSeekPosition = 0
Do
sTextLines = srInput.ReadLine
srOutput.WriteLine(sTextLines)
iFileSeekPosition += (Len(sTextLines) + 2)
Loop Until iFileSeekPosition >= iFileEnd

srInput.Close()
srOutput.Close()

'Kill(sInputFileName)


I have tested this with a 200,000 line Text File and the files were
created almost instantly!

Basically, it works like this -

The first loop opens your Input File (Binary Read Mode), and starting
from the end of the file, counts the number of lines you are wanting to
cut. (iCounter = 27 in this case). It does this by counting the CrLf
characters in your text file. This approach has a tremendous speed
advantage as it doesn't have to count ALL of your Input File lines from
the beginning.

Once it has reverse-counted the number of lines you are wanting, it
notes the current file (byte) position, reads the lines from that
position until the end of the file into a string and writes-out those
lines to your new file. You now have a file with just the number of
lines that you required to be cut.

It then opens your Input File in a StreamReader and starts reading line
by line in the second loop. As each line is read, it is written to
another file, which will eventually contain everything except the last
few lines you want cut. It knows when to stop writing by matching the
number of characters read so far (allowing extra 2 bytes for CrLf on
each line) to the original Seek Position obtained earlier.

As already mentioned, this routine is VERY fast, not necessarily pretty,
but fast!

I would encourage you to add error-handling etc., but I trust this gives
you a strong foundation to work from.


ShaneO

There are 10 kinds of people - Those who understand Binary and those who
don't.
 
Back
Top