• 将文件上传到数据库 和 从数据库下载文件到本地


      有时候我们需要把图片、文档、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对象流,结果下载到的文件为空,后来又牵涉到很多其他的逻辑问题,后来感觉到很崩溃,不过当我静下心来将问题简单化(先实现最简单的,不牵涉很多逻辑问题功能,然后在通过逻辑来调用功能),这样子下来感觉问题简单多了。学习的时候切忌浮躁。

  • 相关阅读:
    Java中try-catch-finally的一点理解
    子类继承父类的私有属性
    Java中的String[] args
    Java类和类成员的访问权限修饰符
    JAVA中抽象类与接口的区别
    Java C# .net 和 C C++ 跨平台的区别
    Java中的instanceof关键字
    深入理解JAVA的多态性[转]
    Linux文件系统的目录结构
    硬盘分区
  • 原文地址:https://www.cnblogs.com/wang7/p/2513012.html
Copyright © 2020-2023  润新知