我有一个来自Oracle数据库的BLOB。在.NET中,它的类型为OracleLob,其中包含Read和ReadByte方法。
int OracleLob.Read(byte[] buffer, int offset, int count)
int OracleLob.ReadByte()
因此,Read方法读取一个字节序列,ReadByte一次读取一个字节。这是我的代码:
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();
}
binWriter.Close();
但是当我在Word中打开wordfile.DOCX时,它表示该文件已损坏且无法打开。我做错了什么?
答案 0 :(得分:3)
BinaryWriter
将以某种形式的序列化方式输出int。它不会只写一个字节。为此目的使用FileStream
,并使用byte[]
版本的读/写方法,因为一次一个字节的流非常慢。
答案 1 :(得分:2)
docx文件是一个OpenXml格式文件,基本上是一系列压缩并重命名为docx的xml文件。您不仅可以从数据库中获取输出并写入文件,而且可以将其神奇地转换为docx文件。
您确定这是您要在此处制作的docx文件吗?我能看到这个工作的唯一方法是你将docx文件序列化到数据库中,但是你必须确保它在“出路”上以完全相同的方式反序列化,否则底层的zip文件将被破坏,并且无法打开文件。
答案 2 :(得分:1)
代码有什么问题,它在将字节数据写入int
时使用BinaryWriter
值。它正在使用写入int
而不是写入byte
的重载,因此源中的每个字节将写为四个字节。如果你检查文件大小,你会发现它的大小应该是它应该的四倍。
将值转换为byte
,以便使用Write
方法的正确重载:
binWriter.Write((byte)currentByte);
为了更有效地执行此操作,您可以使用缓冲区一次读取字节块而不是单个字节:
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);
}
}
答案 3 :(得分:1)
currentByte被声明为int,因此二进制写入器为每次写入写入4个字节。
您需要将currentByte转换为实际字节:
binWriter.Write((byte) currentByte);