Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C#读取/写入SQLServer2005/2008时,文件损坏?_C#_Sql Server 2005_Sql Server 2008_Upload_Download - Fatal编程技术网

从C#读取/写入SQLServer2005/2008时,文件损坏?

从C#读取/写入SQLServer2005/2008时,文件损坏?,c#,sql-server-2005,sql-server-2008,upload,download,C#,Sql Server 2005,Sql Server 2008,Upload,Download,我编写了两个小方法来将.docx(以及其他类型的文件)文件保存并加载到数据库中(Server2005/2008,以VarBinary(MAX)作为列)。一切似乎都很好,但当我读回文件时,它被创建了,但Word抱怨它被破坏了,但最后打开了它,里面有所有的东西。代码怎么了 public static void databaseFileRead(string varID, string varPathToNewLocation) { const int bufferSize =

我编写了两个小方法来将.docx(以及其他类型的文件)文件保存并加载到数据库中(Server2005/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属性显示了这一点)。而从数据库中取出的文件大小为52,0 KB(字节:53 248),磁盘上的文件大小为52,0 KB(字节:53 248)

这一切都发生在Win 7 x64开发机器上,我卸载了Eset Smart Security以确保安全

编辑2:

因此,我添加了另一种“方法”来实现这一点,它似乎做到了这一点。唯一值得注意的区别是没有使用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();
    }

代码可能没有问题。我会看看你在那台服务器上有什么病毒扫描软件,然后马上卸载它。我看到Norton和McAfee都是clobber文件,没有任何迹象表明他们更改了任何内容。

代码可能没有问题。我会看看你在那台服务器上有什么病毒扫描软件,然后马上卸载它。我看到Norton和McAfee都是clobber文件,没有任何迹象表明他们改变了什么。

您的
数据库文件读取方法中有一个错误

考虑一下:您的缓冲区大小为100字节(非常小-我建议最小值为4096字节!),您的循环如下所示:

while (retval == bufferSize) 
{
   writer.Write(outByte);
   writer.Flush();
   startIndex += bufferSize;
   retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
好的,这很好,直到您的文件中只剩下73个字节需要处理——在这种情况下,最后一次调用

retval=sqlQueryResult.GetBytes(0,startIndex,outByte,0,bufferSize)

将在
retval
中返回“73”,由于这是而不是
==bufferSize
,因此将中止。因此,您总是跳过最后两个字节

您需要做的是:

while (retval > 0) 
{
   writer.Write(outByte);
   writer.Flush();
   startIndex += retval;
   retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
这样,在读取最后73个字节时,您将得到
retval=73
,并写出最后73个字节,然后对sqlQueryResult的下一次调用应返回
retval=0
,然后终止循环

试试看——我很确定这就是这个错误的原因


Marc

您的
数据库文件读取方法中有一个错误

考虑一下:您的缓冲区大小为100字节(非常小-我建议最小值为4096字节!),您的循环如下所示:

while (retval == bufferSize) 
{
   writer.Write(outByte);
   writer.Flush();
   startIndex += bufferSize;
   retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
好的,这很好,直到您的文件中只剩下73个字节需要处理——在这种情况下,最后一次调用

retval=sqlQueryResult.GetBytes(0,startIndex,outByte,0,bufferSize)

将在
retval
中返回“73”,由于这是而不是
==bufferSize
,因此将中止。因此,您总是跳过最后两个字节

您需要做的是:

while (retval > 0) 
{
   writer.Write(outByte);
   writer.Flush();
   startIndex += retval;
   retval = sqlQueryResult.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
这样,在读取最后73个字节时,您将得到
retval=73
,并写出最后73个字节,然后对sqlQueryResult的下一次调用应返回
retval=0
,然后终止循环

试试看——我很确定这就是这个错误的原因


Marc

以下代码似乎工作正常,没有错误。跳过使用
BinaryWriter
可以正确地写入文件。为什么使用
BinaryWriter
会破坏我不知道的文件:-)


下面的代码似乎可以正常工作。跳过使用
BinaryWriter
可以正确地写入文件。为什么使用
BinaryWriter
会破坏我不知道的文件:-)


服务器上没有防病毒/防火墙。服务器上没有防病毒/防火墙。我已将代码替换为您的代码,但仍然会出错。我也把buffersize改成了4096。我还认为
writer.Write(outByte,0,(int)retval-1)
正在处理丢失的73个字节。代码基于@madboy:相同的错误?你有其他信息吗?磁盘上生成的文件大小是100 resp的精确倍数。4096字节???@madboy:是的,没错-我忽略了最后一个
编写器。编写
语句。是的,这将处理最后剩余的字节…我现在做了另一个测试。原始文件显示:48,0 KB(bajtów:49 225)为大小,52,0 KB(bajtów:53 248)为磁盘大小(Win 7属性显示了这一点)。而从数据库中取出的文件大小为52,0 KB(bajtów:53 248),磁盘大小为52,0 KB(bajtów:53 248)。请记住,我赢了7 x64,可能是什么原因使它变糟了?我已经用工作代码更新了main poste(read函数的第二部分)。似乎使用BinaryWriter并不是最好的选择。不知道你为什么:-)我已经用你的代码替换了代码,但仍然出错。我也把buffersize改成了4096。我还认为
writer.Write(outByte,0,(int)retval-1)
正在处理丢失的73个字节。代码基于@madboy:相同的错误?你有其他信息吗?磁盘上生成的文件大小是100 resp的精确倍数。4096字节???@madboy:是的,没错-我忽略了最后一个
编写器。编写
语句。是的,这将处理最后剩余的字节…我现在做了另一个测试。原始文件显示:48,0 KB(bajtów:49 225)为大小,52,0 KB(bajtów:53 248)为磁盘大小(Win 7属性显示了这一点)。而从数据库中取出的文件大小为52,0 KB(bajtów:53 248),磁盘大小为52,0 KB(bajtów:53 248)。请记住,我赢了7 x64,可能是什么原因使它变糟了?我已经用工作代码更新了main poste(read函数的第二部分)。似乎使用BinaryWriter并不是最好的选择。不知道你为什么:-)