首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# OpenFileDialog 獲取圖片路徑並以二進制存入數據庫完整實現

     編輯:程式設計綜合問答

核心步驟三部曲

  1. **選擇文件** → `OpenFileDialog` 獲取路徑
  2. **讀取二進制** → `File.ReadAllBytes`
  3. **參數化入庫** → `SqlCommand` + `varbinary(max)`

完整 WinForms 代碼示例

using System;
using System.Data.SqlClient;
using System.IO;
using System.Windows.Forms;

namespace ImageToDbDemo {
    public partial class MainForm : Form {
        private const string ConnStr = 
            "Server=.;Database=TestDb;Trusted_Connection=True;";

        public MainForm() { InitializeComponent(); }

        private void btnSelectAndSave_Click(object sender, EventArgs e) {
            using (var ofd = new OpenFileDialog()) {
                ofd.Filter = "圖片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif|所有文件|*.*";
                ofd.Title = "選擇要存入數據庫的圖片";
                if (ofd.ShowDialog() != DialogResult.OK) return;

                string filePath = ofd.FileName; // ① 獲取完整路徑
                byte[] imageBytes = File.ReadAllBytes(filePath); // ② 讀取二進制

                SaveToDatabase(filePath, imageBytes); // ③ 入庫
                MessageBox.Show($"已存入:{Path.GetFileName(filePath)} ({imageBytes.Length} bytes)");
            }
        }

        private void SaveToDatabase(string fileName, byte[] data) {
            const string sql = @"
                INSERT INTO Images (FileName, ContentType, Data, UploadTime)
                VALUES (@FileName, @ContentType, @Data, GETDATE())";

            using (var conn = new SqlConnection(ConnStr))
            using (var cmd = new SqlCommand(sql, conn)) {
                cmd.Parameters.Add("@FileName", System.Data.SqlDbType.NVarChar, 255).Value = fileName;
                cmd.Parameters.Add("@ContentType", System.Data.SqlDbType.NVarChar, 50).Value = GetMimeType(fileName);
                cmd.Parameters.Add("@Data", System.Data.SqlDbType.VarBinary, -1).Value = data; // -1 = MAX
                conn.Open();
                cmd.ExecuteNonQuery();
            }
        }

        private string GetMimeType(string fileName) {
            string ext = Path.GetExtension(fileName).ToLowerInvariant();
            return ext switch {
                ".jpg" or ".jpeg" => "image/jpeg",
                ".png" => "image/png",
                ".bmp" => "image/bmp",
                ".gif" => "image/gif",
                _ => "application/octet-stream"
            };
        }
    }
}

數據庫表結構建議

CREATE TABLE Images (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    FileName NVARCHAR(255) NOT NULL,
    ContentType NVARCHAR(50) NOT NULL,
    Data VARBINARY(MAX) NOT NULL,  -- 關鍵:MAX 支持 2GB
    UploadTime DATETIME DEFAULT GETDATE()
);
CREATE INDEX IX_Images_FileName ON Images(FileName);

讀取並顯示/下載

private void btnLoad_Click(object sender, EventArgs e) {
    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand("SELECT FileName, ContentType, Data FROM Images WHERE Id=@Id", conn)) {
        cmd.Parameters.AddWithValue("@Id", txtId.Text);
        conn.Open();
        using (var reader = cmd.ExecuteReader()) {
            if (reader.Read()) {
                string name = reader.GetString(0);
                string mime = reader.GetString(1);
                byte[] data = (byte[])reader[2]; // 直接讀取 byte[]

                // 保存到臨時文件並打開
                string tempPath = Path.Combine(Path.GetTempPath(), name);
                File.WriteAllBytes(tempPath, data);
                Process.Start(new ProcessStartInfo(tempPath) { UseShellExecute = true });
            }
        }
    }
}

大文件優化(> 10MB)

技術作用
`FileStream` + `SqlFileStream` (Filestream)文件存文件系統,DB 只存指針,突破 2GB 限制
分塊上傳前端分片、後端合併,避免 LOH 內存碎片
異步 `ReadAllBytesAsync` / `ExecuteNonQueryAsync`不阻塞 UI 線程
壓縮 (GZip/Deflate)節省存儲與傳輸帶寬

常見錯誤與修復

  • ❌ `cmd.Parameters.AddWithValue("@Data", data)` → ✅ 顯式指定 `SqlDbType.VarBinary, -1` 避免類型推斷錯誤
  • ❌ 連接字符串寫死 → ✅ 存 `appsettings.json` / `web.config`,區分環境
  • ❌ 直接拼接 SQL → ✅ **永遠使用參數化查詢**,防注入、處理特殊字符
  • ❌ 忘記 `using` 釋放連接 → ✅ 連接、命令、讀取器全部包在 `using` 中

總結

`OpenFileDialog.FileName` 即路徑,`File.ReadAllBytes` 即二進制,`SqlDbType.VarBinary` 配合參數化 SQL 即入庫。**三行核心代碼,其餘皆是工程化細節**(異常處理、大文件優化、安全配置)。掌握這條主線,圖片/文件存數據庫不再是難題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved