file_read_line
a_riot42
AMX Wizard
I tried to use file_read_line today, and noticed a problem. I haven't used it for a long time, likely prior to the NX series coming out, so I wonder if it changed. Its supposed to keep reading a line from a file until hitting EOF. However, when I used it on a file with a few blank lines (crlf only) scattered throughout, as soon as it hits one, it returns nothing, and stops. I had thought that it kept moving the file pointer to the byte after the last line until EOF is found, but it stopped long before EOF. The third line in my file is a blank line with just crlf, and that seems to stop it and reset the pointer. This is pretty much a useless function if its going to do that. It also removes the newline from the returned string which is a little odd, but I can deal with that. Anyone had any experience with this builtin function?
An interesting aside is that sending the strings from the file to a touch panel, the crlf also shows up on the touch panel. There is no need to send '|' to create a new line, as crlf does the same thing, at least on my iPad. However, I actually need to send the pipe character '|' to the touch panel, but I can't since it is interpreted as a newline. Apparently there is no way to send the pipe character to a touch panel due the interpretation of it as a newline, which isn't even needed since crlf works just as well. I can add a pipe character to a button though and it shows up as a pipe character. Anyone know how to send a pipe character to a touch panel?
Paul
An interesting aside is that sending the strings from the file to a touch panel, the crlf also shows up on the touch panel. There is no need to send '|' to create a new line, as crlf does the same thing, at least on my iPad. However, I actually need to send the pipe character '|' to the touch panel, but I can't since it is interpreted as a newline. Apparently there is no way to send the pipe character to a touch panel due the interpretation of it as a newline, which isn't even needed since crlf works just as well. I can add a pipe character to a button though and it shows up as a pipe character. Anyone know how to send a pipe character to a touch panel?
Paul
Comments
-
If I'm reading your post correctly the answer is, as I understand it, File_Read_Line has always stopped at a the end of a line. (or to the EOF if on the last line)
It's just Read_FIle that does as you describe.
Here's the blurb from the help file.Remarks:
This function reads from the current location of the file pointer up to the next carriage return or to the end-of-file (EOF), whichever comes first. A complete line will not be read if the buffer length is exceeded before a carriage return (or EOF) is encountered. The bytes are read from the file identified by HFile and are stored in Buffer. The <CR> or <CR><LF> pair will not be stored in Buffer. If a complete line is read, the file pointer is advanced to the next character in the file after the <CR> or <CR><LF> pair or to the EOF if the last line was read.
I do have code running right now on NXs utilizing the command and it hasn't bonked on me.
E -
I use read_line all the time. I have it stuck in a while with the return value from the read_line function as the parameter. I cant recall ever an issue unless it was self-inflicted.
-
read_file is what I am using now, but file_read_line is a function in almost every language, and normally reads through the entire file before resetting the file seek pointer once EOF is found.
As I understood the help file, its supposed to read the file until encountering a CR, and then put the line in the buffer, moving the file seek pointer to the next character in the file in preparation for the next call of file_read_line. But it appears that if you have a newline on its own, its incorrectly interpreted as EOF. So doing a file_read_line on a file with a few blank lines scattered throughout never makes it through the whole file. As soon as a blank line is encountered, further calls to file_read_line returns 0 or no bytes read. So file_read_line can't be used on a file with a blank line in it? That's a fairly useless function, since most text files have a blank line or two. Some even start with one, in which case this function doesn't work at all.
In order to read past a blank line the file must be reopened, file pointer moved to where it left off, and continue. So unless your file has no blank lines, this function is basically useless. I seem to recall using it before and not seeing this behavior so I thought perhaps it changed over time. Currently running FW 1.5.78.
My file contains this:
11:32:07 > Discovery profile: Default discovery profile
11:32:07 > Discovery class: data-link (data-link layer)
11:32:07 > Discovery on: 192.168.1.0/24
11:32:07 > Discovery round starting.
11:32:08 > Discovery progress 25%button_event[vdvTest, 1] { push: local_var sString[512] stack_var slong slFH, slBytesRead slFH = file_open('test.txt', file_read_only) slBytesRead = file_read_line(slFH, sString, 512) while(slBytesRead) slBytesRead = file_read_line(slFH, sString, 512) db("'slBytesRead: ', itoa(slBytesRead)") dbug("'Line read: ', sString") file_close(slFH) } }
This is the ouput:
(13:09:59):: File open result: 2
(13:09:59):: slBytesRead: 55
(13:09:59):: Line read: 11:32:07 > Discovery profile: Default discovery profile
(13:09:59):: slBytesRead: 57
(13:09:59):: Line read: 11:32:07 > Discovery class: data-link (data-link layer)
(13:09:59):: slBytesRead: 45
(13:09:59):: Line read: 11:32:07 > Discovery on: 192.168.1.0/24
(13:09:59):: slBytesRead: 36
(13:09:59):: Line read: 11:32:07 > Discovery round starting.
(13:09:59):: slBytesRead: 0
(13:09:59):: Line read:
(13:09:59):: Line read:
The line after the CRLF on its own, "11:32:08 > Discovery progress 25%" is never read.
If I insert a newline as the first line, I don't get anything in the buffer.
Paul -
This is the way I would have done it:
button_event[vdvTest, 1] { push: { local_var sString[512] stack_var slong slFH, slBytesRead slFH = file_open('test.txt', file_read_only) IF( slFH > 0 ) { slBytesRead = 1 //Allow it to go into the while at least once while( slBytesRead > 0 ) { slBytesRead = file_read_line(slFH, sString, 512) db("'slBytesRead: ', itoa(slBytesRead)") dbug("'Line read: ', sString") } file_close(slFH) } } } -
That's out of the help file example, and the only difference is seeding the result to get into the while loop. Does your code work after a line with CRLF appears on its own? In other words, two CRLFs in a row?
Paul -
I'll confirm tomorrow morning, I was thinking I should have probably tested that before i posted.
-
Paul, your absolutely right man, two in a row makes it think its EOF
-
Are you in control of the text file that your reading from? If so what I do when im reading lets say a config file any comments i put or for easier readability i put // and when I am reading in the data anything with a // I just ignore.
-
This seemed like very strange behavior, so I checked the definition in NetLinx help. FILE_READ_LINE returns >= 0 on success, and a few negative values for failure (-9 for when EOF is reached). So your WHILE loop should be:
while(slBytesRead >= 0) { // stuff }
I don't have an NX processor to test with, but with my NI, blank lines with only a CRLF return 0 and I can read several in succession without FILE_READ_LINE saying I've hit EOF. I don't think I've ever noticed that it doesn't count CRLF's in the result. I must have lucked out and never had to loop over any blank lines. -
Good catch KeIL!
Just tested it out on my offices NX, i have three CR_LF's in a row and no problem.Line 295 2017-05-03 (15:35:04):: CONFIG READ: Source 4: ControlIPPort- Line 296 2017-05-03 (15:35:04):: CONFIG READ: Source 4: ControlLogin- Line 297 2017-05-03 (15:35:04):: CONFIG READ: Line 298 2017-05-03 (15:35:04):: CONFIG READ: Line 299 2017-05-03 (15:35:04):: CONFIG READ: Line 300 2017-05-03 (15:35:04):: CONFIG READ: Source 4: ControlPassword- Line 301 2017-05-03 (15:35:04):: CONFIG READ: //Power Off Line 302 2017-05-03 (15:35:04):: CONFIG READ: Source 5: SourceChannel-99
-
This seemed like very strange behavior, so I checked the definition in NetLinx help. FILE_READ_LINE returns >= 0 on success, and a few negative values for failure (-9 for when EOF is reached). So your WHILE loop should be:
while(slBytesRead >= 0) { // stuff }
I don't have an NX processor to test with, but with my NI, blank lines with only a CRLF return 0 and I can read several in succession without FILE_READ_LINE saying I've hit EOF. I don't think I've ever noticed that it doesn't count CRLF's in the result. I must have lucked out and never had to loop over any blank lines.
That must be it. I guess what it does is it removes the crlf prior to returning the bytes read which is a little counterintuitive. Therefore, if that is the only thing on that line, it returns 0 as the bytes read, even though it obviously read them. I had thought that it would have returned a positive integer since it has to read the crlf, but I guess since its removed, its not counted as part of the bytes read. I'm still confused why it removes the crlf, since in my case I need them, and now have to add it back. Nonetheless, at least using file_read_line instead of file_read takes care of advancing the read pointer automatically which is what I wanted. I am now slurping the whole file using file_read, but that can be slow with big files so this is a better alternative for what I am doing.
Thanks for taking a second look!
Paul
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums
