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();
                }
            }                                     
        }            


 






你可能感兴趣的:(c#中winform方式的文件上传和下载高效最新方法)