Page 1 of 1

Retrieve a specific number of lines with TextInputStream

Posted: Sun Jan 19, 2025 6:50 pm
by Mr.Dandy
Hello,

I know retrieve the number of lines but I can't position myself in the file.

Code: Select all

Sub Main
	iStart = 3
	iLines = 5
	aData = ReadFile("c:\temp\foo.txt", iStart, iLines)
	oDoc = ThisComponent 
	oRange = oDoc.Sheets(0).getCellRangeByName("A1:A" & iLines)
	oRange.DataArray = aData
End Sub

Function ReadFile(sUrl as string, _
					optional nStart as long, _
					optional nLines as long)
   if not FileExists(sUrl) then 
   		msgbox("File not found:" & chr(10) & sUrl)
   		exit function
   endif
   oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
   oTIS = createUnoService("com.sun.star.io.TextInputStream")
   
   oFile = oSFA.openFileRead(sUrl)
   oTIS.InputStream = oFile
   i = 0
   Dim aRet(i)
   Do while not oTIS.isEOF
   		if i = nLines then exit do 		
   		Redim Preserve aRet(0 to i)
        aRet(i) = array(oTIS.readLine)
        i = i + 1
   Loop
   oTIS.closeInput
   ReadFile = aRet
End Function
foo file content:

Code: Select all

ali
ben
cal
don
eli
fox
gin
hal
iso
jon
kab
leo
max
neo
oli
pat
qin
rob
sal
teo
ubi
vic
won
xeo
yes
zoe
So, I try to get cal to gin

Thanks

Re: retrieve a specific number of lines with TextInputStream

Posted: Sun Jan 19, 2025 8:04 pm
by JeJe
Using MRI on the TextInputStream there are skipbytes and readbytes methods.

Re: Retrieve a specific number of lines with TextInputStream

Posted: Sun Jan 19, 2025 9:10 pm
by karolus
Hallo

Code: Select all

def main(*_):
    doc = XSCRIPTCONTEXT.getDocument()
    skip, read = 3,  5
    output_range = doc.Sheets[0][:read, 0]
    
    with open("ali.txt") as ali:
        for _ in range(skip-1):
            next(ali)
        out = [[next(ali).strip()] for _ in range(read)]
    output_range.DataArray = out

Re: Retrieve a specific number of lines with TextInputStream

Posted: Mon Jan 20, 2025 12:50 am
by Lupp

Code: Select all

Sub Main
	iStart = 3
	iLines = 5
	aData = ReadFile(ConvertToURL("c:\temp\foo.txt"),iStart, iLines)'"c:\temp\foo.txt", iStart, iLines)
	oDoc = ThisComponent 
	oRange = oDoc.Sheets(0).getCellRangeByName("A1:A" & iLines)
	oRange.clearContents(23)
	oRange.setDataArray(aData) REM The relevant error: You can't ASSIGN the DataAddray. It must be set.
End Sub

Function ReadFile(sUrl as string, _
					optional nStart as long, _
					optional nLines as long)
   if not FileExists(sUrl) then 
   		msgbox("File not found:" & chr(10) & sUrl)
   		exit function
   endif
   oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
   oTIS = createUnoService("com.sun.star.io.TextInputStream")
   oFile = oSFA.openFileRead(sUrl)
   Dim sLine As String, aRet(nLines - 1)
   oTIS.InputStream = oFile
   For i = -nStart + 1 To nLines - 1
    If oTis.isEOF Then
     ReadFile = aREt  
     Exit Function
    EndIf
    sLine = otis.readLine
    If i>=0 Then aRet(i) = Array(sLine)
   Next i
  oTIS.closeInput
 ReadFile = aRet
End Function

Re: retrieve a specific number of lines with TextInputStream

Posted: Tue Jan 21, 2025 7:51 pm
by Mr.Dandy
JeJe wrote: Sun Jan 19, 2025 8:04 pm Using MRI on the TextInputStream there are skipbytes and readbytes methods.
Yes but bytes is not line, I can't to know how lenght each line do :)

Re: Retrieve a specific number of lines with TextInputStream

Posted: Tue Jan 21, 2025 10:20 pm
by Lupp
The code I posted above (the foofile path pointing to the real file, of course) worked perfectly for me in AOO V 4.1.7. Did you (@Mr.Dandy) check and test it?

Re: retrieve a specific number of lines with TextInputStream

Posted: Tue Jan 21, 2025 10:37 pm
by JeJe
Mr.Dandy wrote: Tue Jan 21, 2025 7:51 pm Yes but bytes is not line, I can't to know how lenght each line do :)
The bytes are read one at a time in sequence until the whole file is read. OO or LO doesn't know about lines either unless it reads them in sequence from the start.

If you want to jump to specific lines (Edit: without reading them in in sequence from the start] then you have to make them all the same length (length of the biggest) when you write them to the file in the first place so you can calculate the position of any line.

Alternatively you could store all the lengths of the lines somewhere when you write them to the file, perhaps in a separate document or as a kind of header at the start of the file to be read first.

Re: Retrieve a specific number of lines with TextInputStream

Posted: Tue Jan 21, 2025 10:42 pm
by Lupp
Wanting to start actual reading/evaluation with line number n it's a simple and fast way to read n - 1 lines to get the position and to ignore the contents.

Re: Retrieve a specific number of lines with TextInputStream

Posted: Tue Jan 21, 2025 10:53 pm
by Lupp
The largest .txt I have on my computer has >5 MiByte and 33099 lines.
To read (and show in a spreadshee) lines No 30001 through 30005 with above code took <1.5 s.
(1.393175 s)
Sorry. There was a silly mistake. The correct time is 1.07000 s.