Retrieve a specific number of lines with TextInputStream

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
User avatar
Mr.Dandy
Posts: 457
Joined: Tue Dec 11, 2012 4:22 pm

Retrieve a specific number of lines with TextInputStream

Post 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
Attachments
test_macro.ods
(9.03 KiB) Downloaded 6 times
OpenOffice 4.1.12 - Windows 10
JeJe
Volunteer
Posts: 2978
Joined: Wed Mar 09, 2016 2:40 pm

Re: retrieve a specific number of lines with TextInputStream

Post by JeJe »

Using MRI on the TextInputStream there are skipbytes and readbytes methods.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
karolus
Volunteer
Posts: 1204
Joined: Sat Jul 02, 2011 9:47 am

Re: Retrieve a specific number of lines with TextInputStream

Post 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
AOO4, Libreoffice 6.1 on Rasbian OS (on ARM)
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 24.8… flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
User avatar
Lupp
Volunteer
Posts: 3638
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Retrieve a specific number of lines with TextInputStream

Post 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
On Windows 10: LibreOffice 24.8.3 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
User avatar
Mr.Dandy
Posts: 457
Joined: Tue Dec 11, 2012 4:22 pm

Re: retrieve a specific number of lines with TextInputStream

Post 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 :)
OpenOffice 4.1.12 - Windows 10
User avatar
Lupp
Volunteer
Posts: 3638
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Retrieve a specific number of lines with TextInputStream

Post 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?
On Windows 10: LibreOffice 24.8.3 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
JeJe
Volunteer
Posts: 2978
Joined: Wed Mar 09, 2016 2:40 pm

Re: retrieve a specific number of lines with TextInputStream

Post 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.
Last edited by JeJe on Tue Jan 21, 2025 10:45 pm, edited 1 time in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Lupp
Volunteer
Posts: 3638
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Retrieve a specific number of lines with TextInputStream

Post 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.
On Windows 10: LibreOffice 24.8.3 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
User avatar
Lupp
Volunteer
Posts: 3638
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: Retrieve a specific number of lines with TextInputStream

Post 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.
On Windows 10: LibreOffice 24.8.3 and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
Post Reply