SQL Server2008新特性:fileStream

   忙了好长一阵子,silvelight项目总算告一段落了,在这个项目中,使用了sqlserver 2008,当然是觊觎它的新特性fileStream和hierarchyid.因此在最开始,没少去查阅msdn和做一些练习,所以元旦长假就打算做一个比较完整的练习,从安装sqlserver2008开始,在msdn的帮助下一步一步来完成.下面是完成fileStream练习的步骤:

1.SQL Server2008 enabled fileStream

  因为我在安装sql server 2008的时候,在配置filestream的时候就已经将sql server2008的选项打勾了。当然如果安装的时候没有选择enabled fileStream,可以在

sql server configuration manager(配置管理器)如图,或者在查询分析器里面执行下面的sql 语句

EXEC sp_configure filestream_access_level, 2 RECONFIGURE ;filestream_access_level 的值 详细参考msdn

 

2.Database enabled fileStream 

 下面是我的data base script,显然这里和一般的数据库多了一个'Group'(fileStream Data类型)

CREATE DATABASE [fileStreamTest] ON  PRIMARY
( NAME = N'fileStreamTest', FILENAME = N'C:\data\fileStreamTest.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ),
 FILEGROUP [fileStreamGroup1] CONTAINS FILESTREAM  DEFAULT
( NAME = N'fileStreamGroup', FILENAME = N'C:\data\fileStreamGroup' )
 LOG ON
( NAME = N'fileStreamTest_log', FILENAME = N'C:\data\fileStreamTest_log.ldf' , SIZE = 1024KB , MAXSIZE = 1GB , FILEGROWTH = 10%)
GO

注意的地方是c:\Data 目录必须存在,而filestream1'子目录在c:\Data则不能已存在

执行完毕查看c:\Data目录下面有fileStream1目录,打开发现有 有一个filestream.hdr f文件和一个名为 $FSLOG 的字文件夹.

3.Table enabled FileStream

在这里问题就来了(问题先不说),我按照 How to: Create a Table for Storing FILESTREAM Data这里讲的新建Records,脚本如下,按照msdn说明,Id列是一个ROWGUIDCOL列,Chart 作为文件存储的列不仅是VARBINARY(MAX)类型 ,同时还需要赋予一个fileStream特性.

CREATE TABLE .dbo.Records 

(

    [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE, 

    [SerialNumber] INTEGER UNIQUE,

    [Chart] VARBINARY(MAX) FILESTREAM NULL

)

4.通过ado.net来访问fileStream,我参考项目中用到的方法写了这个方法

ExpandedBlockStart.gif put
 1    static   void  put( string  fileName)
 2          {
 3              SqlConnection conn  =   null ;
 4              SqlTransaction tran  =   null ;
 5              SqlCommand cmd  =   null ;        
 6               try
 7              {
 8                   // get file content
 9                  FileStream input  =   new  FileStream(fileName, FileMode.Open, FileAccess.Read);
10                   byte [] buffer  =   new   byte [( int )input.Length];
11                  input.Read(buffer,  0 , buffer.Length);
12 
13                  conn  =  GetConnection();
14                  tran  =  conn.BeginTransaction();
15                   // call proc
16                  cmd  =   new  SqlCommand( " putFileStream " , conn, tran); // add a new record ,but filestream is null,return filestream.PathName
17                  cmd.CommandType  =  System.Data.CommandType.StoredProcedure;
18                  cmd.Parameters.Add( new  SqlParameter( " @serialNumber " new  Random().Next( 1000 )));             
19                  SqlDataReader r  =  cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
20                  r.Read();
21                   string  id  =  r[ 0 ].ToString();
22                   string  path  =  r[ 1 ].ToString();
23                  r.Close();
24 
25                   //  get the transaction context
26                  SqlCommand command  =   new  SqlCommand( @" select Chart.PathName(),GET_FILESTREAM_TRANSACTION_CONTEXT() from Records where id=@id " , conn, tran);
27                  command.Parameters.AddWithValue( " @id " , id);
28                   //  open a Filestream to write the blob
29                  SqlDataReader reader;
30                  reader  =  command.ExecuteReader(CommandBehavior.SingleRow);
31                  reader.Read();
32                  SqlString sqlFilePath  =  reader.GetSqlString( 0 );
33                  SqlBinary transactionToken  =  reader.GetSqlBinary( 1 );
34 
35                  reader.Close();
36 
37                   if  (transactionToken.Length  !=   0 )
38                  {
39                       // open a sqlfileStream
40                      SqlFileStream stream  =   new  SqlFileStream(sqlFilePath.Value, transactionToken.Value, FileAccess.Write, FileOptions.SequentialScan,  0 );
41                       // write file to sqlfilestream
42                      stream.Write(buffer,  0 , buffer.Length);
43                      stream.Close();
44                  }
45                  tran.Commit();
46                  conn.Close();
47              }
48               catch
49              {
50 
51              }
52          }

 

 我开始调用put方法,可结果数据库没有记录,这让我很好奇,我开启了sql profile并同时开始debug,发现都正常,可结果数据库没有记录,我把sqlprofile抓到的

sql exec putFileStream @serialNumber=555,拿到分析器查询,没有问题,不过当我用sql加入了一条记录之后,在用程序调用put方法结果就正常了,不知道什么原因总之郁闷了几个小时。

下面也贴一下读取fileStream的代码

 
ExpandedBlockStart.gifget
1 public byte[] getFileStream(Guid id)
 
2         {
 
3             SqlConnection conn = null;
 
4             SqlTransaction tran = null;
 
5             SqlCommand cmd = null;
 
6             byte[] bytes = null;// getFileStream
 7             conn = GetConnection();
 
8             tran = conn.BeginTransaction();
 
9 
10             cmd = new SqlCommand("SELECT [Chart].PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM [Records] WHERE [id] = @id;", conn, tran);
11             //cmd.CommandType = System.Data.CommandType.StoredProcedure;
12             cmd.Parameters.Add("@id", SqlDbType.UniqueIdentifier).Value = id;
13 
14             SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow);
15             if (rdr.Read())
16             {
17                 SqlString sqlFilePath = rdr.GetSqlString(0);
18                 SqlBinary transactionToken = rdr.GetSqlBinary(1);
19                 rdr.Close();
20 
21                 SqlFileStream fileStream = new SqlFileStream(sqlFilePath.Value, transactionToken.Value, FileAccess.Read);
22                 bytes = new byte[fileStream.Length];
23                 fileStream.Read(bytes, 0, bytes.Length);
24                 fileStream.Close();//if fileStream have not close,tran.Commit throw process error
25                 tran.Commit();
26             }
27             conn.Close();
28             return bytes;
29         }
30 
31 

 

 

 参考文档http://technet.microsoft.com/en-us/library/cc645923.aspx

 

 

 

转载于:https://www.cnblogs.com/subway-2008/archive/2010/01/04/fileStream.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值