[Closed] stringStream Backwards
I need to read a stringStream Backwards line by line, someone knows how? I’m getting crazy with this…
thanks in advance.
You could read it forwards, line by line, store each line as elements of an array, and then loop through the array backwards ?
The problem is that i’m trying to read it backwards because i need to reach a value that is about the end of a file with hundred of thousands of lines. The time i spend reading line by line is too long so i would like to do it from the end.
thanks anyway for the reply
in my experience always better to use skipToString method then read fileStream or StringStream lines in backward order…
(
ss -- stringStream
sub -- searching substring
if (p = skipToString ss sub) != undefined do
(
str = sub + (readline ss) -- searching string
)
)
it’s a fastest way…
an easy solution for this, and not the optimal, could be to filter the string using ‘filterString’
with the new line char as the filter “
“,
then you have an array of lines and you can loop through it backwards with
for i = filteredLines.count to 1 by -1 do
...
I’ve found a way that is faster tahn skipToString, in the case yo know that the string you want to search is near the end of the file.
(
fileName = "C:\\asdf\\asdf\\asdf.extension"
startTime = timeStamp()
f = openFile fileName mode:"r"
maxlen = 0
if f != undefined then --if file is correctly opened
(
seek f #eof
maxlen = filepos f
aux = 0
stop = false
i = 1
while not stop and i < maxlen do--maxlen do
(
seek f (maxlen - i - aux)
char = readChar f
if (char == "
") then
(
if (i==1) then seek f (maxlen - i - aux)
currentLine = (readLine f)
aux = 1
if findString currentLine "stringToFind" != undefined then
(
stop = true
seek f (maxlen - i - aux)
endTime = timeStamp()
print ((endTime - startTime)/1000.0)
)
)
else
aux = 0
if (maxlen - i) == 0 then
stop = true
i+= 1
)
close f
)
endTime = timeStamp()
print ((endTime - startTime)/1000.0)
print "-----------------"
)
it only works in very special cases. It can’t be faster in common case because read by char is much slower then read by line. Check the sample that I made:
fn createSkipFile len:200000 pos:0.85 =
(
if not (doesfileexist "c:/temp") do makeDir "c:/temp"
file = "c:/temp/skipfile.txt"
index = len*pos
if (ss = createfile file) != undefined do
(
other = "\"Everything takes longer than it takes.\" (Jon Carpenter)"
for i=1 to len do
(
format "%
" (if i == index then "String To Find --------------------> is Here" else other) to:ss
)
flush ss
close ss
-- edit file
)
)
fn forwardSkipString sub:"String To Find" =
(
t1 = timestamp()
if doesfileexist (file = "c:/temp/skipfile.txt") and (ss = openfile file) != undefined do
(
if (p = skipToString ss sub) != undefined do
(
str = sub + (readline ss) -- searching string
)
flush ss
close ss
)
format "done: % %
" ((timestamp() - t1)/1000.) str
str
)
fn backwardSkipString sub:"String To Find" =
(
t1 = timestamp()
if doesfileexist (file = "c:/temp/skipfile.txt") and (ss = openfile file) != undefined do
(
seek ss #eof
maxlen = filepos ss
aux = 0
stop = false
i = 1
while not stop and i < maxlen do
(
seek ss (maxlen - i - aux)
char = readChar ss
if (char == "
") then
(
if (i==1) do seek ss (maxlen - i - aux)
str = readLine ss
aux = 1
if findString str sub != undefined do
(
stop = true
seek ss (maxlen - i - aux)
)
)
else aux = 0
if (maxlen - i) == 0 then stop = true
i+= 1
)
if not stop do str = undefined
flush ss
close ss
)
format "done: % %
" ((timestamp() - t1)/1000.) str
str
)
i’m making 200000 lines file with “string to find” in 85% position of it. If you set the string in 70% e.g. the difference between forward and backward methods will be huge!
Yes you are right at all, but i was trying to find my way because i have files of hundreds of thousand lines and i know the information i’m looking for is about at 99% of it. In most cases this information is in the last 100 lines, so i’ll use my method this time, but i’ll keep in mind “skipToString” for the general cases.
Thank you for your reply again, and for your time.
you can modify forward search using skipping part of file
fn forwardSkipString sub:"String To Find" skip:0.9 =
(
t1 = timestamp()
if doesfileexist (file = "c:/temp/skipfile.txt") and (ss = openfile file) != undefined do
(
if skip != unsupplied do
(
seek ss ((getfilesize file)*skip)
)
if (p = skipToString ss sub) != undefined do
(
str = sub + (readline ss) -- searching string
)
flush ss
close ss
)
format "done: % %
" ((timestamp() - t1)/1000.) str
str
)