Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

@FileRead from a device issues...

May
855
0
Here's the situation: I want to read one character at a time from a device (such as "CON:", and this is important, "COM1:"; and while "InKey" will (implicitly) work for CON:, it will only work for CON: as far as I can tell). And I would have thought that the following code would work:
Code:
@Echo Off
SetLocal
Set Handle=%@FileOpen[CON:,r,b]
Set Char=%@FileRead[%Handle,1]
Do While "%Char" != "**EOF**"
   @EchoS %Char
   Set Char=%@FileRead[%Handle,1]
EndDo
EndLocal
Quit 0
But I would have been wrong. The above "@FileRead" function "buffers" the input until a carriage return/line feed (which I found rather surprising because this true despite the fact that the console is being opened in "binary" mode where I thought that cr/lf sequences would be totally irrelevant) or end-of-file (Ctrl-Z on the console).

Here's a sample of what I mean (the above batch file has been modified slightly by adding a character counter and outputting every character on a single line preceded by the value of the counter):
Code:
  Sun  Feb 26, 2012  10:19:31p
TCC  13.03.46  Windows 7 [Version 6.1.7601]
Copyright 2012 JP Software Inc.  All Rights Reserved
Registered to Daniel Mathews
[Z:\]CD Demo
[Z:\Demo]Demo
abcdef
1: a
2: b
3: c
4: d
5: e
6: f
7:
8:
^Z
[Z:\Demo]
Now I have no way to test this on a com: port on this machine (i.e., I have nothing that can be plugged into the com: port that "outputs" data) to see if it works for "COM:" (but not "CON:"), but unless I can find a way to truly read a character at a time from a device I can't proceed further in what I was attempting to accomplish.

- Dan
 
WAD. @FILEREAD calls the Windows ReadFile API, and if you're reading from CON:, Windows won't send anything to ReadFile until a line has been entered in the console keyboard buffer.

If you want to read / write individuals bytes from / to COMn:, you're going to need an external app (or a custom file system driver).
 
Thanks, Rex, that is kind of what I expected (rhetorical question: Why a carriage return/line feed? After all, there's no guarantee that arbitrary binary data ("b" mode) will have those), so much so that I've been actually looking for a custom file system driver on the web (and I've found two so far, neither for Windows 7 which causes me to distrust them given how many low-level changes there appear to be in Windows 7 vs. Windows XP; and I really wasn't thinking in terms of external "apps", maybe that's something to look into (if I can figure exactly what to search for in Google, of course!)

- Dan
 
WAD. @FILEREAD calls the Windows ReadFile API, and if you're reading from CON:, Windows won't send anything to ReadFile until a line has been entered in the console keyboard buffer.

If you want to read / write individuals bytes from / to COMn:, you're going to need an external app (or a custom file system driver).

How about @FILEREADB[handle,1] ? I created the small batch file here:

Code:
@echo off
setlocal
*on break goto END
*on error goto END
set hc=%@fileopen[CON:,read,binary]
do forever
  set cc=%@filereadb[%hc,1]
  echo %@fz4[%cc] %@char[%cc]``
enddo

:END
set dummy=%@fileclose[%hc]

where fz4=%@format[04,%1] (display numeric value in 4 columns, zero-padded on left].

I started the program in a stand-alone TCC 12.11.76 window (to match Dave's version). The results were surprising!


- each character I entered from the keyboard was instantly echoed at the end of the current line
- when I pressed "enter", the loop was executed, and each character, including the line terminating CR and LF, was displayed on a separate line.
I tried it again, with command-line ECHO turned OFF, with identical results.

I suspect that the original echo came from the keyboard driver (WinXP SP3) and @FILEREADB did not actually receive the individual characters until "enter" was pressed, and the behavior would be identical to @FILEREAD. The significance of opening the file as binary instead of text is only how individual bytes are delivered, not the buffering.

REX:
Some minor HELP issues.
- @FILEREADB and @FILEHANDLE are missing from the "See also" section of most of the filehandle-based commands
- @FILEHANDLE should have a warning that if the handle is not valid it reports an error (though most reports of this nature report the condition by a specific value)
 
(rhetorical question: Why a carriage return/line feed? After all, there's no guarantee that arbitrary binary data ("b" mode) will have those)

Ask Microsoft -- they'll probably tell you that anything coming from CON: will always have a CR/LF (eventually).

The other character devices (like COMn:) are leftovers from DOS and are deprecated in Windows. So I wouldn't expect much help from Microsoft in that area.
 
It also uses the Windows ReadFile() API, so you're going to have the same issue.

For console input, the INKEY command provides unbuffered access; using the /p and /x options suppresses instant echoing. Using the /Wn option allows terminating the loop on simple timeout - no more data. I am not sure how INKEY would work with redirected COM: input - no device available to test it.
 

Similar threads

Back
Top