【问题标题】:Large Data streaming from sql server through WCF to client大数据从 sql server 通过 WCF 流式传输到客户端
【发布时间】:2016-02-02 02:00:43
【问题描述】:

使用 SQL 数据库存储大型数据文件(大约 1 GB 的 CSV 文件)并使用 WCF 将数据库中的数据流式传输到客户端(不获取内存中的完整数据)有哪些可能的方法?

【问题讨论】:

  • 您到底为什么要在 RDBMS 中存储 1GB CSV 文件?这听起来像是一个设计问题。我想您可以使用FILESTREAM 并将其从目录中拉出...
  • @DanField 除了使用数据库无法找出任何其他方式。只是我的用例的简要概述:- 有一个 Web 应用程序可以托管在负载均衡器(NLB)后面的客户端的多个服务器上,并且使用 Web 应用程序,我们有 Windows 服务,可以根据请求生成 csv 文件。将此文件存储在安装服务器的硬盘在请求下载时会出现问题,因为我们不确定文件是在哪个节点(NLB 后面)创建的,并且下载请求可能被重定向到其他节点。无法使用网络路径(安全问题).你建议什么?-谢谢
  • @DanField 通过文件流你的意思是 SQL 文件流。是否可以在使用filestream的同时使用WCF直接通过sql流数据?

标签: sql-server wcf streaming large-files


【解决方案1】:

我认为这里有几个问题需要考虑:

  • 您实际想要返回的数据大小
  • 该数据的结构(或缺乏)
  • 在 NLB 后面存储数据的地方
  • 将该数据返回给消费者。

从您的问题来看,您似乎想要存储 1 GB 的结构化 (CSV) 数据并将其流式传输到客户端。如果您真的要生成然后提供 1GB 文件(并且周围没有太多元数据),我会使用 FTP/SFTP 服务器(或者可能是网络文件共享,当然可以通过多种方式保护的方式)。

如果您需要存储关于文件的元数据超出其文件名/创建时间/位置,那么 SQL 可能是一个不错的选择,假设您可以执行以下操作之一:

  • 将 CSV 数据以表格格式存储在数据库中
  • 使用FILESTREAM并存储文件本身

Here is a decent primer on FILESTREAM from SimpleTalk。然后,您可以使用SqlFileStream 帮助从文件本身流式传输数据(SQL Server 将帮助您保持事务一致性,您可能想要也可能不想要),documentation 中提供了一个示例。相关部分在这里:

private static void ReadFilestream(SqlConnectionStringBuilder connStringBuilder)
{
    using (SqlConnection connection = new SqlConnection(connStringBuilder.ToString()))
    {
        connection.Open();
        SqlCommand command = new SqlCommand("SELECT TOP(1) Photo.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM employees", connection);

        SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
        command.Transaction = tran;

        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                // Get the pointer for the file
                string path = reader.GetString(0);
                byte[] transactionContext = reader.GetSqlBytes(1).Buffer;

                // Create the SqlFileStream
                using (Stream fileStream = new SqlFileStream(path, transactionContext, FileAccess.Read, FileOptions.SequentialScan, allocationSize: 0))
                {
                    // Read the contents as bytes and write them to the console
                    for (long index = 0; index < fileStream.Length; index++)
                    {
                        Console.WriteLine(fileStream.ReadByte());
                    }
                }
            }
        }
        tran.Commit();
    }
}

或者,如果您确实选择以表格格式存储它,您可以使用典型的 SqlDataReader 方法,或者可能是 bcp 和 .NET 助手的某种组合。

您应该能够将最后一个链接与Microsoft's remarks on streaming large data over WCF 结合起来以获得所需的结果。

【讨论】:

  • 我会将文件另存为 BLOB,如果您不想,则无需将其准确存储到表中(还有更多工作要做)
猜你喜欢
  • 2012-02-11
  • 2018-07-15
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多