通过数据库上传下载附件

上传文件到服务器有很多种方式,按存储方式大概分为文件系统存储和数据库存储,平时用的比较多的是文件系统存储,特点是简单、方便,灵活,可选的实现方式也很多,TCP/UDP传输,或者直接通过Windows权限存放到服务器端,或者FTP服务,等等。数据库存储的特点是安全,毕竟多了一层加密,但是可想而知,效率不高,毕竟关系型数据库里存储的东西都是数据,想把文件放到数据库自然需要先转换成数据,需要取出的时候再转回来,浪费时间,而且大文件方式更不可取,试想一个读写操作需要都要占用很长时间,数据库还怎么提供服务,但是存放一下小文件,特别是非常零散的小文件还是可以用用的,毕竟是一种思路,下面的Demo简单说明了这一操作的思路:

大概过程就是将文件转换为二进制流,然后用数据库将其存储下来,下载的过程就是反向操作,将流从数据库中取出来,然后读成文件,运行界面:

核心代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;

namespace FileToDataBaseTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }

    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            UploadFiles = new ObservableCollection<UploadFileViewModel>();
            SearchFile();
        }

        private string filePath;
        public string FilePath
        {
            get { return filePath; }
            set
            {
                filePath = value;
                OnPropertyChanged("FilePath");
            }
        }

        public ObservableCollection<UploadFileViewModel> UploadFiles { get; set; }

        public UploadFileViewModel SelectedFileViewModel { get; set; }

        private UploadFile file = null;

        #region 载入文件

        private ICommand loadFileCommand;
        public ICommand LoadFileCommand
        {
            get
            {
                if (loadFileCommand == null)
                {
                    loadFileCommand = new RelayCommand(param => LoadFile());
                }
                return loadFileCommand;
            }
        }
        public void LoadFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                FilePath = dialog.FileName;
                FileInfo fileInfo = new FileInfo(@FilePath);
                file = new UploadFile();
                file.FileSize = fileInfo.Length;
                file.FileName = fileInfo.Name;
                file.FileType = fileInfo.Extension;
                file.FileByteCode = new byte[file.FileSize];
                FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                BinaryReader reader = new BinaryReader(stream);
                reader.Read(file.FileByteCode, 0, (int)file.FileSize);
            }
        }

        #endregion

        #region 保存文件

        private ICommand saveCommand;
        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                {
                    saveCommand = new RelayCommand(param => SaveFile());
                }
                return saveCommand;
            }

        }

        public void SaveFile()
        {
            StringBuilder sqlStr = new StringBuilder();
            sqlStr.AppendFormat(" INSERT  INTO FileDetails         ");
            sqlStr.AppendFormat("         ( fName, fSize, fType, files )         ");
            sqlStr.AppendFormat(" VALUES  ( @fName,          ");
            sqlStr.AppendFormat("           @fSize,          ");
            sqlStr.AppendFormat("           @fType,          ");
            sqlStr.AppendFormat("           @files           ");
            sqlStr.AppendFormat("           )         ");
            Dictionary<string, object> paramss = new Dictionary<string, object>();
            paramss.Add("@fName", file.FileName);
            paramss.Add("@fSize", file.FileSize);
            paramss.Add("@fType", file.FileType);
            paramss.Add("@files", file.FileByteCode);
            int num = DataBaseHelper.SqlExcuteNoQueryWithParamters(sqlStr.ToString(), paramss);
            if (num > 0)
            {
                System.Windows.MessageBox.Show("保存成功");
            }
        }

        #endregion

        #region 查询文件

        public void SearchFile()
        {
            UploadFiles.Clear();
            StringBuilder sbSql = new StringBuilder();
            sbSql.AppendLine(" SELECT  fName ,  ");
            sbSql.AppendLine("         fSize ,  ");
            sbSql.AppendLine("         fType   ");
            sbSql.AppendLine(" FROM    FileDetails  ");
            DataTable dt = DataBaseHelper.GetDataTable(sbSql.ToString());
            foreach (var row in dt.Rows)
            {
                DataRow dr = (DataRow)row;
                UploadFile file = new UploadFile();
                file.FileName = (string)dr["fName"];
                file.FileSize = (long)dr["fSize"];
                file.FileType = (string)dr["fType"];
                UploadFileViewModel fileViewModel = new UploadFileViewModel(file);
                UploadFiles.Add(fileViewModel);
            }
        }

        #endregion
        
    }

    public class UploadFileViewModel : ViewModelBase
    {
        public UploadFileViewModel(UploadFile uploadFile)
        {
            this.uploadFile = uploadFile;
        }

        private UploadFile uploadFile;

        public string FileName
        {
            get { return uploadFile.FileName; }
            set { uploadFile.FileName = value; }
        }

        public long FileSize
        {
            get { return uploadFile.FileSize; }
            set { uploadFile.FileSize = value; }
        }

        public string FileType
        {
            get { return uploadFile.FileType; }
            set { uploadFile.FileType = value; }
        }

        public Byte[] FileByteCode
        {
            get { return uploadFile.FileByteCode; }
            set { uploadFile.FileByteCode = value; }
        }

        #region 下载文件

        private ICommand downloadFileCommand;
        public ICommand DownloadFileCommand
        {
            get
            {
                if (downloadFileCommand == null)
                {
                    downloadFileCommand = new RelayCommand(param => DownloadFile());
                }
                return downloadFileCommand;
            }
        }
        public void DownloadFile()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.FileName = this.FileName;
            string extension = this.FileType.Replace(".", "");
            sfd.Filter = string.Format("*.{0}|*.{0}", extension);
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string savePath = sfd.FileName;
                StringBuilder sbSql = new StringBuilder();
                sbSql.AppendFormat("  SELECT  files           ");
                sbSql.AppendFormat("  FROM    FileDetails           ");
                sbSql.AppendFormat("  WHERE   fName = '{0}'           ", this.FileName);
                byte[] fileBytes = DataBaseHelper.SqlExcuteScalar(sbSql.ToString()) as byte[];
                FileStream stream = new FileStream(savePath, FileMode.CreateNew);
                BinaryWriter writter = new BinaryWriter(stream);
                writter.Write(fileBytes, 0, (int)this.FileSize);
                stream.Close();
                writter.Close();
                System.Windows.MessageBox.Show("下载完成");
            }
        }

        #endregion

    }

    public class UploadFile
    {
        public string FileName { get; set; }

        public long FileSize { get; set; }

        public string FileType { get; set; }

        public byte[] FileByteCode { get; set; }
    }

    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler changedEvent = PropertyChanged;
            if (changedEvent != null)
            {
                changedEvent.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class DataBaseHelper
    {
        public static SqlConnection GetConn()
        {
            string connStr = string.Format("server=.;uid=sa;pwd=sql@2013;database=SaveAnyFile");
            SqlConnection conn = new SqlConnection(connStr);
            return conn;
        }

        public static DataTable GetDataTable(string commmandText)
        {
            SqlCommand command = new SqlCommand();
            SqlConnection conn = GetConn();
            command.Connection = conn;
            command.CommandType = CommandType.Text;
            command.CommandText = commmandText;
            SqlDataAdapter adapter = new SqlDataAdapter(command);
            DataTable dataTable = new DataTable();
            conn.Open();
            adapter.Fill(dataTable);
            conn.Close();
            return dataTable;
        }

        public static int SqlExcuteNoQueryWithParamters(string commmandText, Dictionary<string, object> parameter)
        {
            SqlCommand command = new SqlCommand();
            SqlConnection conn = GetConn();
            command.Connection = conn;
            command.CommandType = CommandType.Text;
            command.CommandText = commmandText;
            foreach (var param in parameter)
            {
                command.Parameters.AddWithValue(param.Key, param.Value);
            }
            conn.Open();
            int num = command.ExecuteNonQuery();
            conn.Close();
            return num;
        }

        public static object SqlExcuteScalar(string commandText)
        {
            SqlCommand command = new SqlCommand();
            SqlConnection conn = GetConn();
            command.Connection = conn;
            command.CommandType = CommandType.Text;
            command.CommandText = commandText;
            conn.Open();
            object obj = command.ExecuteScalar();
            conn.Close();
            return obj;
        }
    }


}
Code
<Window x:Class="FileToDataBaseTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <StackPanel Orientation="Horizontal"
                    Margin="5"
                    VerticalAlignment="Center">
            <TextBlock Text="文件地址"
                       VerticalAlignment="Center"
                       />
            <TextBox Width="150"
                     VerticalAlignment="Center"
                     Text="{Binding FilePath}"/>
            <Button Content="浏览..."
                    Margin="5"
                    Command="{Binding LoadFileCommand}"/>
            <Button Content="上传"
                    Margin="5"
                    Command="{Binding SaveCommand}"/>
        </StackPanel>
        <StackPanel>
            <DataGrid AutoGenerateColumns="False"
                      IsReadOnly="True"
                      VerticalGridLinesBrush="{x:Null}"
                      HorizontalGridLinesBrush="{x:Null}"
                      SelectionUnit="FullRow"
                      SelectedItem="{Binding SelectedFileViewModel}"
                      ItemsSource="{Binding UploadFiles}"
                      BorderThickness="0">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="文件名" Binding="{Binding FileName}"/>
                    <DataGridTextColumn Header="大小" Binding="{Binding FileSize}"/>
                    <DataGridTextColumn Header="类型" Binding="{Binding FileType}"/>
                    <DataGridTemplateColumn Header="下载">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="下载" Command="{Binding DownloadFileCommand}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </StackPanel>
</Window>
XAML

代码看起来比较乱,虽说是个Demo,但也遵循了MVVM模式,可以参考一下

ps.对于基础的东西 比如通讯协议 比如操作系统 比如编译... 还是要了解一些 万变不离其宗 无论怎样封装 组合 最重要的还是那些东西,内功有了,招式自然而然就出来了

源码下载

posted on 2013-08-06 09:27  MikeRen  阅读(1751)  评论(0编辑  收藏  举报

导航