將文件上傳到數據庫 和 從數據庫下載文件到本地


  有時候我們需要把圖片、文檔、dll文件、等等,上傳的數據庫,然后當需要的時候再從數據庫中讀取到本地,下面我以上傳圖片為例,講解一下如何把本地的一張圖片上傳到數據庫,然后再從數據庫下載到本地。

  工具:VS2010,Sql Server 2000。語言:C#。

  像這樣的文件,我們上傳的時候都是以二進制的形式操作,在數據庫中對應的數據類型為image,我們只需要把本地文件轉為二進制形式,然后以image數據保存到數據庫就行。

  Sql Server 2000自帶的數據庫Northwind,有一張表Categories,其中有一個字段Picture為image類型,我們就以它為例,上傳一張圖片到這個表中。

  1 打開vs2010新建一個項目“Windows窗體應用程序”,在窗體Form1上放置兩個按鈕,分別改變文本為"上傳“ 和 "下載",添加對應的單擊事件。

  2 新建一個類,這個類用來封裝對文件上傳和下載的功能調用,然后我們可以在前面的單擊事件中調用這個方法。下面是這個類的完整定義:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.IO;
using System.Data;

namespace test
{
    class UpDownLoad
    {
        public string categoryName;  //下載時可以再外部指定文件名
        private string description;
        private byte[] picture;

        public SqlConnection GetConn()  //得到連接對象
        {
            SqlConnection conn = new SqlConnection("Data Source =.;Initial Catalog = Northwind;user id = sa;");
            try
            {
                conn.Open();
            }
            catch (Exception e)
            {
                MessageBox.Show("連接數據庫失敗:{0}", e.Message);                
                conn.Close();
            }
            return conn;
        }


        private static string GetFilePath() //通過打開對話框得到文件路徑
        {
            string filepath = "";
            OpenFileDialog openfiledlg = new OpenFileDialog();
            if (openfiledlg.ShowDialog() == DialogResult.OK)
            {
                filepath = openfiledlg.FileName;
               
            }
            return filepath;          
        }

        private static Byte[] GetContent(string filepath)  //將某路徑下的文件 轉化為 二進制代碼 
        {
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read); //打開文件流
            Byte[] byData = new Byte[fs.Length]; //保存文件的字節數組
            fs.Read(byData, 0, byData.Length); //讀取文件流           
            fs.Close();//釋放資源
            return byData;
        }

        public void UpLoad() //上傳
        {
            string filePath = GetFilePath();//得到文件路徑
            
            FileInfo fi = new FileInfo(filePath);//文件信息對象
            this.categoryName = fi.Name; //獲取文件名

            this.description = "這是我上傳到數據庫的第一張照片";

            this.picture = GetContent(filePath);//通過路徑獲取文件二進制形式

            SqlConnection conn = GetConn();
            string sqlstr = string.Format("insert into Categories(CategoryName,Description,Picture) values(@fileName,@descri,@pic)");
            SqlCommand comm = new SqlCommand(sqlstr, conn);

            comm.Parameters.Add("fileName", SqlDbType.VarChar);//添加變量
            comm.Parameters["fileName"].Value = this.categoryName;

            comm.Parameters.AddWithValue("descri", this.description);//添加變量

            comm.Parameters.AddWithValue("pic", this.picture);

            if (comm.ExecuteNonQuery() == 1)
            {
                MessageBox.Show("添加一張照片成功。");
            }
            conn.Close();//關閉數據庫
        }

        public  void DownLoad()  //下載圖片
        {
            if (categoryName == "")
            {
                MessageBox.Show("請先對下載的文件填寫文件名");
                return;
            }
            SqlConnection conn = GetConn();
            string sqlstr = string.Format("select * from Categories where CategoryName = @fileName");
            SqlCommand comm = new SqlCommand(sqlstr, conn);

            comm.Parameters.AddWithValue("@fileName", this.categoryName);

            SqlDataReader dr = comm.ExecuteReader();

            if (dr.HasRows)
            {
                if (dr.Read())//讀一行數據
                {
                    this.picture = (byte []) dr["Picture"];
                    
                    FileStream fs = new FileStream(categoryName, FileMode.Create, FileAccess.Write);
                    fs.Write(picture, 0, picture.Length);
                    fs.Close();//一定要關閉,否則不會將流讀入文件

                    dr.Close();
                    conn.Close();                        
                }

            }//if
            else
            {
                MessageBox.Show("沒有這個文件");
                return;
            }

        }
    
    }
}

  3 如果這個類的命名空間與主程序的命名空間名不同,要在主程序添加引用:using test;

然后在前面的兩個單擊事件中分別添加如下代碼,

(1)在上傳按鈕對應的button1中先聲明一個對象,然后調用:

private void button1_Click(object sender, EventArgs e)
{
            UpDownLoad updown = new UpDownLoad();
            updown.UpLoad();
}

(2)在下載對應的button2中聲明一個對象,然后給要下載的文件賦值,再調用:

private void button2_Click(object sender, EventArgs e)
{
            UpDownLoad updown = new UpDownLoad() ;
            updown.categoryName = "金河.jpg";//最好是自己剛才上傳的文件的名字
            updown.DownLoad();
}

然后在本程序的Debug目錄下面就會出現從數據庫中下載到本地的圖片。

 

  總結:最初我想把dll文件上傳到數據庫,然后通過從數據庫下載dll文件到本地實現程序的自動更新,但是當時下載的時候忘記關閉FileStream對象流,結果下載到的文件為空,后來又牽涉到很多其他的邏輯問題,后來感覺到很崩潰,不過當我靜下心來將問題簡單化(先實現最簡單的,不牽涉很多邏輯問題功能,然后在通過邏輯來調用功能),這樣子下來感覺問題簡單多了。學習的時候切忌浮躁。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM