在平台开发中,我们往往对性能要求十分严苛,每一个字段、接口都有严格的要求。

系统中文件流操作十分占用资源,这里为大家介绍对文件上传进行哈希校验---同一文件只允许上传一次到服务器,其他的上传只要指向文件地址即可。

首先需要设计一张用于文件管理的业务表:

    public class SysFile
{
public int Id { get; set; } /// <summary>
/// 文件名称
/// </summary>
[StringLength(100)]
public string FileName { get; set; } /// <summary>
/// 文件存放路径
/// </summary>
[StringLength(200)]
public string FilePath { get; set; } /// <summary>
/// 存放目录
/// </summary>
[StringLength(100)]
public string FileDirectory { get; set; } /// <summary>
/// 文件大小
/// </summary>
public int FileSize { get; set; } /// <summary>
/// 哈希值 SHa256
/// </summary>
[StringLength(100)]
public string Hash { get; set; } /// <summary>
/// 关联表
/// </summary>
public string LinkName { get; set; } /// <summary>
/// 关联ID
/// </summary>
public int LinkID { get; set; }
}

实际项目中可以根据该表写一个领域服务,方便接口调用。

由于需要验证文件是否存在,所以需要提供查询和上传接口:

        public async Task<List<UploadFileDto>> Check(List<UploadFileDto> input)
{
var existFiles = await _fileRepository.GetAllListAsync(_ => input.Select(f => f.FileHash).Contains(_.Hash));
foreach (var file in input)
{
var existFile = existFiles.FirstOrDefault(_ => _.Hash == file.FileHash);
if(existFile!=null)
{
input.Remove(file);
}
}
return input;
} public async Task<bool> Upload(IFormFileCollection files)
{
if (!files.Any())
return false; var filePath = Path.Combine(_env.ContentRootPath, "wwwroot/Upload");
if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); foreach (var file in files)
{
var fileName = $"{Guid.NewGuid()}@{file.FileName}";
var tempFilePath = Path.Combine(filePath, fileName); using (var fileStream = new FileStream(Path.Combine(filePath, fileName), FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
} return true;
}
UploadFileDto:
    public class UploadFileDto
{
public string FileHash { get; set; } public string FileName { get; set; }
}

后台需要以下步骤:

1、对前端计算的文件哈希值进行查询,返回数据库中不存在的文件信息

2、将已存在的文件进行路径指向,此时这些文件就不需要再次上传,只要在数据库中加一条路径指向就可以了

3、对服务器不存在的文件进行逐一上传

由于文件的hash算法是在前端实现,所有后台处理的方式有多种,大家可以根据自己的业务和需求进行调整。

前端(angular)的实现,前端的实现是采用开源的js包,所以任何框架均可实现

首先安装js-sha256包:npm install js-sha256

在需要上传的模块中进行引用:  import { sha256 } from 'js-sha256';

这里使用的是primeng中的上传组件,在选择文件后进行哈希计算:

    onSelect(event, form): void {
if (form.files.length == 1) {
this.uploadDto.pop();
}
for (const file of event.files) {
let self = this;
let fr = new FileReader();
var upload = new UploadFileDto();
upload.fileName = file.name;
fr.readAsArrayBuffer(file);
fr.onload = function (data: any) {
let fi = data.target.result;
var hash = sha256(fi);
upload.fileHash = hash;
self.uploadDto.push(upload);
}
}
}

点击上传:

    myUploader(event, form): void {
if (event.files.length == 0) {
return;
} this.uploading = true;
this._filesUploadService.check(this.uploadDto)
.subscribe(result => {
this.uploadDto = result;
}); let input = new FormData();
for (const file of event.files) {
var uploadFile = this.uploadDto.find(_ => _.fileName == file.name);
if (uploadFile) {
input.append('files', file);
}
}
this._httpClient
.post(this.uploadUrl, input)
.subscribe(result => {
if (result) {
for (const file of event.files) {
this.uploadedFiles.push(file);
}
form.clear();
this.uploading = false;
this.message.success('上传成功!');
}
else {
this.uploading = false;
this.message.error('上传失败!');
}
},
error=>{
this.message.error('上传失败!');
});
}

其他开发人员可能对angular语法有点难懂,其实核心只有三步:

1、选择文件并对文件进行计算

2、上传计算的文件信息并获取返回信息

3、对返回的文件信息进行包装,将文件流一并传入接口

总结:以上只是对文件校验上传的简单实现,如有不足之处,还请多多赐教。

文件hash、上传,实现文件上传重复验证的更多相关文章

  1. 【Java EE 学习 22 上】【文件上传】【目录打散】【文件重命名】

    1.文件上传概述 (1)使用<input type="file">的方式来声明一个文件域. (2)表单提交方式一定要是post方式才行 (3)表单属性enctype 默 ...

  2. Linux 终端访问 FTP 及 上传下载 文件

    今天同事问我一个问题,在Linux 下访问FTP,并将文件上传上去. 我之前一直是用WinSCP工具的. 先将文件从linux copy到windows下,然后在传到ftp上.google 一下. 方 ...

  3. shell ftp上传下载文件

    1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地/home/databackup#### #!/bin/bash ftp -n<<! open ...

  4. 利用HTML5分片上传超大文件

    在网页中直接上传大文件一直是个比较头疼的问题,主要面临的问题一般包括两类:一是上传时间长中途一旦出错会导致前功尽弃:二是服务端配置复杂,要考虑接收超大表单和超时问题,如果是托管主机没准还改不了配置,默 ...

  5. Linux 终端訪问 FTP 及 上传下载 文件

    今天同事问我一个问题,在Linux 下訪问FTP,并将文件上传上去. 我之前一直是用WinSCP工具的. 先将文件从linux copy到windows下,然后在传到ftp上. google 一下. ...

  6. Linux 终端访问 FTP 及 上传下载 文件[转]

    1.      Linux 终端连接FTP [oracle@Dave ~]$ ftp 10.85.7.97 Connected to 10.85.7.97. 220 Serv-U FTP Server ...

  7. C#使用七牛云存储上传下载文件、自定义回调

    项目需要将音视频文件上传服务器,考虑并发要求高,通过七牛来实现. 做了一个简易的压力测试,同时上传多个文件,七牛自己应该有队列处理并发请求,我无论同时提交多少个文件,七牛是批量一个个排队处理了. 一个 ...

  8. WebUploader 解决文件多次上传和删除上传文件的问题

    文件多次上传有两种情况: 1. 上传前的多次选择 2. 上传成功后,再次选择 其实API上,已经有了介绍了,不知道为什么有同学还是不知道如何做,我来抛砖引玉吧. 配置项: duplicate {Boo ...

  9. java+上传大文件

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...

随机推荐

  1. Django使用消息提示简单的弹出个对话框

    1.下面就来介绍一下如何简单的显示一个消息提示,好像js可以控制,不过这里用了django.contrib.messages这个库 2.首先呢,在项目的settings.py有默认配置一个django ...

  2. Nginx动态添加模块 平滑升级

    已经安装好的Nginx动态添加模块 说明: 已经安装好的Nginx,需要添加一个未被编译安装的模块,需要怎么弄呢? 这里已安装第三方nginx-rtmp-module模块为例 nginx的模块是需要重 ...

  3. HTTP及WEB框架简述

    HTTP介绍 Hyper Text Transfer Protocol,超文本传输书协议,是万维网数据通信的基础,规定了请求和响应标准. HTTP工作原理 HTTP 请求以及响应的步骤 客户端连接到W ...

  4. HCL试验八

    pc1:配置静态ip地址,掩码,网关 路由器R1:配置ip地址192.168.1.254 24;配置dhcp int gi 0/0 ip add 192.168.1.254 24 qu dhcp en ...

  5. 【VS开发】关于SEH的简单总结

    尽管以前写过一篇SEH相关的文章<关于SEH的简单总结>, 但那真的只是皮毛,一直对Windows异常处理的原理似懂非懂, 看了下面的文章 ,一切都豁然开朗.  1997年文章,Windo ...

  6. Spring Cloud Feign原理及性能

    什么是Feign? Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直 ...

  7. 关于.Net Core+Angular+Ueditor富文本编辑器的使用方式

    博客:https://www.cnblogs.com/24klr/ 资料:https://www.jianshu.com/p/0b21a1324d47 GitHub:https://github.co ...

  8. python实现更换电脑桌面壁纸,锁屏,文件加密方式

    python实现更换壁纸和锁屏代码 #控制windows系统 import win32api,win32con,win32gui # 可以利用python去调用dll动态库的包.嵌入式开发 from ...

  9. Zabbix-自带监控项与Kye

    开启主机自动发现 ⦁选择配置 ->自动发现 ->创建自动发现->ip范围必须连续,不连续的话逗号分开 ⦁更新间隔 -> 2s ->更新 ⦁检查 -> 选择新的 -& ...

  10. Codeforces 1229B. Kamil and Making a Stream

    传送门 注意到只要考虑祖先和后代之间的贡献 发现对于一个节点,他和所有祖先最多产生 $log$ 个不同的 $gcd$ 所以每个节点开一个 $vector$ 维护祖先到自己所有不同的 $gcd$ 和这个 ...