Home All Groups Group Topic Archive Search About

Writing a byte to a specific location in a file

Author
16 Jun 2006 11:54 AM
Craig
I have the need to write a byte of information to a specific location in a
text file.

eg. the file looks something like this.

FYYNN
Line 1
Line 2
<eof>

The first character is a flag indicating the file has changed and the 2 -
4th characters are flags indicating the line of data that has changed ie Y or
N.

What I need to do is set the last four characters on the first line and then
write a line coresponding to each of the 'Y' flags.  Finally and it must be
the last thing I do is set the first character on the first line to a flag
which is used by a second application to initate an action.

I hope this makes sense.

initial myfile.txt
WNNNN
<eof>

Below is a sub that I am using to try and update the first flag.

Sub WriteFile()

        Dim fs As New System.IO.FileStream("C:\myFile.txt",
System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)
        Dim w As New System.IO.BinaryWriter(fs)

        fs.Seek(1, IO.SeekOrigin.Begin)
        w.Seek(1, SeekOrigin.Begin)
        w.Write(CChar("X"))
    End Sub 'Main

Resulting myfile.txt
ïX¿WNNNN
<eof>

Author
16 Jun 2006 3:43 PM
Göran Andersson
If you want to write directly to the file you have to first determine
what kind of file it is, then encode the characters according to this.
That is far more complicated than your attempt.


It looks like it's an 8-bit unicode file (UTF8), and that you have
written the character in the middle of the preamble (which is an
encoding identifier at the beginning of the file).

The preamble for an UTF8 file is the three bytes EF BB BF. As you seek
to the second byte in the file (as the index is zero based) you
overwrite the second and third bytes of the preamble. The reason that
you are writing two bytes to the file is that the Char data type in .NET
is a 16 bit unicode character, and writing that using a BinaryWriter
results in two bytes.

After you written to the file, it will contain this data:

EF 'X' 00 'W' 'N' 'N' 'N' 'N'

As this is no longer a unicode file (as you destroyed the preamble), it
will be read as a regular ANSI text file, and the EF and 00 bytes will
show as "weird" characters.


The easiest way to do this is to simply read the entire file, make the
changes, and write it all back again.


Craig wrote:
Show quoteHide quote
> I have the need to write a byte of information to a specific location in a
> text file.
>
> eg. the file looks something like this.
>
> FYYNN
> Line 1
> Line 2
> <eof>
>
> The first character is a flag indicating the file has changed and the 2 -
> 4th characters are flags indicating the line of data that has changed ie Y or
> N.
>
> What I need to do is set the last four characters on the first line and then
> write a line coresponding to each of the 'Y' flags.  Finally and it must be
> the last thing I do is set the first character on the first line to a flag
> which is used by a second application to initate an action.
>
> I hope this makes sense.
>
> initial myfile.txt
> WNNNN
> <eof>
>
> Below is a sub that I am using to try and update the first flag.
>
> Sub WriteFile()
>
>         Dim fs As New System.IO.FileStream("C:\myFile.txt",
> System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)
>         Dim w As New System.IO.BinaryWriter(fs)
>
>         fs.Seek(1, IO.SeekOrigin.Begin)
>         w.Seek(1, SeekOrigin.Begin)
>         w.Write(CChar("X"))
>     End Sub 'Main
>
> Resulting myfile.txt
> ïX¿WNNNN
> <eof>
>
Author
16 Jun 2006 10:58 PM
Craig
Thankyou,
I'm still not sure I have done this the best way, but given I have to write
the first byte last it works.. Thankyou Göran.

As it turns out the file I need to write to is plain Ascii, and when I
created this file for testing I created it in UTF8.  First Problem!

Once I sorted that, I changed my writing routine to include ascii encoding
and it seems to work as intended.

For interest the new routine was ammended to look like like this,

Sub WriteFile()
   Dim fs As New System.IO.FileStream("C:\myfile.txt", _
        System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, _
        FileShare.ReadWrite)
   Dim w As New System.IO.BinaryWriter(fs, Encoding.ASCII)
   w.Seek(0, SeekOrigin.Begin)
   w.Write(CChar("X"))
End Sub


Show quoteHide quote
"Göran Andersson" wrote:

> If you want to write directly to the file you have to first determine
> what kind of file it is, then encode the characters according to this.
> That is far more complicated than your attempt.
>
>
> It looks like it's an 8-bit unicode file (UTF8), and that you have
> written the character in the middle of the preamble (which is an
> encoding identifier at the beginning of the file).
>
> The preamble for an UTF8 file is the three bytes EF BB BF. As you seek
> to the second byte in the file (as the index is zero based) you
> overwrite the second and third bytes of the preamble. The reason that
> you are writing two bytes to the file is that the Char data type in .NET
> is a 16 bit unicode character, and writing that using a BinaryWriter
> results in two bytes.
>
> After you written to the file, it will contain this data:
>
> EF 'X' 00 'W' 'N' 'N' 'N' 'N'
>
> As this is no longer a unicode file (as you destroyed the preamble), it
> will be read as a regular ANSI text file, and the EF and 00 bytes will
> show as "weird" characters.
>
>
> The easiest way to do this is to simply read the entire file, make the
> changes, and write it all back again.
>
>
> Craig wrote:
> > I have the need to write a byte of information to a specific location in a
> > text file.
> >
> > eg. the file looks something like this.
> >
> > FYYNN
> > Line 1
> > Line 2
> > <eof>
> >
> > The first character is a flag indicating the file has changed and the 2 -
> > 4th characters are flags indicating the line of data that has changed ie Y or
> > N.
> >
> > What I need to do is set the last four characters on the first line and then
> > write a line coresponding to each of the 'Y' flags.  Finally and it must be
> > the last thing I do is set the first character on the first line to a flag
> > which is used by a second application to initate an action.
> >
> > I hope this makes sense.
> >
> > initial myfile.txt
> > WNNNN
> > <eof>
> >
> > Below is a sub that I am using to try and update the first flag.
> >
> > Sub WriteFile()
> >
> >         Dim fs As New System.IO.FileStream("C:\myFile.txt",
> > System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)
> >         Dim w As New System.IO.BinaryWriter(fs)
> >
> >         fs.Seek(1, IO.SeekOrigin.Begin)
> >         w.Seek(1, SeekOrigin.Begin)
> >         w.Write(CChar("X"))
> >     End Sub 'Main
> >
> > Resulting myfile.txt
> > ïX¿WNNNN
> > <eof>
> >
>