在文件系统上使用filestream存储pdf文件

时间:2011-12-16 05:21:12

标签: pdf filestream

我是第一次尝试使用filestream使用varbinary(MAX)列类型的DB在文件系统上存储pdf文件。

我已按照以下步骤操作。

  1. 在SQL Server 2008 R2上启用了文件流功能。
  2. 为BLOB存储创建文件组
  3. 使用varbinary(max)
  4. 类型的blob列创建表

    现在,我想使用文件上传控件来选择文件,当点击上传按钮时,它应该保存pdf文件。另外,如何检索文件?


    我尝试过以下代码

    protected void btnFSupload_Click(object sender, EventArgs e)
        {
            SqlConnection cn = null;
            SqlTransaction tx = null;
            SqlCommand cmd = null;
            SqlCommand cmd2 = null;
            bool bCommit = false;
    
            try
            {
                // read in the file to be saved as a blob in the database
                FileStream input = new FileStream(@"D:\swami.pdf", FileMode.Open, FileAccess.Read);
                byte[] buffer = new byte[(int)input.Length];
    
                input.Read(buffer, 0, buffer.Length);
    
                cn = new SqlConnection("server=at-hetal01\\sqlexpress;Initial Catalog=practice;Integrated Security=true;");
                cn.Open();
    
                tx = cn.BeginTransaction();
    
                cmd = new SqlCommand("dbo.stp_AddBLOB", cn, tx);
    
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
    
                SqlDataReader r = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
    
                r.Read();
    
                string id = r[0].ToString();
                string path = r[1].ToString();
                r.Close();  
    
                // get the transaction context
                cmd2 = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()", cn, tx);
                Object obj = cmd2.ExecuteScalar();
                byte[] txCtx = (byte[])obj;
    
                // open the filestream to the blob
                SafeFileHandle handle = OpenSqlFilestream(path,DESIRED_ACCESS_WRITE,SQL_FILESTREAM_OPEN_NO_FLAGS,txCtx,(UInt32)txCtx.Length,0);
    
                // open a Filestream to write the blob
                FileStream output = new FileStream(handle,FileAccess.Write,buffer.Length,false);
                output.Write(buffer,0,buffer.Length);
                output.Close();
    
                if (handle != null && !handle.IsClosed)
                    handle.Close();
    
                bCommit = true;
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
            }
            finally
            {
                if (cn != null)
                {
                    switch (bCommit)
                    {
                        case true:
                            tx.Commit();
                            break;
    
                        case false:
                            tx.Rollback();
                            break;
                    }
    
                    cn.Close();
                }
            }
    
        }
    

    以上代码显示如下错误

    操作系统在'D:\ DB \ FS \ d11132f8-c2a8-452d-ae0c-208164a550d7上尝试'NtCreateFile'时返回错误'0xc000003a({Path Not Found}路径%hs不存在。)' \ beb8e1f1-8116-440b-870B-7cef4281a15d \ 0000001c-000000e4-010d”。该语句已终止。

    那么,有什么线索吗?

2 个答案:

答案 0 :(得分:0)

如果您使用SSMS表设计器更改了表,则FILESTEAM列属性将丢失,从而产生未找到的路径。通过在数据库中运行follwoing语句,确保为文件字段设置了FILESTREAM属性:

select SERVERPROPERTY('FilestreamShareName') as ShareName,
       SERVERPROPERTY('FilestreamConfiguredLevel') as ConfiguredLevel,
       SERVERPROPERTY('FilestreamEffectiveLevel') as EffectiveLevel

您需要通过脚本而不是SSMS更改表,以将varchar(max)/ filestream字段绑定到您应该已创建的FileGroup。

当我遇到这个问题时,我在StackOverflow上找到了答案,但似乎无法再找到它作为参考。

答案 1 :(得分:0)

我知道这是旧的,但供将来参考:

我们检查了@BMP建议的SERVERPROPERTY值。它们配置正确,因此无济于事。

但是,我们继续关闭了Windows文件共享文件流访问的一部分。一旦完成,错误就消失了。

在我们的例子中,它是一个在与sql服务器完全相同的机器上运行的Web应用程序,它出现了问题。我不确定网络应用程序的应用程序池用户是否无法访问由Windows创建的文件共享。

细节是:

Windows 2003 Server(x86)
IIS 6
SQL Server 2008 R2 Express


更新:显然这工作了几天。它不再起作用了。