1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

@FileRead from a device issues...

Discussion in 'Support' started by mathewsdw, Feb 26, 2012.

  1. mathewsdw

    Joined:
    May 24, 2010
    Messages:
    855
    Likes Received:
    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
     
  2. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    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).
     
  3. mathewsdw

    Joined:
    May 24, 2010
    Messages:
    855
    Likes Received:
    0
    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
     
  4. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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)
     
  5. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    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.
     
  6. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,870
    Likes Received:
    83
    It also uses the Windows ReadFile() API, so you're going to have the same issue.
     
  7. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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.
     

Share This Page