File Seeking / Overwriting bytes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jason

    File Seeking / Overwriting bytes

    Hi,

    I need to open an existing file, seek to a position at X number of
    bytes, and write out Y number of bytes overwriting any existing bytes,
    but no erasing any other data. Is this possible?

    I've opened a file in append "a" mode, and then used fseek with
    SEEK_SET to seek to 0 bytes into the file, but this sets the position
    at the end of existing data, not actually at the start of the file.

    So say I have a file of 8 bytes: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
    0xFF
    I want to open it, seek to a specific offset, lets say 2 bytes in,
    then write out 4 bytes with the value 1D overwriting existing bytes,
    leaving the file with: 0xFF 0xFF 0x1D 0x1D 0x1D 0x1D 0xFF 0xFF

    Heres my testing code.

    FILE *cont;
    cont = fopen("/home/jk/test.txt", "a");
    fseek(cont, 0, SEEK_SET);
    fputs("T", cont);
    fclose(cont);


    Please can someone point me in the right direction, I want to avoid
    reading everything in, editing it and rewriting it all out because the
    file could be huge.

    Many thanks,
    Jason
  • Nate Eldredge

    #2
    Re: File Seeking / Overwriting bytes

    Jason <jecheney@gmail .comwrites:
    Hi,
    >
    I need to open an existing file, seek to a position at X number of
    bytes, and write out Y number of bytes overwriting any existing bytes,
    but no erasing any other data. Is this possible?
    >
    I've opened a file in append "a" mode, and then used fseek with
    SEEK_SET to seek to 0 bytes into the file, but this sets the position
    at the end of existing data, not actually at the start of the file.
    You want the "r+" mode.

    Comment

    • Jason

      #3
      Re: File Seeking / Overwriting bytes

      On 13 Nov, 21:39, Nate Eldredge <n...@vulcan.la nwrote:
      Jason <jeche...@gmail .comwrites:
      Hi,
      >
      I need to open an existing file, seek to a position at X number of
      bytes, and write out Y number of bytes overwriting any existing bytes,
      but no erasing any other data. Is this possible?
      >
      I've opened a file in append "a" mode, and then used fseek with
      SEEK_SET to seek to 0 bytes into the file, but this sets the position
      at the end of existing data, not actually at the start of the file.
      >
      You want the "r+" mode.
      Ah that simple, thanks very much works perfectly.

      Comment

      • Eric Sosman

        #4
        Re: File Seeking / Overwriting bytes

        Jason wrote:
        Hi,
        >
        I need to open an existing file, seek to a position at X number of
        bytes, and write out Y number of bytes overwriting any existing bytes,
        but no erasing any other data. Is this possible?
        Yes, for suitable file types (that is, for files that make
        sense when accessed via "binary" rather than "text" streams).
        I've opened a file in append "a" mode, and then used fseek with
        SEEK_SET to seek to 0 bytes into the file, but this sets the position
        at the end of existing data, not actually at the start of the file.
        "Append" means "all new data goes at the end." If you want to
        write data at some other spot, use "rb+" or "r+b", both of which
        mean "open an existing file for reading (r) and update (+), in
        binary mode (b)."
        So say I have a file of 8 bytes: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
        0xFF
        I want to open it, seek to a specific offset, lets say 2 bytes in,
        then write out 4 bytes with the value 1D overwriting existing bytes,
        leaving the file with: 0xFF 0xFF 0x1D 0x1D 0x1D 0x1D 0xFF 0xFF
        >
        Heres my testing code.
        >
        FILE *cont;
        cont = fopen("/home/jk/test.txt", "a");
        Use "rb+", as noted above. Also, in a real program you should
        check whether I/O operations succeed or fail, especially the fopen()
        calls because they are particularly susceptible to failure.
        fseek(cont, 0, SEEK_SET);
        "2 bytes in," I think you said? Then why the zero? This seek
        positions the stream at the very beginning of the file, not at at
        the third byte.
        fputs("T", cont);
        This writes the single byte 'T', not the desired four bytes
        of '\x1d'.
        fclose(cont);
        >
        >
        Please can someone point me in the right direction, I want to avoid
        reading everything in, editing it and rewriting it all out because the
        file could be huge.
        --
        Eric.Sosman@sun .com

        Comment

        • Joe Wright

          #5
          Re: File Seeking / Overwriting bytes

          Jason wrote:
          Hi,
          >
          I need to open an existing file, seek to a position at X number of
          bytes, and write out Y number of bytes overwriting any existing bytes,
          but no erasing any other data. Is this possible?
          >
          I've opened a file in append "a" mode, and then used fseek with
          SEEK_SET to seek to 0 bytes into the file, but this sets the position
          at the end of existing data, not actually at the start of the file.
          >
          So say I have a file of 8 bytes: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
          0xFF
          I want to open it, seek to a specific offset, lets say 2 bytes in,
          then write out 4 bytes with the value 1D overwriting existing bytes,
          leaving the file with: 0xFF 0xFF 0x1D 0x1D 0x1D 0x1D 0xFF 0xFF
          >
          Heres my testing code.
          >
          FILE *cont;
          cont = fopen("/home/jk/test.txt", "a");
          fseek(cont, 0, SEEK_SET);
          fputs("T", cont);
          fclose(cont);
          >
          >
          Please can someone point me in the right direction, I want to avoid
          reading everything in, editing it and rewriting it all out because the
          file could be huge.
          >
          Many thanks,
          Jason
          Try this..

          #include <stdio.h>
          #include <stdlib.h>

          int main(void) {
          FILE *fp;
          char *file = "jc.txt";
          int c;

          fp = fopen(file, "w");
          fprintf(fp, "My name is jason.\n");
          fclose(fp);

          fp = fopen(file, "r");
          while ((c = getc(fp)) != EOF) putchar(c);
          fclose(fp);

          fp = fopen(file, "r+");
          fseek(fp, 11, SEEK_SET);
          fputc('J', fp);
          fclose(fp);

          fp = fopen(file, "r");
          while ((c = getc(fp)) != EOF) putchar(c);
          fclose(fp);

          return 0;
          }

          I've left the testing of fopen(), etc. up to you.

          --
          Joe Wright
          "Everything should be made as simple as possible, but not simpler."
          --- Albert Einstein ---

          Comment

          • Antoninus Twink

            #6
            Re: File Seeking / Overwriting bytes

            On 13 Nov 2008 at 21:43, Jason wrote:
            On 13 Nov, 21:39, Nate Eldredge <n...@vulcan.la nwrote:
            >You want the "r+" mode.
            >
            Ah that simple, thanks very much works perfectly.
            You may also want to do an fsync() (or fclose() of course) after writing
            the data, to make sure it gets committed to disk.

            Comment

            • Keith Thompson

              #7
              Re: File Seeking / Overwriting bytes

              Joe Wright <joewwright@com cast.netwrites:
              Jason wrote:
              >I need to open an existing file, seek to a position at X number of
              >bytes, and write out Y number of bytes overwriting any existing bytes,
              >but no erasing any other data. Is this possible?
              [...]
              Try this..
              >
              #include <stdio.h>
              #include <stdlib.h>
              >
              int main(void) {
              FILE *fp;
              char *file = "jc.txt";
              int c;
              >
              fp = fopen(file, "w");
              fprintf(fp, "My name is jason.\n");
              fclose(fp);
              >
              fp = fopen(file, "r");
              while ((c = getc(fp)) != EOF) putchar(c);
              fclose(fp);
              >
              fp = fopen(file, "r+");
              fseek(fp, 11, SEEK_SET);
              fputc('J', fp);
              fclose(fp);
              >
              fp = fopen(file, "r");
              while ((c = getc(fp)) != EOF) putchar(c);
              fclose(fp);
              >
              return 0;
              }
              >
              I've left the testing of fopen(), etc. up to you.
              You almost certainly want to do this in binary mode.

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
              Nokia
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              • Martien Verbruggen

                #8
                Re: File Seeking / Overwriting bytes

                On Thu, 13 Nov 2008 17:27:24 -0500,
                Joe Wright <joewwright@com cast.netwrote:
                Jason wrote:
                >Hi,
                >>
                >I need to open an existing file, seek to a position at X number of
                >bytes, and write out Y number of bytes overwriting any existing bytes,
                >but no erasing any other data. Is this possible?
                Try this..
                fp = fopen(file, "r+");
                fseek(fp, 11, SEEK_SET);
                fputc('J', fp);
                fclose(fp);
                To remain portable, the second argument of fseek() has to be 0 or a value
                returned by a previous call to ftell(). You should probably open the
                file in binary mode.

                Martien
                --
                | Some people, when confronted with a problem,
                Martien Verbruggen | think: "I know, I'll use regular
                | expressions". Now they have two problems. --
                | Jamie Zawinski

                Comment

                • Joe Wright

                  #9
                  Re: File Seeking / Overwriting bytes

                  Keith Thompson wrote:
                  Joe Wright <joewwright@com cast.netwrites:
                  >Jason wrote:
                  >>I need to open an existing file, seek to a position at X number of
                  >>bytes, and write out Y number of bytes overwriting any existing bytes,
                  >>but no erasing any other data. Is this possible?
                  [...]
                  >Try this..
                  >>
                  >#include <stdio.h>
                  >#include <stdlib.h>
                  >>
                  >int main(void) {
                  > FILE *fp;
                  > char *file = "jc.txt";
                  > int c;
                  >>
                  > fp = fopen(file, "w");
                  > fprintf(fp, "My name is jason.\n");
                  > fclose(fp);
                  >>
                  > fp = fopen(file, "r");
                  > while ((c = getc(fp)) != EOF) putchar(c);
                  > fclose(fp);
                  >>
                  > fp = fopen(file, "r+");
                  > fseek(fp, 11, SEEK_SET);
                  > fputc('J', fp);
                  > fclose(fp);
                  >>
                  > fp = fopen(file, "r");
                  > while ((c = getc(fp)) != EOF) putchar(c);
                  > fclose(fp);
                  >>
                  > return 0;
                  >}
                  >>
                  >I've left the testing of fopen(), etc. up to you.
                  >
                  You almost certainly want to do this in binary mode.
                  >
                  It never occurred to me. Why on earth use binary mode?

                  --
                  Joe Wright
                  "Everything should be made as simple as possible, but not simpler."
                  --- Albert Einstein ---

                  Comment

                  • Keith Thompson

                    #10
                    Re: File Seeking / Overwriting bytes

                    Joe Wright <joewwright@com cast.netwrites:
                    Keith Thompson wrote:
                    >Joe Wright <joewwright@com cast.netwrites:
                    >>Jason wrote:
                    >>>I need to open an existing file, seek to a position at X number of
                    >>>bytes, and write out Y number of bytes overwriting any existing bytes,
                    >>>but no erasing any other data. Is this possible?
                    >[...]
                    >>Try this..
                    >>>
                    >>#include <stdio.h>
                    >>#include <stdlib.h>
                    >>>
                    >>int main(void) {
                    >> FILE *fp;
                    >> char *file = "jc.txt";
                    >> int c;
                    >>>
                    >> fp = fopen(file, "w");
                    >> fprintf(fp, "My name is jason.\n");
                    >> fclose(fp);
                    >>>
                    >> fp = fopen(file, "r");
                    >> while ((c = getc(fp)) != EOF) putchar(c);
                    >> fclose(fp);
                    >>>
                    >> fp = fopen(file, "r+");
                    >> fseek(fp, 11, SEEK_SET);
                    >> fputc('J', fp);
                    >> fclose(fp);
                    >>>
                    >> fp = fopen(file, "r");
                    >> while ((c = getc(fp)) != EOF) putchar(c);
                    >> fclose(fp);
                    >>>
                    >> return 0;
                    >>}
                    >>>
                    >>I've left the testing of fopen(), etc. up to you.
                    >You almost certainly want to do this in binary mode.
                    >>
                    It never occurred to me. Why on earth use binary mode?
                    For one thing, your fseek() call isn't guaranteed to be meaningful for
                    a text file; the behavior is undefined unless the offset is either
                    zero or a value obtained from an earlier call to ftell().

                    You'll probably get away with it if you (a) use fseek and ftell
                    carefully, and (b) avoid either overwriting or creating any new-lines,
                    but there could still be some issues.

                    On Unix-like systems, it doesn't make any difference; on Windows, a
                    new-line is represented as a two-character sequence, and other systems
                    have even stranger ways of representing lines in text files.

                    --
                    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                    Nokia
                    "We must do something. This is something. Therefore, we must do this."
                    -- Antony Jay and Jonathan Lynn, "Yes Minister"

                    Comment

                    • Eric Sosman

                      #11
                      Re: File Seeking / Overwriting bytes

                      Joe Wright wrote:
                      Keith Thompson wrote:
                      >Joe Wright <joewwright@com cast.netwrites:
                      >>Try this..
                      >> [... see up-thread ...]
                      >>
                      >You almost certainly want to do this in binary mode.
                      >>
                      It never occurred to me. Why on earth use binary mode?
                      To be sure the fseek() will work. On a text stream, you
                      can only fseek() to a position you've already recorded with
                      ftell(), or to the very beginning or the very end. You can't
                      just leap to an arbitrary byte position, because a text stream
                      may need to translate between internal and external forms, andß
                      the forms may not be of equal length.

                      One commonly-encountered translation involves line endings.
                      When you write "Hello\nworld!\ n" to a text stream, some systems
                      actually write "Hello\r\nworld !\r\n" to the output file. You
                      may think that the 'w' is at offset six -- after all, you wrote
                      exactly six characters before it -- but it turns out that the
                      'w' is actually at offset seven because the single '\n' character
                      you wrote was translated to '\r' '\n' in the file. If you manage
                      to seek to offset six and plant a 'W' there, you might read back
                      "Hello\rWworld\ n" or "HelloWworl d" or you might not even be able
                      to read the data at all.

                      Less frequently encountered translations crop up occasionally.
                      Some character encoding schemes use "shifts" or "escapes" to record
                      supplementary characters, so if you write the single character 'ß',
                      say, you might get something like '\x0e' '\x5f' '\x0f', meaning
                      "switch to alternate character set, interpret 5F as a character of
                      that alternate set instead of as an underscore, shift back to the
                      normal character set." (The example is intended only to show the
                      nature of such schemes; the details need not be taken literally.)
                      So your single 'ß' winds up occupying three bytes in the file, and
                      if you seek to the spot you imagine is just after it you'll wind
                      up at what looks like the 5F underscore, in the middle of the three-
                      byte sequence that represents your single character. Not Good.

                      Anyhow: If you need to seek to calculated positions, you
                      need to use a binary stream to do it reliably. In a text stream
                      you can return to a place you've already been (and remembered),
                      but you can't navigate by de'd reckoning.

                      --
                      Eric.Sosman@sun .com

                      Comment

                      • Keith Thompson

                        #12
                        Re: File Seeking / Overwriting bytes

                        Martien Verbruggen <mgjv@heliotrop e.com.auwrites:
                        On Thu, 13 Nov 2008 18:24:04 -0500,
                        Eric Sosman <Eric.Sosman@su n.comwrote:
                        >Joe Wright wrote:
                        >>Keith Thompson wrote:
                        >>>Joe Wright <joewwright@com cast.netwrites:
                        >>>>Try this..
                        >>>> [... see up-thread ...]
                        >>>>
                        >>>You almost certainly want to do this in binary mode.
                        >>>>
                        >>It never occurred to me. Why on earth use binary mode?
                        >>
                        > To be sure the fseek() will work. On a text stream, you
                        >can only fseek() to a position you've already recorded with
                        >ftell(), or to the very beginning or the very end.
                        >
                        I don't think SEEK_END, which I assume you'd use to position at the end,
                        is supported on text streams.
                        >
                        C99: 7.19.9.2 - 4
                        >
                        4 For a text stream, either offset shall be zero, or offset shall be a
                        value returned by an earlier successful call to the ftell function on
                        a stream associated with the same file and whence shall be SEEK_SET.
                        >
                        I don't have a C90 standard, but a pre-standard draft has identical
                        wording to the above, so I assume the standard contains that wording as
                        well.
                        The wording you quoted implies that seeking to the end *is* allowed.
                        Valid calls are:

                        fseek(f, 0, SEEK_SET);
                        fseek(f, 0, SEEK_CUR);
                        fseek(f, 0, SEEK_END);
                        fseek(f, n, SEEK_SET);

                        where n was returned by a previous call to ftell() on the same file.

                        --
                        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                        Nokia
                        "We must do something. This is something. Therefore, we must do this."
                        -- Antony Jay and Jonathan Lynn, "Yes Minister"

                        Comment

                        • S M Ryan

                          #13
                          Re: File Seeking / Overwriting bytes

                          In article <774863e7-58a5-4625-b37e-7fcd208be791@g1 7g2000prg.googl egroups.com>,
                          Jason <jecheney@gmail .comwrote:
                          Hi,
                          >
                          I need to open an existing file, seek to a position at X number of
                          bytes, and write out Y number of bytes overwriting any existing bytes,
                          but no erasing any other data. Is this possible?
                          In character mode it depends on the operating system. Unices will do what you
                          want, but it's not required that any system do so.
                          I've opened a file in append "a" mode, and then used fseek with
                          SEEK_SET to seek to 0 bytes into the file, but this sets the position
                          at the end of existing data, not actually at the start of the file.
                          That's what "a" mode does. It always writes at the end regardless of where the
                          file might be positioned. You need something like "w", "w+", or "r+".
                          Please can someone point me in the right direction, I want to avoid
                          reading everything in, editing it and rewriting it all out because the
                          file could be huge.
                          On modern systems that might actually be as cheap as anything else.

                          --
                          I'm not even supposed to be here today.

                          I ASSURE YOU WE'RE OPEN!

                          Comment

                          • Nate Eldredge

                            #14
                            Re: File Seeking / Overwriting bytes

                            S M Ryan <wyrmwif@tang o-sierrra.comwrit es:
                            In article <774863e7-58a5-4625-b37e-7fcd208be791@g1 7g2000prg.googl egroups.com>,
                            Jason <jecheney@gmail .comwrote:
                            >Please can someone point me in the right direction, I want to avoid
                            >reading everything in, editing it and rewriting it all out because the
                            >file could be huge.
                            >
                            On modern systems that might actually be as cheap as anything else.
                            What systems are those?

                            Comment

                            • Martien Verbruggen

                              #15
                              Re: File Seeking / Overwriting bytes

                              On Thu, 13 Nov 2008 16:52:06 -0800,
                              Keith Thompson <kst-u@mib.orgwrote:
                              Martien Verbruggen <mgjv@heliotrop e.com.auwrites:
                              >On Thu, 13 Nov 2008 18:24:04 -0500,
                              > Eric Sosman <Eric.Sosman@su n.comwrote:
                              >>Joe Wright wrote:
                              >>>Keith Thompson wrote:
                              >>>>Joe Wright <joewwright@com cast.netwrites:
                              >>>>>Try this..
                              >>>>> [... see up-thread ...]
                              >>>>>
                              >>>>You almost certainly want to do this in binary mode.
                              >>>>>
                              >>>It never occurred to me. Why on earth use binary mode?
                              >>>
                              >> To be sure the fseek() will work. On a text stream, you
                              >>can only fseek() to a position you've already recorded with
                              >>ftell(), or to the very beginning or the very end.
                              >>
                              >I don't think SEEK_END, which I assume you'd use to position at the end,
                              >is supported on text streams.
                              >>
                              >C99: 7.19.9.2 - 4
                              >>
                              >4 For a text stream, either offset shall be zero, or offset shall be a
                              > value returned by an earlier successful call to the ftell function on
                              > a stream associated with the same file and whence shall be SEEK_SET.
                              >>
                              >I don't have a C90 standard, but a pre-standard draft has identical
                              >wording to the above, so I assume the standard contains that wording as
                              >well.
                              >
                              The wording you quoted implies that seeking to the end *is* allowed.
                              Valid calls are:
                              >
                              fseek(f, 0, SEEK_SET);
                              fseek(f, 0, SEEK_CUR);
                              fseek(f, 0, SEEK_END);
                              fseek(f, n, SEEK_SET);
                              >
                              where n was returned by a previous call to ftell() on the same file.
                              I see... There are two possible readings there, depending on what
                              'whence shall be SEEK_SET' is linked to...

                              (offset == 0) or (offset == fseek value and whence == SEEK_SET)

                              or

                              (offset == 0 or offset == fseek value) and whence == SEEK_SET

                              In a programming language we heve precedence or grammar rules that tell
                              us which interpretation is the right one. English doesn't really ave
                              that. The presence or absence of a comma after 'and' IMO is not enough.

                              is there a ruling somewhere that makes clear which of these two
                              interpretations was the intended one? I find it har dto believe that
                              this hasn't popped up before 9and if it has, why wasn't it made less
                              ambiguous? Or am I the only one who thinks it is ambiguous?)


                              Martien
                              --
                              |
                              Martien Verbruggen | If at first you don't succeed, try again.
                              | Then quit; there's no use being a damn fool
                              | about it.

                              Comment

                              Working...