1. 程式人生 > >c#中winform方式的檔案上傳和下載高效最新方法

c#中winform方式的檔案上傳和下載高效最新方法

網上很多檔案上傳下載的文章,多數是採用http方式,使用.net的webcliend的功能,此功能對大檔案效率比較低,對web伺服器安全性也有影響。

我採用資料庫的方式同樣實現並高效的處理了此功能,對於資料庫winform應用值得借鑑。

開發思路(以下思路是c/s三層架構,中間需要有webservice服務):

1 把資料存於資料庫也可以不存入資料庫,如果存入資料庫就要在表中增加image欄位存放byte資料。

2 採filestream對像,對檔案進行讀寫操作,不管是存入資料庫還是以檔案形式上傳到伺服器的檔案系統中

  上傳部分選擇檔案都是相同的,都需要用到資料表,如果要存入資料庫就要建表,如果不存入資料庫可以

  用sql語句虛擬一個表結構:如Select  file_Id=0,file_name='',convert(image,null) file_data  where 1<>1

3  如果是把檔案存入web伺服器,在webservice中需要有上傳和下載的函式。上傳時就是把dataset中的byte還原

 成檔案流fileStream,再把檔案寫入檔案系統(此方式要設定iis對檔案系統的寫的許可權,不然會提示拒絕訪問);

  下載就是根據檔名用fileStream把檔案從檔案系統中讀取來,再以byte的形式放入dataset.table中。

4 檔案的另存,檔案的另存把datatabel中的byte寫入filestream中,再寫入客戶端的檔案系統中。

以下是開發的全程式碼:

 1 此段是用檔案開啟控制元件選擇檔案,把檔案寫入table的對應的路徑中。

 private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog filedlg = new OpenFileDialog();
            filedlg.Multiselect = true;
            if (filedlg.ShowDialog() == DialogResult.OK)
            {
                    string[] filenames = filedlg.FileNames;           
                   
                    for (int i = 0; i < filenames.Length; i++)
                    {
                       string fileName = filenames[i];
                       int n = fileName.LastIndexOf(@"\");           
                       string file = fileName.Substring(n + 1, fileName.Length - n - 1);
                       sDH=dgvMSG.CurrentRow.Cells["MSG_DH"].Value.ToString();
                        if (File.Exists(fileName))
                        {  
                           DataRow[]  dr1=dsMSG .Tables ["MSG_DOC"].Select ("MSGDOC_DH='"+sDH +"' AND MSGDOC_FILENAME='"+file +"'");
                           if (dr1.Length <=0)
                           {
                               DataRow dr = dsMSG.Tables["MSG_DOC"].NewRow();
                               dr["MSGDOC_DH"] = sDH;
                               dr["MSGDOC_FILENAME"] = file;

                               FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                               byte[] bt = new byte[fs.Length];
                               fs.Position = 0;
                               fs.Read(bt, 0, Convert.ToInt32(fs.Length));
                               dr["MSGDOC_FILE"] = bt;
                               dsMSG.Tables["MSG_DOC"].Rows.Add(dr);
                               lbFILES.Items.Add(file);
                           }
                        }
                    }
                    btnSAVEAS.Enabled = (lbFILES.Items.Count > 0);
            }
        }
2 下面是把table中的檔案流另存到客戶端檔案
   private void btnSAVEAS_Click(object sender, EventArgs e)
        {
            if (lbFILES.SelectedItems.Count > 0 && dgvMSG .Rows .Count >0)
            {
                string sDH = dgvMSG.CurrentRow.Cells["MSG_DH"].Value.ToString();             
                FolderBrowserDialog fld = new FolderBrowserDialog();
                if (fld.ShowDialog ()== DialogResult.OK)
                {
                    waiting w = new waiting();
                    try
                    {
                        w.Show();
                        DataSet dsMSG_DOC = Query_MSG_DOC(sDH);
                        string path = fld.SelectedPath;
                        if (!path.EndsWith(@"\"))//判斷是否為根目錄,如果不是根目錄要新增分隔符"\"
                            path += @"\";
                        for (int i = 0; i < lbFILES.SelectedItems.Count; i++)
                        {
                            string sFilename = lbFILES.SelectedItems[i].ToString();
                            DataRow[] dr = dsMSG_DOC.Tables["MSG_DOC"].Select("MSGDOC_DH='" + sDH + "' AND MSGDOC_FILENAME='" + sFilename + "'");
                            if (dr.Length > 0 && dr[0]["MSGDOC_FILE"] != null)
                            {
                                byte[] btFile = (byte[])dr[0]["MSGDOC_FILE"];
                                FileStream fs = new FileStream(path + sFilename, FileMode.Create);
                                fs.Write(btFile, 0, btFile.Length);
                                fs.Close();
                            }
                        }

                    }
                    finally
                    {
                        w.Close();
                    }
                }
            }
        }

3  下面是如何移除檔案列表和資料表中的資料
  private void btnRemove_Click(object sender, EventArgs e)
        {
            if (!isinBrowse)
            {
                for (int i = 0; i < lbFILES.SelectedItems.Count; i++)
                {
                
                    string filename = lbFILES.SelectedItems[i].ToString();
                    
                    string sDH = dgvMSG.CurrentRow.Cells["MSG_DH"].Value.ToString();

                    DataRow[] dr = dsMSG.Tables["MSG_DOC"].Select("MSGDOC_DH='" + sDH + "' AND MSGDOC_FILENAME='" + filename + "'");
                    if (dr.Length > 0)
                    {
                        string sID=Convert.ToString (dr[0]["MSGDOC_ID"]);
                        dsMSG.Tables["MSG_DOC"].Rows.Remove(dr[0]);
                        string sql = "Delete FROM MSG_DOC WHERE MSGDOC_DH='" + sDH + "'"
                            + " AND MSGDOC_ID=" + sID ;
                        string msgError = "";
                        POS.SQLcmd_1(BASEINFO.DESEncrypt(sql), Program.userinfo.P_user.U_ID.ToString(), out msgError);
                        //lbFILES.Items.Remove(lbFILES.SelectedItems[i]);
                    }
                }
                object[] selected_objs = new object[lbFILES.SelectedItems.Count];
                lbFILES.SelectedItems.CopyTo(selected_objs, 0);
                foreach (object oval in selected_objs)
                {
                    lbFILES.Items.Remove(oval);
                }
                SetToolsBtn();

            }
        }
4 下面webserve把檔案流存入伺服器的檔案系統中
 [WebMethod]
    public bool UplodeFiles(byte[] btData, out string errorMsg)
    {
        
        try
        {
           

            DataSet dsFILE = serverbase.DecompressDS(btData);
            DataRow drs = dsFILE.Tables[0].Rows[0];
            byte []btFile=(byte[])dsFILE.Tables[0].Rows[0]["FILE_DATA"];
            string fileName = Convert.ToString (dsFILE.Tables[0].Rows[0]["FILENAME"]);
            FileStream fs = new FileStream(@"D:\" + fileName,FileMode.CreateNew); \\此處為了測試方便用的固定路徑,業務上可以通過引數傳路徑
            fs.Write(btFile, 0, btFile.Length);
            fs.Close();  
            errorMsg = "";     
            return true;                                  
        }
        catch (Exception E)
        {
            errorMsg = E.Message.ToString();       
            return false;
        }
        finally
        {
          
        }

    }
5 如果只是存入伺服器的檔案系統,在第1段程式碼後面,呼叫webserve的上傳函式就可以了。

      增下下面程式碼 你的webservice.UplodeFiles(BASEINFO.SerializationDataset(dsFILE), out msgError);

6下載檔案伺服器檔案到客戶端就是反過來就好了。

7直接雙擊檔案列表開啟檔案方法如下:

 private void lbFILES_DoubleClick(object sender, EventArgs e)
        {
            if (isinBrowse && lbFILES.Items.Count > 0 && dgvMSG.Rows.Count > 0)
            {
                string sDH = dgvMSG.CurrentRow.Cells["MSG_DH"].Value.ToString();
                DataSet dsMSG_DOC = Query_MSG_DOC(sDH);
                string path = System.IO.Path.GetTempPath();//Environment.GetEnvironmentVariable("TEMP");
                if (!path.EndsWith(@"\"))//判斷是否為根目錄,如果不是根目錄要新增分隔符"\"
                    path += @"\";

                string sFilename = lbFILES.Items[lbFILES.SelectedIndex].ToString ();
                DataRow[] dr = dsMSG_DOC.Tables["MSG_DOC"].Select("MSGDOC_DH='" + sDH + "' AND MSGDOC_FILENAME='" + sFilename + "'");
                if (dr.Length > 0 && dr[0]["MSGDOC_FILE"] != null)
                {
                    byte[] btFile = (byte[])dr[0]["MSGDOC_FILE"];
                    FileStream fs = new FileStream(path + sFilename, FileMode.Create);
                    fs.Write(btFile, 0, btFile.Length);
                    System.Diagnostics.Process.Start(path + sFilename);
                    fs.Close();
                }
            }                                     
        }