c#操作⽂件存⼊数据库(以⼆进制形式存⼊)
在开发的过程中,经常会遇到将⽂件存⼊数据库的形式,⼀般常⽤⽅法是将⽂件上传⾄服务器,数据库只需保存⽂件路径地址即可,但是很多内部window应⽤并不链接⽹络都是本地运⾏服务,那么此时我们存储⽂件就需要⽤到另⼀种形式,即将⽂件 FileStream 操作⽂件流的形式将⽂件转为字节存⼊数据库,下载时,在对应转换下载即可。
本次,我们将提供两种数据库的操作⽅式,PostgresSql 和 Sqlite 两种数据库的存储⽅式。
PostgresSql
Psql 数据库提供了存储字节的类型,即 bytea,所以创建数据库时,要将对应的字段设置为 bytea
1CREATE TABLE tb_flypath
2 (
3 ID SERIAL PRIMARY KEY ,
4 FileName TEXT NOT NULL,
5 FileContent bytea NOT NULL,
6 CreateTime timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP
7 )
那么,设置为 bytea 后就可以将⽂件转为字节进⾏存储了,使⽤以下代码
getsavefilename1///<summary>
2///将⽂件转为字节
3///</summary>
4///<param name="path">⽂件路径</param>
5///<returns></returns>
6public byte[] getContent(string path)
7 {
8 System.IO.FileStream fs = new System.IO.FileStream(@path, System.IO.FileMode.Open);
9 fs.Position = 0;
10byte[] content = new byte[fs.Length];
11 fs.Read(content, 0, (int)fs.Length);
12 fs.Close();
13return content;
14 }
我们直接使⽤ SQL 语句,将字节转为字符串存⼊数据库
1///<summary>
2///字节转字符串
3///</summary>
4///<param name="inputBytes">字节</param>
5///<returns></returns>
6public string ByteToString(byte[] inputBytes)
7 {
8 StringBuilder temp = new StringBuilder(2048);
9foreach (byte tempByte in inputBytes)
10 {
11 temp.Append(tempByte > 15 ?
12 Convert.ToString(tempByte, 2) : '0' + Convert.ToString(tempByte, 2));
13 }
14return temp.ToString();
15 }
16
17string bstr = ByteToString(buffer);
18string insertSql = string.Format(@"INSERT INTO tb_flyPath (FileContent) VALUES ('{0}')", bstr);
以上就是将⽂件写⼊数据库的操作,但是,如果采⽤此⽅法的话,就会有问题,因为 INSERT SQL ⽆法识别字节的类型,所以我们是将字符串存⼊了对应字节类型的字段⾥。
那么后续遇到的问题是,下载⽂件时,⽆论如何转换 FileContent 都⽆法将下载的⽂件打开,如果是⽂本的话,则出现的内容为已转换的⼆进制数据。
⾄于为什么会出现这样,还没研究透,欢迎留⾔。
所以,我⼜采取了以下的⽅式进⾏数据存储,使⽤数据库 Parameter 参数执⾏SQL,这种⽅法可以将你传⼊的数据直接转为对应的类型 DbType.Bytea ,此类型可以传⼊字节类型数据进⾏存储,使⽤这种⽅式后,存⼊的数据就可以下载后进⾏转换使⽤并打开各种⽂件了。
1///<summary>
2///⽂件存储⼊表
3///</summary>
4///<param name="filePath">⽂件路径</param>
5///<param name="id">节点ID</param>
6///<returns></returns>
7public bool FileInsert(string filePath, string id)
8 {
9string strErrMsg = "";
10//读取⽂件
11 FileStream fs = File.OpenRead(filePath);
12byte[] buffer = new byte[fs.Length];
13 fs.Read(buffer, 0, buffer.Length);
14
15if (!CreateCommand(out strErrMsg))
16return false;
17
31 NpgsqlParameter paramFileContent = _Command.CreateParameter();
32 paramFileContent.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bytea;
33 paramFileContent.ParameterName = "FileContent";
34 paramFileContent.Direction = ParameterDirection.Input;
35 paramFileContent.Value = buffer;
36 _Command.Parameters.Add(paramFileContent);
37
38 NpgsqlParameter paramFileName = _Command.CreateParameter();
39 paramFileName.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Varchar;
40 paramFileName.ParameterName = "FileName";
41 paramFileName.Direction = ParameterDirection.Input;
42 paramFileName.Value = id;
43 _Command.Parameters.Add(paramFileName);
44
45string sqlInsert = "INSERT INTO tb_flypath (filename,filecontent) VALUES (:FileName, :FileContent)";
46 _Command.CommandText = sqlInsert;
47 _Command.CommandType = CommandType.Text;
48
49 _Connection.Open();
50int result = _Command.ExecuteNonQuery();
51 _Connection.Close();
52
53return result > 0 ? true : false;
54 }
55
56///<summary>
57///根据⽂件名从数据库中获取⽂件
58///</summary>
59///<param name="fileName">数据库中的⽂件名</param>
60///<param name="savePath">⽂件的保存路径,包括⽂件名,如D:\test.fly</param>
61public bool DownloadFile(string fileName, string savePath)
62 {
63string strErrMsg = "";
64
65if (!CreateCommand(out strErrMsg))
66return false;70
71string sqlSelect = "select filename, filecontent from tb_flypath where filename=:FileName";
72 _Command.CommandText = sqlSelect;
73 _Command.CommandType = CommandType.Text;
74
75 NpgsqlParameter paramFileName = _Command.CreateParameter();
76 paramFileName.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Varchar;
77 paramFileName.ParameterName = "FileName";
78 paramFileName.Direction = ParameterDirection.Input;
79 paramFileName.Value = fileName;
80 _Command.Parameters.Add(paramFileName);
81
82 _Connection.Open();
83 NpgsqlDataReader dr = _Command.ExecuteReader();
84 dr.Read();
85byte[] buffer = (byte[])dr["filecontent"];
86 dr.Close();
87 _Connection.Close();
88
89//把⽂件保存到指定路径
90 File.WriteAllBytes(savePath, buffer);
91
92return true;
93 }
Sqlite
我们在讲下 Sqlite 数据库的操作⽅式,其实⽅法都⼀样,没什么太⼤区别,只是各个数据库的存储数据类型不太⼀样。 Sqlite 提供了 BLOB 类型进⾏存储字节数据,所以创建表。
1CREATE TABLE tb_flyPath
2 (
3 ID INTEGER primary key autoincrement ,
4 FileName VARCHAR not null ,
5 FileContent BLOB not null ,
6 CreateTime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
7 )
那么存取⽂件的⽅法⼤致⽆区别,PostgresSql ⽤的是 bytea 类型,那么 Sqlite 这⾥需要设置为 DbType.Binary 类型。 1///<summary>
2///⽂件存储⼊表
3///</summary>
4///<param name="filePath">⽂件路径</param>
5///<param name="id">节点ID</param>
6///<returns></returns>
7public bool FileInsert(string filePath, string id)
8 {
9string strErrMsg = "";
10//读取⽂件
11 FileStream fs = File.OpenRead(filePath);
12byte[] buffer = new byte[fs.Length];
13 fs.Read(buffer, 0, buffer.Length);
14
15if (!CreateCommand(out strErrMsg))
16return false;
17
31 SQLiteParameter paramFileContent = _Command.CreateParameter();
32 paramFileContent.DbType = DbType.Binary;
33 paramFileContent.ParameterName = "FileContent";
34 paramFileContent.Direction = ParameterDirection.Input;
35 paramFileContent.Value = buffer;
36 _Command.Parameters.Add(paramFileContent);
37
38 SQLiteParameter paramFileName = _Command.CreateParameter();
39 paramFileName.DbType = DbType.String;
40 paramFileName.ParameterName = "FileName";
41 paramFileName.Direction = ParameterDirection.Input;
42 paramFileName.Value = id;
43 _Command.Parameters.Add(paramFileName);
44
45string sqlInsert = "INSERT INTO tb_flyPath (filename,filecontent) VALUES (:FileName, :FileContent)";
46 _Command.CommandText = sqlInsert;
47 _Command.CommandType = CommandType.Text;
48
49 _Connection.Open();
50int result = _Command.ExecuteNonQuery();
51 _Connection.Close();
52
53return result > 0 ? true : false;
54 }
55
56///<summary>
57///根据⽂件名从数据库中获取⽂件
58///</summary>
59///<param name="fileName">数据库中的⽂件名</param>
60///<param name="savePath">⽂件的保存路径,包括⽂件名,如D:\test.fly</param>
61public bool DownloadFile(string fileName, string savePath)
62 {
63string strErrMsg = "";
64
65if (!CreateCommand(out strErrMsg))
66return false;
67
71string sqlSelect = "select filename, filecontent from tb_flyPath where filename=:FileName";
72 _Command.CommandText = sqlSelect;
73 _Command.CommandType = CommandType.Text;
74
75 SQLiteParameter paramFileName = _Command.CreateParameter();
76 paramFileName.DbType = DbType.String;
77 paramFileName.ParameterName = "FileName";
78 paramFileName.Direction = ParameterDirection.Input;
79 paramFileName.Value = fileName;
80 _Command.Parameters.Add(paramFileName);
81
82 _Connection.Open();
83 SQLiteDataReader dr = _Command.ExecuteReader();
84 dr.Read();
85byte[] buffer = (byte[])dr["filecontent"];
86 dr.Close();
87 _Connection.Close();
88
89//把⽂件保存到指定路径
90 File.WriteAllBytes(savePath, buffer);
91
92return true;
93 }
如有讲的不对,欢迎评论留⾔。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论