上传文件到服务器有很多种方式,按存储方式大概分为文件系统存储和数据库存储,平时用的比较多的是文件系统存储,特点是简单、方便,灵活,可选的实现方式也很多,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(); SearchFile(); } private string filePath; public string FilePath { get { return filePath; } set { filePath = value; OnPropertyChanged("FilePath"); } } public ObservableCollection 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 paramss = new Dictionary (); 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 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; } }}
代码看起来比较乱,虽说是个Demo,但也遵循了MVVM模式,可以参考一下
ps.对于基础的东西 比如通讯协议 比如操作系统 比如编译... 还是要了解一些 万变不离其宗 无论怎样封装 组合 最重要的还是那些东西,内功有了,招式自然而然就出来了