开发者

Writing bytes to a file in C#

I have a BLOB from an Oracle database. In .NET it is of type OracleLob and has among them a Read and ReadByte methods.

int OracleLob.Read(byte[] buffer, int offset, int count)
int OracleLob.ReadByte()

So the Read method reads a sequence of bytes and ReadByte reads a single byte at a time. Here is my code:

OracleLob ol = (OracleLob) cmd.Parameters[1].Value; //her er filen!!

BinaryWriter binWriter = new BinaryWriter(File.Open(@"D:\wordfile.DOCX", FileMode.Create));
int currentByte = ol.ReadByte();

while (currentByte != -1)
{
   binWriter.Write(currentByte);
   currentByte = ol.ReadByte开发者_如何学Python();
}

binWriter.Close();

But when I open wordfile.DOCX in Word, it says that the file is corrupt and cannot be opened. What am I doing wrong?


BinaryWriter will output the int in some form of serialized manner. It won't write just a single byte. Use FileStream for this purpose, and use the byte[] versions of the read/write methods, since byte-at-a-time streaming is very slow.


A docx file is a OpenXml format file that is basically a series of xml files that is zipped down and renamed to docx. You can't just take a output from a database and write to a file and magically make it into a docx file.

Are you sure it's a docx file you are trying to make here? The only way I can see this working is if you serialized a docx file into the database, but then you have to make sure that it's de-serialized the exactly same way on "the way out", else the underlaying zip file will be corrupt, and the file cannot be opened.


What's wrong with the code is that it's using an int value when writing the byte data to the BinaryWriter. It's using the overload that is writing an int instead of the one writing a byte, so each byte from the source will be written as four bytes. If you check the file size you see that it's four times as large as it should be.

Cast the value to byte so that the correct overload of the Write method is used:

binWriter.Write((byte)currentByte);

To do this more efficiently, you can use a buffer to read blocks of bytes instead of a single byte at a time:

using (FileStream stream = File.Open(@"D:\wordfile.DOCX", FileMode.Create)) {
  byte[] buffer = new byte[4096];
  int len = ol.Read(buffer, 0, buffer.Length);
  while (len > 0) {
    stream.Write(buffer, 0, len);
    len = ol.Read(buffer, 0, buffer.Length);
  }
}


currentByte is declared as an int, so the binary writer is writing 4 bytes for each write.

You need to cast currentByte as an actual byte:

binWriter.Write((byte) currentByte);
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜