【发布时间】:2011-01-22 19:19:50
【问题描述】:
我编写了两个小方法来保存和加载 .docx(以及后来的其他类型文件)文件到数据库(SERVER 2005/2008,以 VarBinary(MAX) 作为列)。一切看起来都不错,但是当我读回文件时,它已创建,但 Word 抱怨它已损坏,但最终将其打开,其中包含所有内容。代码有什么问题?
public static void databaseFileRead(string varID, string varPathToNewLocation) {
const int bufferSize = 100;
byte[] outByte = new byte[bufferSize];
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP))
using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("@varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader(CommandBehavior.Default))
while (sqlQueryResult != null && sqlQueryResult.Read()) {
using (FileStream stream = new FileStream(varPathToNewLocation, FileMode.OpenOrCreate, FileAccess.Write)) {
using (BinaryWriter writer = new BinaryWriter(stream)) {
long startIndex = 0;
long retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
while (retval == bufferSize) {
writer.Write(outByte);
writer.Flush();
startIndex += bufferSize;
retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
writer.Write(outByte, 0, (int) retval - 1);
writer.Flush();
writer.Close();
}
stream.Close();
}
}
}
}
public static void databaseFilePut(string varFilePath) {
FileStream stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(stream);
byte[] file = reader.ReadBytes((int) stream.Length);
reader.Close();
stream.Close();
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP))
using (var sqlWrite = new SqlCommand("INSERT INTO Raporty (RaportPlik) Values(@File)", varConnection)) {
sqlWrite.Parameters.Add("@File", SqlDbType.Binary, file.Length).Value = file;
sqlWrite.ExecuteNonQuery();
}
}
编辑:
我已按照建议将代码更改为 bufferSize 为 4096,但仍然不行。
原始文件显示:大小为 48,0 KB(字节:49 225),磁盘大小为 52,0 KB(字节:53 248)(Win 7 属性显示了这一点)。从 db 中取出的文件大小为 52,0 KB(字节:53 248),磁盘大小为 52,0 KB(字节:53 248)。
这一切都发生在使用 Win 7 x64 的开发机器上,为了确定,我已经卸载了 Eset Smart Security。
编辑2:
所以我从webpage 添加了另一种“方法”,它似乎可以解决问题。唯一值得注意的区别是缺少使用 BinaryWriter 和 Byte[] blob 的有点奇怪的定义。 是不是很奇怪?
public static void databaseFileRead(string varID, string varPathToNewLocation) {
const int bufferSize = 4096;
byte[] outByte = new byte[bufferSize];
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP))
using (var sqlQuery = new SqlCommand(@"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = @varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("@varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
while (sqlQueryResult != null && sqlQueryResult.Read()) {
using (FileStream stream = new FileStream(varPathToNewLocation, FileMode.OpenOrCreate, FileAccess.Write))
using (BinaryWriter writer = new BinaryWriter(stream)) {
long startIndex = 0;
long retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
while (retval > 0) {
writer.Write(outByte);
writer.Flush();
startIndex += retval;
retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
}
}
}
Byte[] blob = null;
FileStream fs = null;
const string sConn = Locale.sqlDataConnectionDetailsDZP;
SqlConnection conn = new SqlConnection(sConn);
SqlCommand cmd = new SqlCommand("SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = " + varID, conn);
conn.Open();
SqlDataReader sdr = cmd.ExecuteReader();
sdr.Read();
blob = new Byte[(sdr.GetBytes(0, 0, null, 0, int.MaxValue))];
sdr.GetBytes(0, 0, blob, 0, blob.Length);
sdr.Close();
conn.Close();
fs = new FileStream("c:\\Builder.docx", FileMode.Create, FileAccess.Write);
fs.Write(blob, 0, blob.Length);
fs.Close();
}
【问题讨论】:
标签: c# sql-server-2005 sql-server-2008 upload download