Announcement

Collapse
No announcement yet.

Reading from a file after APPEND

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Reading from a file after APPEND

    PBCC5 manual says: When PB/CC opens a file for APPEND, it does not adjust the file pointer to overwrite any existing CHR$(26) character (end of file mark, $EOF). Instead, it places new data at the "true" end of the file. PB/DOS overwrites the CHR$(26) marker.

    So, when I read from a file I've appended to, and use NOT EOF to tell me if I've reached the end, it will stop before the appended material?

    Workaround, anyone? Of course, the obvious workaround is to not use APPEND......

  • #2
    So what happens when you try it? does it rely on the ^Z character for EOF, or use the file length?

    Comment


    • #3
      Code:
      SUB Foo() AS LONG
       LOCAL hFile AS LONG, nrec AS LONG, S AS STRING 
      
       hFile = FREEFILE 
       OPEN "THEFILE" FOR [b]OUTPUT[/b] AS hFile 
       FOR Z = 1 TO 10 
          S = USING$ ("Record NUmber  #", Z) 
          PRINT #hFile, S 
       NEXT 
      S =  "HERE COMES EOF MARKER" & $CHR$(26) & " SEE?"
      PRINT #hFile, S
      CLOSE hFile
      
      hFile = FREEFILE 
      OPEN "THEFILE" FOR [b]APPEND[/b] AS hFile 
       FOR Z = 11 TO 10 
          S = USING$ ("Record NUmber  #", Z) 
          PRINT #hFile, S 
       NEXT 
       CLOSE hFILE 
      
      hFile = FREEFILE 
      OPEN "THEFILE" FOR [b]INPUT[/b] AS hFile 
      WHILE NOT EOF(hFile) 
        LINE INPUT #hFile, S 
        STDOUT  S 
      WEND
      CLOSE hFILE 
      END SUB
      No, I did not try it...but this is the code I would use to try it.
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        MCM wrote:

        No, I did not try it...but this is the code I would use to try it.
        ummm -- that code's not going to cut it...

        Code:
        SUB Foo() AS LONG   <=== a typed SUB, cool!
        
        ... $CHR$(26)    <=== a constant function call?
        
        ...FOR Z = 11 TO 10    <=== which way did he go, which way did he go

        At least my misspelling of "cognitive" didn't prevent any program from working... Doncha just love tpyos! Can't publish with 'em, can't publish without 'em!

        Sarcasm aside, that's a useful demo. I learn (re-learn) something every day. (Nowadays it seems like I'm doing a lot more re-learning...)

        Comment


        • #5
          > SUB.... () AS LONG

          I do BIG IDEAS.

          Details are left to staff.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Seems to work as before

            Lurkers - it seems to work as before. When I append to an existing file then use EOF(#) to read from it, I get the whole thing.

            Comment


            • #7
              If you APPEND after a CHR$(26), the data gets written, but not read back (using MCM code from above) unless you read using FOR BINARY:
              Code:
              #COMPILE EXE
              #DIM ALL
              
              FUNCTION PBMAIN() AS LONG
              
                  LOCAL hFile AS LONG, nrec AS LONG, z AS LONG, s AS STRING
              
                  ? "Creating THEFILE using 'FOR OUTPUT' with NO EOF marker added..."
                  hFile = FREEFILE
                  OPEN "THEFILE" FOR OUTPUT AS hFile
                  FOR z = 1 TO 5
                      s = USING$ ("Record Number A#", z)
                      PRINT #hFile, s
                  NEXT z
                  s =  "No EOF MARKER inserted."
                  PRINT #hFile, s
                  CLOSE hFile
              
                  ? "Appending 5 more records using 'FOR APPEND' and then adding EOF MARKER..."
                  hFile = FREEFILE
                  OPEN "THEFILE" FOR APPEND AS hFile
                  FOR z = 1 TO 5
                      s = USING$ ("Record Number B#", z)
                      PRINT #hFile, s
                  NEXT z
                  s =  "EOF MARKER inserted here ->" & CHR$(26) & "<-"
                  PRINT #hFile, s
                  CLOSE hFILE
              
                  ? "Appending 5 more records using 'FOR APPEND'"
                  ? "(these C records *will* be written, but won't be read back"
                  ? "because of the embedded EOF MARKER)"
                  hFile = FREEFILE
                  OPEN "THEFILE" FOR APPEND AS hFile
                  FOR z = 1 TO 5
                      s = USING$ ("Record Number C#", z)
                      PRINT #hFile, s
                  NEXT z
                  CLOSE hFILE
              
                  ? : ? "And reading THEFILE back using 'FOR INPUT':"
                  hFile = FREEFILE
                  OPEN "THEFILE" FOR INPUT AS hFile
                  WHILE NOT EOF(hFile)
                      LINE INPUT #hFile, s
                      STDOUT s
                  WEND
                  CLOSE hFILE
              
                  ? : ? "And reading THEFILE back using 'FOR BINARY':"
                  hFile = FREEFILE
                  OPEN "THEFILE" FOR BINARY AS hFile
                  GET$ #hFile, LOF(#hFile), s
                  CLOSE hFile
                  STDOUT s
              
                  WAITKEY$
              
              END FUNCTION
              The output is:
              Code:
              Creating THEFILE using 'FOR OUTPUT' with NO EOF marker added...
              Appending 5 more records using 'FOR APPEND' and then adding EOF MARKER...
              Appending 5 more records using 'FOR APPEND'
              (these C records *will* be written, but won't be read back
              because of the embedded EOF MARKER)
              
              And reading THEFILE back using 'FOR INPUT':
              Record Number A1
              Record Number A2
              Record Number A3
              Record Number A4
              Record Number A5
              No EOF MARKER inserted.
              Record Number B1
              Record Number B2
              Record Number B3
              Record Number B4
              Record Number B5
              EOF MARKER inserted here ->
              
              And reading THEFILE back using 'FOR BINARY':
              Record Number A1
              Record Number A2
              Record Number A3
              Record Number A4
              Record Number A5
              No EOF MARKER inserted.
              Record Number B1
              Record Number B2
              Record Number B3
              Record Number B4
              Record Number B5
              EOF MARKER inserted here ->→<-
              Record Number C1
              Record Number C2
              Record Number C3
              Record Number C4
              Record Number C5
              Last edited by Jim Dunn; 14 Mar 2010, 03:59 PM.
              3.14159265358979323846264338327950
              "Ok, yes... I like pie... um, I meant, pi."

              Comment


              • #8
                EOF and APPEND and LINE INPUT

                FWIW, you migth want to read another discussion of this topic in:

                The 4th entry in this thread contains a workaround.
                Last edited by Peter Voll; 26 May 2010, 09:39 AM.

                Comment


                • #9
                  I don't know why the word "workaround" is being thrown around here so freely.

                  The doc for LINE INPUT# (poor semantics*, but understandable in context) says...
                  It is assumed the data is standard text, delimited by a CR/LF ($CRLF) or EOF (1A hex or $EOF).
                  The doc for OPEN FOR APPEND says it will "append to" an existing file. For those for whom English is not your primary language, this means "add after the last byte currently in the file."

                  Seems to me this is a case for "proper technique" and/or "understanding both the data I am working with and the behavior of the verbs I wish to use."

                  If I had to append to a file which "might" have an EOF char (0x1A) at the end, and that were going to screw up the way I intend to read that file later - using LINE INPUT# - I would just eliminate the 0x1A before I started appending....

                  Code:
                    OPEN "thefile" FOR BINARY as hFile 
                    SEEK hFile, LOF(hFile) -1&    ' position to last byte
                    GET hFile, , bytevar      ' read last character
                    IF btyevar = &h1A?  THEN  ' is the last char an EOF? 
                      SEEK hFile, LOF(hFile) - 1& '  back up since our GET advanced 
                      SETEOF  hFile                ' set new EOF prior to $EOF char 
                    END IF 
                    CLOSE hFile   ' save file with new length one less than before 
                  
                     Hfile = FREEFILE 
                     OPEN  "thefile" FOR APPEND as hFIle 
                     do my thing here 
                     ....
                  You might even write yourself a little procedure to "RemoveEofIfFound (Filename$) and keep this in your "Frequently #INCLUDEd Procedures" library. With minor modification you could truncate the file at the FIRST 0x1A found instead of looking only at the physical end of data.

                  Was that so hard?

                  The word "workaround" should be reserved for use when dealing with a compiler bug ("issue"). No such "issue" here.

                  MCM
                  *The data are assumed to be in "standard [CP/M but that would look really bad in the help for a Windows' compiler, wouldn't it?] text" format, with records delimited by CRLF; end of file is presumed at the first 0x1A found in the data or at the last byte of data in the file, whichever occurs first.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Hey Michael !

                    I'm sorry if I misused the word "workaround", and you are right, english is not my mother tongue, but Daniel Raymer, who started this thread, asked for a "workaround", thats why I used the word...

                    The code you are posting is very similar to the code I posted in the thread I was referring back to in my previous post in this thread, exept for one detail:
                    Your SEEK
                    SEEK hFile, LOF(hFile) -1& ' position to last byte
                    will position to the byte before the last byte.
                    F.ex. If the length-of-file is 20 bytes, then the (possible) 0x1A will be in position 20. Your SEEK will position to byte 19, and the following GET wil read byte 19...

                    You say
                    The word "workaround" should be reserved for use when dealing with a compiler bug ("issue"). No such "issue" here.
                    In the thread, I refer back to, you were contributing in post #15 (Jan 22nd, 2002), and you said:
                    Regardless, this is an inconsistency and should be addressed in a future version of the compilers.
                    But of course, that is more than 8 years ago...

                    Comment


                    • #11
                      Your SEEK
                      >SEEK hFile, LOF(hFile) -1& ' position to last byte

                      will position to the byte before the last byte.
                      F.ex. If the length-of-file is 20 bytes, then the (possible) 0x1A will be in position 20. Your SEEK will position to byte 19, and the following GET wil read byte 19...
                      You are correct. I usually work with OPEN FOR BINARY "BASE=0" but in deference to others I didn't use that in the OPEN here and must have screwed myself up by thinking one way here, one way there.

                      Oh, well, whomever tried that surely has discovered it by now.

                      >But of course, that is more than 8 years ago...

                      Not just eight years, but three or four major compiler versions and updated help files.

                      All I've ever asked for is that documented behavior equals actual behavior; when not true I call that a bug.

                      Since the documentation now DOES explain the use of 0x1E as an 'end of file' indicator, I'd say that inconsistency has been addressed.

                      The real point was, why whine about inconsistencies when it's so easy to just "deal with and be done with it?"

                      MCM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        The reason for discussion this topic at all was, that APPEND was behaving different in PB/DOS, but you didn't know.
                        So converting from PB/DOS to PB/CC was a problem, as you can't fix a problem, if you don't know there is a problem. So you are right, once you know about it, it isn't really a problem. But you have to know it !
                        And because of the thread I'm referring back to , there is now an entry in the documentation describing this difference between PB/DOS and PB/CC...

                        Comment


                        • #13
                          Please note that the Ctrl+Z is considered an EOF, or end of file, regardless of where it is located in the physical file data. Checking for a Ctrl+Z as the last character(s) in the file will not be sufficient for all cases, although it may be sufficient for files you have created yourself.

                          Comment


                          • #14
                            > APPEND was behaving different in PB/DOS, but you didn't know

                            Oh yes I did.

                            "Back in the day" (I really hate that phrase) I wrote more PB/DOS code than Carter's has little pills.

                            However, when I migrated MS-DOS applications to PB/Windows, I made the time to RTFM.

                            Maybe that also explains why I can be such a PITA when Doc<>RealLife.

                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              > APPEND was behaving different in PB/DOS, but you didn't know.

                              What I meant to say was:
                              You knew how APPEND was behaving in PB/DOS, but you didn't know that it was behaving different in PB/CC.

                              Comment

                              Working...
                              X