文件存入數據庫本質是:讀取文件為位元組陣列(二進制流) → 寫入數據庫二進制字段。讀取則是反向操作。SQL Server 用 Image 類型(現推薦 VarBinary(MAX)),Access 用 OLE Object。
public void SaveFileToSqlServer(string filePath, string tableName, string fieldName, SqlConnection conn) {
FileInfo fi = new FileInfo(filePath);
using (FileStream fs = fi.OpenRead()) {
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandText = $"INSERT INTO {tableName} ({fieldName}) VALUES (@file)";
SqlParameter param = new SqlParameter("@file", SqlDbType.VarBinary) { Value = buffer };
cmd.Parameters.Add(param);
if (conn.State == ConnectionState.Closed) conn.Open();
cmd.ExecuteNonQuery();
}
}
}
public void SaveFileToAccess(string filePath, string tableName, string fieldName, OleDbConnection conn) {
FileInfo fi = new FileInfo(filePath);
using (FileStream fs = fi.OpenRead()) {
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
using (OleDbCommand cmd = new OleDbCommand()) {
cmd.Connection = conn;
cmd.CommandText = $"INSERT INTO {tableName} ({fieldName}) VALUES (@file)";
OleDbParameter param = new OleDbParameter("@file", OleDbType.Binary) { Value = buffer };
cmd.Parameters.Add(param);
if (conn.State == ConnectionState.Closed) conn.Open();
cmd.ExecuteNonQuery();
}
}
}
public void SaveUploadedFile(HttpPostedFile postedFile, int mailId, string connStr) {
string sql = "UPDATE t_mail SET attachfilename=@name, attachfile=@file WHERE mailid=@id";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
string fileName = System.IO.Path.GetFileName(postedFile.FileName);
cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = fileName;
cmd.Parameters.Add("@file", SqlDbType.VarBinary);
using (Stream fs = postedFile.InputStream) {
byte[] buffer = new byte[postedFile.ContentLength];
fs.Read(buffer, 0, buffer.Length);
cmd.Parameters["@file"].Value = buffer;
}
cmd.Parameters.Add("@id", SqlDbType.Int).Value = mailId;
conn.Open();
cmd.ExecuteNonQuery();
}
}
public void ExtractFileFromDb(string tableName, string fieldName, int id, string outputPath, SqlConnection conn) {
using (SqlCommand cmd = new SqlCommand($"SELECT {fieldName} FROM {tableName} WHERE ID=@id", conn)) {
cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
if (conn.State == ConnectionState.Closed) conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader()) {
if (dr.Read()) {
byte[] fileData = (byte[])dr[0];
// 關鍵:使用 FileMode.CreateNew 確保新建文件,BinaryWriter 正確寫入二進制
using (FileStream fs = new FileStream(outputPath, FileMode.CreateNew))
using (BinaryWriter bw = new BinaryWriter(fs)) {
bw.Write(fileData);
}
}
}
}
}
關鍵修正: 原代碼用 FileInfo.OpenWrite() 可能導致現有文件追加而非覆蓋,改用 FileStream(FileMode.CreateNew) + BinaryWriter 確保正確另存為 Word/Excel/圖片等原始格式。
using System.Data.SqlClient;
using System.Data.OleDb;
using System.IO;
Read/Write 循環),避免記憶體壓力。using 確保釋放。