分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

Asp.Net Core 2.0 WebUploader FastDfs 文件上传 分段上传

发布时间:2023-09-06 01:59责任编辑:沈小雨关键词:Web文件上传

功能点:

1. 使用.net core 2.0 实现文件上传

2. 使用webuploader实现单文件,多文件上传

3. 使用webuploader实现大文件的分段上传。

4. 使用webuploader与FastDfs实现文件上传。

5. 通过依赖注入可以很方便地实现本地文件存储切换为FastDfs

主要功能:

直接上代码:

1. 使用.net core 2.0 实现文件上传

 ???????public ActionResult Upload(IFormCollection files) ???????{ ???????????var result = new UploadResult(); ???????????foreach (var item in files.Files) ???????????{ ???????????????#region 把文件流转化为字节流 ???????????????byte[] buffer = new byte[item.Length]; ???????????????Stream fs = item.OpenReadStream(); ???????????????fs.Read(buffer, 0, buffer.Length); ???????????????#endregion ???????????????UploadConfig config = new UploadConfig ???????????????{ ???????????????????Buffer = buffer, ???????????????????FileName = item.FileName, ???????????????????Chunked = files.Keys.Contains("chunk"), ???????????????????PreviosName = files["previosName"] ???????????????}; ???????????????result = _provider.Upload(config); ???????????} ???????????return Json(result); ???????}

这里要注意参数,使用的是IFormCollection,没有使用IFormFile,使用后者的话,不能接收前台发送的自定义参数。虽然我用了fforeach循环,但实现上它的files count只有一个,不管前台发送的是一个文件,还是多个文件,这点还要研究一下,是不是有配置。

 ???????private readonly IFileSystemProvider _provider; ???????public HomeController(IFileSystemProvider provider) ???????{ ???????????_provider = provider; ???????}
IFileSystemProvider 为定义的接口,分别有本地文件存储,和分布式文件存储两种实现方式,后面会奉上代码。

2. 使用webuploader实现单文件,多文件上传
这里主要上前台代码:
 ???????// 实例化 ???????uploader = WebUploader.create({ ???????????pick: { ???????????????id: ‘#filePicker‘, ???????????????label: ‘点击选择文件‘ ???????????}, ???????????dnd: ‘#dndArea‘, ???????????paste: ‘#uploader‘, ???????????swf:‘lib/webuploader/Uploader.swf‘, ???????????chunked: true, //分片处理大文件 ???????????chunkSize: 1 * 1024 * 1024, ???????????server: home/upload, ???????????disableGlobalDnd: true, ???????????threads: 1, //上传并发数 ???????????fileNumLimit: 300, ???????????compress: false, //图片在上传前不进行压缩 ???????????fileSizeLimit: 1024 * 1024 * 1024, ???// 1024 M ???????????fileSingleSizeLimit: 1024 * 1024 * 1024 ???// 1024 M ???????});

初始化webuploader这里要注意threads我想的是1,如果分段上传,几个分段同时发送的话,后台如果写入是个问题,特别是使用fastdfs, .net版本的sdk还不支持指定位置写入的功能。

注意到一个事件:它是实现分段上传重中之重

 ???????uploader.on(‘uploadAccept‘, function (file, response) { ???????????if (file.chunk + 1 !== file.chunks) { ???????????????$.extend(uploader.options.formData, { previosName: response.filePath }); ???????????} else { ???????????????$.extend(uploader.options.formData, { previosName: "" }); ???????????} ???????????return true; ???????});

这里着重解释一下。看到网上关于文件分段上传,都是在服务器端用临时文件记录着文件上传的地址,当有分段信息到达时,会查询临时文件,取出文件地址,然后再往这个地址追加文件流。

这样增加了服务器端的复杂度,而且如果是分布式部署的话,会存在找到临时文件的问题,进而会考虑到数据库和分布式缓存的解决方案,更加复杂了。

这里简单说明一下解决思路:

1) 后台:第一段上传成功后,返回文件地址。如代码的 return Json(result);

2) 前台:使用uploadAccept事件接收文件信息和后台返回地址。

3)前台:在uploadAccept事件中:添加往后台发送的参数previosName:第一段返回的文件地址。

   这里要注意如果是多个文件上传的话,第二个文件的第一个分段不能带有第一个文件的上传地址,如上代码所示

4) 后台:如上面的代码所示,接收前台发送的文件地址,做文件的追加,即可。

3. 使用webuploader实现大文件的分段上传。

下面是服务端的代码:

 ???????public UploadResult Upload(UploadConfig config) ???????{ ???????????//相对路径 ???????????string path = GetFileName(config); ???????????//根据路径创建一个新的文件,并在指定位置写入字节,如果文件已存在,就追加 ???????????using (FileStream fs = File.OpenWrite(Path.Combine(_option.RootFilePath, path))) ???????????{ ???????????????if (fs.CanWrite) ???????????????{ ???????????????????fs.Seek(fs.Length, SeekOrigin.Current); ???????????????????fs.Write(config.Buffer, 0, config.Buffer.Length); ???????????????????fs.Flush(); ???????????????????fs.Close(); ???????????????} ???????????} ???????????return new UploadResult { FilePath = path, OriginalName = config.FileName }; ???????} ???????private string GetFileName(UploadConfig config) ???????{ ???????????string path; ???????????if (string.IsNullOrEmpty(config.PreviosName)) ???????????{ ???????????????path = Path.Combine(subDirectory, $"{GuidTo16String()}.{config.FileName}"); //返回的相对路径和文件名 ???????????????CheckSavePath(); ???????????} ???????????else ???????????{ ???????????????path = config.PreviosName; ???????????????if (string.IsNullOrEmpty(config.PreviosName)) ???????????????{ ???????????????????throw new ArgumentNullException("PreviosName 参数不能为空"); ???????????????} ???????????} ???????????return path; ???????} ???????private string CheckSavePath() ???????{ ???????????var path = Path.Combine(_option.RootFilePath, subDirectory); ???????????// 如何路径不存在,就创建文件路径 ???????????if (!Directory.Exists(path)) ???????????{ ???????????????Directory.CreateDirectory(path); ???????????} ???????????return path; ???????}

这里关注一下GetFileName方法:代码很简单,就不做说明了。

4. 使用webuploader与FastDfs实现文件上传

前端代码和服务端的action的代码是一样的。主要是写文件的方式不一样,主要代码如下:

 ???????public UploadResult Upload(UploadConfig config) ???????{ ???????????if (string.IsNullOrEmpty(config.PreviosName)) ???????????{ ???????????????var fileName = string.Empty; ???????????????var storageNode = _client.GetStorageNode(config.GroupName); ???????????????if (!config.Chunked) ???????????????{ ???????????????????fileName = _client.UploadFile(storageNode, config.Buffer, Path.GetExtension(config.FileName)); ???????????????} ???????????????else ???????????????{ ???????????????????//分段上传需要调用这个方法 ???????????????????fileName = _client.UploadAppenderFile(storageNode, config.Buffer, Path.GetExtension(config.FileName)); ???????????????} ???????????????return new UploadResult { FilePath = fileName, OriginalName = config.FileName }; ???????????} ???????????else ???????????{ ???????????????//分段上传:需要提供上传GroupName, 文件上传地址PreviosName,文件上传内容filebody ???????????????//续传 地址config.PreviosName ???????????????_client.AppendFile(config.GroupName, config.PreviosName, config.Buffer); ???????????????return new UploadResult { FilePath = config.PreviosName, OriginalName = config.FileName }; ???????????} ???????}

这里注意分段上传的文件,第一段上传使用的方法是UploadAppenderFile,后续使用的是AppendFile。

连接FastDfs的代码如下:

 ???public class FastDfsClientProvider : IFastDfsClientProvider ???{ ???????private readonly FastDfsOption _options; ???????public FastDfsClientProvider(FastDfsOption options) ???????{ ???????????_options = options; ???????} ???????public FastDfsClient GetClient() ???????{ ???????????return new FastDfsClient(new List<IPEndPoint> ???????????{ ???????????????new IPEndPoint(IPAddress.Parse(_options.IpAddress), _options.Port) ???????????}); ???????} ???}

5. 通过依赖注入可以很方便地实现本地文件存储切换为FastDfs

代码如下:

 ???????public void ConfigureServices(IServiceCollection services) ???????{ ???????????services.AddMvc(); ???????????????????????services.AddTransient<IFileSystemProvider>(m=> { ???????????????IHostingEnvironment env = m.GetService<IHostingEnvironment>(); ???????????????LocalFsOption lOption = new LocalFsOption ???????????????{ ???????????????????RootFilePath = Path.Combine(env.ContentRootPath, "Files") ???????????????}; ???????????????return new LocalFsProvider(lOption); ???????????}); ???????}

如果想换实现的话 改一个return new LocalFsProvider(lOption),配置一下参数就行了。

部分代码参考博友,找不到出处了,请凉解。

Asp.Net Core 2.0 WebUploader FastDfs 文件上传 分段上传

原文地址:https://www.cnblogs.com/hankuikui/p/9182073.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved