如何使用 SQL 文件流 win32 API 并支持 WCF 流

Posted

技术标签:

【中文标题】如何使用 SQL 文件流 win32 API 并支持 WCF 流【英文标题】:How to use SQL file streaming win32 API and support WCF streaming 【发布时间】:2011-02-22 10:37:28 【问题描述】:

我正在使用 Sql server 文件流类型在后端存储大文件。我正在尝试使用 WCf 将文件流式传输到客户端。

我能够使用 SQLFileStream (API) 获取文件的句柄。然后我尝试返回这个流。我在客户端实现了数据分块以从流中检索数据。

我能够为常规文件流和内存流做到这一点。另外,如果我将sqlfilestream转换为也可以使用的内存流。唯一认为不起作用的是当我尝试返回 sqlfilestream 时。我做错了什么。

我已经尝试过启用流式传输的 nettcpbinding 和使用 MTOM 编码的 http 绑定。

这是我收到的错误消息:


套接字连接被中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或底层网络问题造成的。本地套接字时间为 00:09:59....

这是我的示例代码

        RemoteFileInfo info = new RemoteFileInfo();
        info.FileName = "SampleXMLFileService.xml";

        string pathName = DataAccess.GetDataSnapshotPath("DataSnapshot1");

        SqlConnection connection = DataAccess.GetConnection();            

        SqlTransaction sqlTransaction = connection.BeginTransaction("SQLSileStreamingTrans");
        SqlCommand command = new SqlCommand();
        command.Connection = connection;
        command.Transaction = sqlTransaction;
        command.CommandText = "SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()";

        byte[] transcationContext = command.ExecuteScalar() as byte[];

        SqlFileStream stream = new SqlFileStream(pathName, transcationContext, FileAccess.Read);

// byte[] bytes = new byte[stream.Length]; // stream.Read(bytes, 0, (int) stream.Length);

// 流 returnStream = stream; // MemoryStream memoryStream = new MemoryStream(bytes);

        info.FileByteStream = stream;

        info.Length = info.FileByteStream.Length;

        connection.Close();

        return info;

    [MessageContract]
    public class RemoteFileInfo : IDisposable
    
        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public long Length;

        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStream;

        public void Dispose()
        
            if (FileByteStream != null)
            
                FileByteStream.Close();
                FileByteStream = null;
            
        
    

感谢任何帮助

【问题讨论】:

【参考方案1】:

我刚刚针对我的情况解决了这个问题。

我的 WCF 服务设置为 InstanceContextMode.PerCall。

当我请求流时,我必须让事务/连接保持打开状态,直到客户端使用该对象。它是通过服务的 Dispose 方法完成的(如果你实现了 IDisposable,WCF 会自动为你调用 Dispose)。

对我来说就像一个魅力,在客户端读取流没有问题。

【讨论】:

解决了我的问题!只是为了让任何不确定的人清楚,拉出许多 WCF 流示例使用的所有 using 语句(以确保正确处理对象)并在服务 Dispose 函数中处理它们(实现 IDisposable。 这个 VB.Net 示例可以满足您的需求 - petermeinl.wordpress.com/2012/02/20/…,像我一样轻松转换为 C#,如果有人需要帮助,请给我留言/评论,因为我知道服务错误可能会令人沮丧修复!

以上是关于如何使用 SQL 文件流 win32 API 并支持 WCF 流的主要内容,如果未能解决你的问题,请参考以下文章

C头文件如何导入win32api函数?

如何在win32 api中将鼠标坐标写入文本文件?

尝试使用 Win32 WASAPI C++ 中的“捕获流”创建 wav 文件

如何设置win32 api c++按钮背景颜色和文本颜色?

如何从 PHP 进行 Win32 API 调用?

如何在 Ruby 中使用 Win32API 从 DLL 返回字符串