如何从GZipStream获取字节数组或可读流

时间:2016-04-19 15:22:20

标签: c# stream gzipstream

我想将一个字节数组的压缩版本写入SQL Server varbinary(max)列。

我想将SqlClient命令的参数提供给SqlBytes类型,并尝试实例化该类型:

// data is a byte array at this point
SqlParameter p7 = new SqlParameter("@bytes", Compress(data));
p7.SqlDbType = SqlDbType.VarBinary;


public static SqlBytes Compress(byte[] input)
{

    using (MemoryStream memstream = new MemoryStream(input))
    {    
        using (GZipStream zipped = new GZipStream(memstream, CompressionMode.Compress))
        {               
            return new SqlBytes(zipped);    
        }    
    }
}

但该命令失败并显示"此操作不受支持"错误(见下面的跟踪)。所以我需要从GZipStream中获取压缩内容,并将其转换为允许实例化SqlBytes类型的形式。怎么做的?

注意:GZipStream不支持阅读,因此zipped.CopyTo( myOuputMemoryStream)无效。

at System.IO.Compression.GZipStream.get_Length()
at System.Data.SqlTypes.SqlBytes.get_Value()
at System.Data.SqlClient.SqlParameter.BinarySize(Object value, Boolean isSqlType)
at System.Data.SqlClient.SqlParameter.GetActualSize()
at System.Data.SqlClient.SqlParameter.ValidateTypeLengths(Boolean yukonOrNewer)
at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at .Form1.Save2Database(Byte[] data) 

in c:\\Users\\foo\\Documents\\Visual Studio 2013\\Projects\\Test\\Test\\Form1.cs:line 228

1 个答案:

答案 0 :(得分:2)

传递给GZipStream构造函数的流是以压缩(或解压缩)格式写入数据的流。您应该创建一个空的内存流,并使用GZipStream将字节写入其中:

var badDate = new DateTime(1, 1, 1);

return EdiReader.EdiReader.ReadEdiAndConvert(filePath)
    .Where(x => x.SiteNo == site)
    .Select(invoice => new DbBillInvoice() 
    {
        MeterNumber = invoice.MeterNumber,
        //assuming invoice.StartReadDate is actually a DateTime value, and not a string,
        // and that DbBillInvoice.StartReadDate is Nullable<DateTime>
        StartReadDate = (invoice.StartReadDate == badDate)?(DateTime?)null:invoice.StartReadDate,
        StartRead = invoice.StartRead,
        StartReadType = invoice.StartReadType,
        EndReadDate =  (invoice.EndReadDate == badDate)?(DateTime?)null:invoice.EndReadDate,
        EndRead = invoice.EndRead,
        EndReadType = invoice.EndReadType,
        ...
    }).ToList(); //Potential for a big performance win if you can change processing to avoid the ToList() call here.