开发者

.NET BinaryWriter.Write() Method -- Writing Multiple Datatypes Simultaneously

I'm using BinaryWriter to write records to a file. The records are comprised of a class with the following property datatypes.

Int32,

Int16,

Byte[],

Null Character

To write each record, I call BinaryWriter.Write four times--one for each datatype. This works fine but I'd like to know if there's any way to just call the BinaryWriter.Write() method a single time using all of these datatypes. The reasoning for this is that another program is reading my binary file and will occasionally only read part of a record because it starts reading between开发者_如何学C my write calls. Unfortunately, I don't have control over the code to the other program else I would modify the way it reads.


Add a .ToBinary() method to your class that returns byte[].

public byte[] ToBinary()
{
   byte[] result= new byte[number_of_bytes_you_need];

   // fill buf

   return result;
}

In your calling code (approximate as I haven't compiled this)

stream.BinaryWrite(myObj.toBinary());

You're still writing each value independently, but it cleans up the code a little.

Also, as sindre suggested, consider using the serialization, as it makes it incredibly easy to recreate your objects from the file in question, and requires less effort than writing the file as you're attempting to.

Sync: you can't depend on any of these solutions to fix your file sync issue. Even if you manage to reduce your binaryWrite() call to a single statement, not using serialization or the .ToBinary() method I've outlined, bytes are still written sequentially by the framework. This is a limitation of the physical structure of the disk. If you have control over the file format, add a record length field written before any of the record data. In the app that's reading the file, make sure that you have record_length bytes before attempting to process the next record from the file. While you're at it, put this in a database. If you don't have control over the file format, you're kind of out of luck.


In keeping with you writing to a BinaryWriter, I would have the object create a binary record using a second BinaryWriter that is then written to the BinaryWriter. So on your class you could have a method like this:

    public void WriteTo(BinaryWriter writer)
    {
        MemoryStream ms = new MemoryStream();
        BinaryWriter bw = new BinaryWriter(ms);
        bw.Write(value1);
        bw.Write(value2);
        bw.Write(value3);
        bw.Write(value4);

        writer.Write(ms.ToArray());
    }

This would create a single record with the same format as you're already writing to the main BinaryWriter, just it would build it all at once then write it as a byte array.


Create a class of the record and use the binary formatter:

FileStream fs = new FileStream("file.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, <insert instance of a class here>);
fs.Close();

I haven't done this myself so I'm not absolutely sure it would work, the class cannot contain any other data, that's for sure. If you have no luck with a class you could try a struct.

Edit: Just came up with another possible solution, create a struct of your data and use the Buffer.BlockCopy function:

byte[] writeBuffer = new byte[sizeof(structure)];
structure[] strucPtr = new structure[1];  // must be an array, 1 element is enough though
strucPtr[0].item1 = 0213; // initialize all the members

// Copy the structure array into the byte array.
Buffer.BlockCopy(strucPtr, 0, writeBuffer, 0, writeBuffer.Length);

Now you can write the writeBuffer to file in one go.

Second edit: I don't agree with the sync problems not beeing possible to solve. First of all, the data is written to the file in entire sectors, not one byte at a time. And the file is really not updated until you flush it, thus writing data and updating the file length. The best and safest thing to do is to open the file exclusively, write a record (or several), and close the file. That requires the reading applications to use a similiar manner to read the file (open ex, read, close), as well as handling "access denied" errors gracefully.

Anyhow, I'm quite sure this will perform better no matter what when your'e writing an entire record at a time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜