当前位置: 首页 > news >正文

Net Core 使用Mongodb操作文件(上传,下载)

Net Core 使用Mongodb操作文件(上传,下载)

1.Mongodb GridFS 文件操作帮助类。

GridFS 介绍 https://baike.baidu.com/item/GridFS/6342715?fr=aladdin

DLL源码:https://gitee.com/chenjianhua1985/mongodb-client-encapsulation

DLL文件:链接:https://pan.baidu.com/s/1SpWDtaXjavalJQav89UE4A?pwd=yceu 提取码:yceu

/// <summary>/// MongoDB 文件 操作类/// </summary>public abstract class MongoFileRepository : IMongoFileRepository{#region GridFS 介绍// MongodB使用两个集合来存储GridFS文件,一个是fs.files,另一个是fs.chunks//  fs.files这个集合中存储的是每一个上传到数据库的文档的信息//  fs.chunks这个集合存储的是上传文件的内容。一个chunk相当于一个文档(大文件被拆分成多个有序的chunk)//  GridFS中的bucket这个概念指代的是fs.files和fs.chunks的组合// 它的工作原理是://   在GridFS存储文件是将文件分块存储,文件会按照256KB的大小分割成多个块进行存储//    GridFS使用两个集合//     (collection)存储文件,一个集合是chunks, 用于存储文件的二进制数据//      一个集合是files,用于存储文件的元数据信息(文件名称、块大小、上传时间等信息)//      从GridFS中读取文件要对文件的各各块进行组装、合并//  GridFSBucket 用于打开下载流对象#endregion/// <summary>/// 库 名/// </summary>public abstract string DataBaseName { get; }/// <summary>/// 配置类型/// </summary>public virtual DBConfigTypeEnum DBConfigType { get; set; } = DBConfigTypeEnum.WriteDB;/// <summary>///  根据 Id 获取内部信息/// </summary>/// <param name="id"></param>/// <returns></returns>public ObjectId GetInternalId(string id){if (!ObjectId.TryParse(id, out ObjectId internalId))internalId = ObjectId.Empty;return internalId;}/// <summary>///  根据 Id 获取文件 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<GridFSFileInfo> GetFileById(string id){// 通过系统 Id 筛选出包含 _id 的文件数据var filter = Builders<GridFSFileInfo>.Filter.Eq("_id", GetInternalId(id));return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).Find(filter).FirstOrDefaultAsync();}/// <summary>/// 根据 Id 获取文件 -- 异步/// </summary>/// <param name="id">文件Id</param>/// <returns></returns>public async Task<GridFSFileInfo> GetFileById(ObjectId id){var filter = Builders<GridFSFileInfo>.Filter.Eq("_id", id);return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).Find(filter).FirstOrDefaultAsync();}/// <summary>///  上传文件  -- 异步/// </summary>/// <param name="fileName">文件名称</param>/// <param name="source">流</param>/// <returns></returns>public async Task<ObjectId> UploadFile(string fileName, Stream source){var id = await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).UploadFromStreamAsync(fileName, source);return id;}/// <summary>///  根据Id 下载文件流可搜索  -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<GridFSDownloadStream<ObjectId>> DownloadFileStreamSeekable(string id){var options = new GridFSDownloadOptions{Seekable = true};return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).OpenDownloadStreamAsync(GetInternalId(id), options);}/// <summary>/// 根据Id 下载文件流可搜索 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<GridFSDownloadStream<ObjectId>> DownloadFileStreamSeekable(ObjectId id){var options = new GridFSDownloadOptions{Seekable = true};return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).OpenDownloadStreamAsync(id, options);}/// <summary>/// 根据 Id 下载文件流 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<GridFSDownloadStream<ObjectId>> DownloadFileStream(string id){return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).OpenDownloadStreamAsync(GetInternalId(id));}/// <summary>/// 下载 Id 获取文件流 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<GridFSDownloadStream<ObjectId>> DownloadFileStream(ObjectId id){return await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).OpenDownloadStreamAsync(id);}/// <summary>/// 根据Id删除文件 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task DeleteFile(string id){await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).DeleteAsync(GetInternalId(id));}/// <summary>/// 根据Id删除文件 -- 异步/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task DeleteFile(ObjectId id){await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).DeleteAsync(id);}/// <summary>/// 根据Id和文件名称移除文件 -- 异步/// </summary>/// <param name="id"></param>/// <param name="newFilename"></param>/// <returns></returns>public async Task RenameFile(string id, string newFilename){await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).RenameAsync(GetInternalId(id), newFilename);}/// <summary>///  根据Id和文件名称移除文件 --异步/// </summary>/// <param name="id"></param>/// <param name="newFilename"></param>/// <returns></returns>public async Task RenameFile(ObjectId id, string newFilename){await MongoDBClient.GetGridFSBucketInstance(DataBaseName, DBConfigType).RenameAsync(id, newFilename);}}

在项目的使用实例

本人比较喜欢封装好再用。所以将上面的帮助类封装成了一个DLL文件,这样在项目中可以直接引用。

 项目结构

 API层有一个mongoDBConfig.json这个是客户端连接配置文件。

[{"DbName": "PMFiles","ReadConnectionString": "mongodb://192.168.10.200:27017","WriteConnectionString": "mongodb://192.168.10.200:27017"},{"DbName": "Test","ReadConnectionString": "mongodb://192.168.10.200:27017","WriteConnectionString": "mongodb://192.168.10.200:27017"}
]

使用很简单,在要引用的类库中直接引用DLL文件就可以。

下面是具体的实例代码:

1.数据访问层

/// <summary>/// MongodbFile处理接口/// </summary>public interface IFileRepository : IMongoFileRepository{}

这里创建的接口是空的,没有要扩展的方法,常用的接口都在 IMongoFileRepository 基类接口中定义了.

实现类:

/// <summary>/// Mongodb 文件 数据库 操作类/// </summary>public class FileRepository : MongoFileRepository , IFileRepository{public override string DataBaseName => "PMFiles";}

这里创建的实现类也是空的,没有要扩展的方法,常用的接口都在 MongoFileRepository基类中实现了.

注意: 这里重写了DataBaseName这里一定要重写基类的数据库名称。

2.业务层

/// <summary>/// 文件 操作 业务逻辑层接口/// </summary>public interface IFileService : IMongoFileRepository{}

实现类

这里主要是调用数据访问层的实例来实现功能。

[AutoInject(typeof(IFileService), InjectType.Scope)]

这里的服务注入用的是自动注入。可以改成手动注册。手动注册时可以删除类上的 AutoInject 标签

/// <summary>/// 文件操作服务/// </summary>[AutoInject(typeof(IFileService), InjectType.Scope)]public class FileService : IFileService{private readonly IFileRepository _srviceFile = RepositoryIocFactory.GetRegisterImp<IFileRepository>();public Task DeleteFile(string id){return _srviceFile.DeleteFile(id);}public Task DeleteFile(ObjectId id){return _srviceFile.DeleteFile(id);}public Task<GridFSDownloadStream<ObjectId>> DownloadFileStream(string id){return _srviceFile.DownloadFileStream(id);}public Task<GridFSDownloadStream<ObjectId>> DownloadFileStream(ObjectId id){return _srviceFile.DownloadFileStream(id);}public Task<GridFSDownloadStream<ObjectId>> DownloadFileStreamSeekable(string id){return _srviceFile.DownloadFileStreamSeekable(id);}public Task<GridFSDownloadStream<ObjectId>> DownloadFileStreamSeekable(ObjectId id){return _srviceFile.DownloadFileStreamSeekable(id);}public Task<GridFSFileInfo> GetFileById(string id){return _srviceFile.GetFileById(id);}public Task<GridFSFileInfo> GetFileById(ObjectId id){return _srviceFile.GetFileById(id);}public ObjectId GetInternalId(string id){return _srviceFile.GetInternalId(id);}public Task RenameFile(string id, string newFilename){return _srviceFile.RenameFile(id, newFilename);}public Task RenameFile(ObjectId id, string newFilename){return _srviceFile.RenameFile(id, newFilename);}public Task<ObjectId> UploadFile(string fileName, Stream source){return _srviceFile.UploadFile(fileName, source);}}

1、API层的实现

AIP层主要的接口有 上传 和 根据ID下载文件,以文件流对象返回数据。

/// <summary>/// MongoDB文件上传/// </summary>public class FileUploadController : BaseApiController{private IFileService serviceFile;public FileUploadController(IFileService fileService){serviceFile = fileService;}/// <summary>/// 上传文件/// </summary>/// <returns></returns>[HttpPost, Route("UploadFileAsync")][DisableRequestSizeLimit][DisableFormValueModelBinding]public async Task<AjaxResultPageModel> UploadFileAsync(){var rspModel = new AjaxResultPageModel();var fileIds = new List<string>();//检查ContentTypeif (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)){rspModel.Warning("内容类型不能为空");}else{var _defaultFormOptions = new FormOptions();var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);var reader = new MultipartReader(boundary, Request.Body);var section = await reader.ReadNextSectionAsync();while (section != null){//把Form的栏位內容逐一取出var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);if (hasContentDispositionHeader){//按文件和键值对分类处理if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition)){FileMultipartSection currentFile = section.AsFileSection();//存储文件到Mongovar id = await serviceFile.UploadFile(currentFile.FileName, section.Body);fileIds.Add(id.ToString());}}section = await reader.ReadNextSectionAsync();}rspModel.Success(fileIds);}return rspModel;}/// <summary>/// 下载文件/// </summary>[HttpGet,Route("Download")]public async Task<IActionResult> Download(string id){var fileInfo = await serviceFile.GetFileById(id);if (fileInfo == null){return NotFound();}else{return File(await serviceFile.DownloadFileStream(fileInfo.Id), "application/octet-stream", fileInfo.Filename);}}}

前端实现:

前端使用vue组件

<template><div class="home"><el-card class="box-card-top" shadow="never"><el-row :gutter="100"><el-col :span="2"><div class="user-avatar"><p class="user-avatar-text">{{ avatar }}</p></div></el-col><el-col :span="22"><div class="text"><h3>{{ holler }} {{ username }}</h3><p>桂树青春百里疆,鹧鸪啼彻午阴凉. 延平津上峰如削,剑去江空水自长.--剑道·尘心</p><p>活在当下,着眼未来.没有一往无前的觉悟.就不配握紧手中的双刀.空有大志,却没有实际行动.天下万般兵刃.唯有过往,伤人最深.如果真相带来痛苦.谎言只会雪上加霜.  --LOL·亚索</p></div></el-col></el-row><!-- <h2>首页界面</h2><div class="hello"> --><!-- <el-input v-model="user" type="text" /> --><!-- <div id="message" v-html="remsg"></div> --><!-- <div id="el-input"><el-input id="chatbox" @keyup.native.enter="handle"  type="textarea" :rows="1" placeholder="请输入内容" v-model="msg"></el-input></div><el-button size="small" style="display:inline-block;" icon="el-icon-s-promotion" type="suceess" @click="handle" plain></el-button> --><!-- </div> --></el-card><el-row :gutter="20"><el-col :span="4"><el-card class="box-card-center" shadow="never"><el-upload:action="action":file-list="modeList1":http-request="modeUpload1":multiple="true":before-remove="handleRemove1"><el-button size="small" type="primary">上传</el-button></el-upload><el-button @click="upload1">点击上传文件</el-button><br/><el-button @click="fileUpload">点击上传文件1</el-button></el-card></el-col><el-col :span="4"><el-card class="box-card-center" shadow="never"></el-card></el-col><el-col :span="4"><el-card class="box-card-center" shadow="never"></el-card></el-col></el-row></div></template><script>import axios from 'axios'import config from "../../config/index";import service from "../../api/UploadFiles/index";export default {data() {return {username: null,holler: "欢迎回来 — ",avatar: "",action: "", //上传文件的接口mode1: {},modeList1:[],fd1: new FormData()};},created() {this.username = JSON.parse(sessionStorage.getItem(config.localStorageKey)).userName;this.avatar = this.username.slice(0, 1);},methods: {modeUpload1: function(item) {// console.log(item.file);// this.mode1 = item.file// const isIMG =//   item.file.type === 'image/jpg' ||//   item.file.type === 'image/jpeg' ||//   item.file.type === 'image/png'// const isLt = item.file.size / 1024 / 2000 <= 1// if (!isIMG) {//   this.error='文件格式有误\n请上传后缀为jpg\\png的图片'// }// if (!isLt) {//   // console.log(file.size)//   this.error='上传头像图片大小不能超过500KB!'// }// if(isIMG&&isLt){this.fd1.append('files', item.file); //这里是自己把文件对象获取到,并存储起来//console.log("modeUpload1-> addFile:",item.file);//}},upload1: function() {console.log("upload1-> 11,files.length=",this.fd1.getAll('files').length);if(this.fd1.getAll('files').length===0){//formdata.getAll()返回的是一个file的数组(当然这里是你之前的参数得是文件)this.error='请先上传文件'}else {console.log("upload1-> post");axios.post('https://localhost:5001/adminapi/FileUpload/UploadFileAsync', this.fd1, { //headers: {'Content-Type': 'multipart/form-data'}}).then(response => {console.log("upload1->",response.data);})}},handleRemove1(file, fileList) {let files = this.fd1.getAll('files');this.fd1.delete('files');let len = files.lengthfor(var i=0;i<len;i++){if(files[i].uid!=file.uid){ //uid应该是可以唯一标志文件的,如果不能,就是我,会死this.fd1.append('files',files[i])}}},//上传方法fileUpload(uploader) {//let form = new FormData();//form.append("files", uploader.file);//console.log(this.fd1);//console.log("--------------------------");//console.log(uploader)service.uploadFlie(this.fd1// onUploadProgress: (progressEvent) => {//   //这一步是展示上传的进度条,不展示也行,根据自身需求决定//   let percent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;//   uploader.onProgress({ percent: percent }); //调用uploader的进度回调// },).then((res) => {console.log(res);if (res.success) {this.$message({message: "上传成功",type: "success",});} else {this.$message.error("上传失败,"+res.message);}}).catch((err) => {this.$message.error(err);});},},};/* import * as signalR from "@microsoft/signalr";let hubUrl = "https://localhost:44360/chatHub";//"https://localhost:44367/chatHub";//https://localhost:44318/chatHub; https://localhost:44367/chatHub//.net core 版本中默认不会自动重连,需手动调用 withAutomaticReconnectconst connection = new signalR.HubConnectionBuilder().withAutomaticReconnect().withUrl(hubUrl).build();connection.start().catch(err => alert(err.message));export default {name: "Im",mounted() {var _this = this;console.log('hubUrl:',hubUrl);//实现Show方法 OKconnection.on("Show", function(username, message) {_this.remsg = _this.remsg + "<br>" + username + ":" + message;console.log('Show:',message);});//实现ConnectResponse方法//connection.on("ChatHubReceiveMsg", function(username, message) {//  _this.remsg = _this.remsg + "<br>" + username + ":" + message;//  console.log('ChatHubReceiveMsg:',message);//}); //实现DisconnectResponse方法//connection.on("DisconnectResponse", function(username, message) {//  _this.remsg = _this.remsg + "<br>" + username + ":" + message;//  console.log('DisconnectResponse:',message);//});},data() {return {user: "cjh",msg: "",remsg: ""};},methods: {handle: function() {if(this.msg.trim()==""){alert("不能发送空白消息");return;}//调用后端方法 SendMsg 传入参数 OKconnection.invoke("SendMsg", this.user, this.msg);//connection.invoke("PublicSendMsg", this.msg);this.msg = "";}}}; */</script><style lang="less" scoped>.home {margin: 20px;.box-card-top {min-height: 160px;.user-avatar {width: 100px;height: 100px;margin-left: 50px;margin-top: 5px;border-radius: 50%;background-image: linear-gradient(#cdeefa, #b4b4fc);// background-color: #b4b4fc;.user-avatar-text {font-size: 40px;text-align: center;padding-top: 22px;color: #383838;}}.text h3 {margin-top: 20px;margin-bottom: 10px;font-size: 20px;}.text p {font-size: 16px;user-select: none;}}.box-card-center {width: 350px;height: 300px;margin-top: 20px;}}h1,h2 {font-weight: normal;}ul {list-style-type: none;padding: 0;}li {display: inline-block;margin: 0 10px;}a {color: #42b983;}#el-input {display: inline-block;width: 96%;float: left;}#message {overflow-y: auto;text-align: left;border: #42b983 solid 1px;height: 500px;}</style>

跨域问题处理。

requestFile.js

注意上图的类型只能是这个类型,只能一个类型,不能多。

//interceptors.js// vue axios配置 发起请求加载loading请求结束关闭loading
// http request 请求拦截器,有token值则配置上token值
import axios from 'axios'
import common from '../utils/common'
// import { API_BASE } from '../config/config';
// axios.defaults.baseURL = API_BASE;
// api base_url,设置前缀不存在
// const BASE_URL="";
const service = axios.create({baseURL: '', timeout: 60000, // 请求超时时间headers: {// Authorization: Authorization,'Content-Type': 'multipart/form-data'}
});
// Content-Type: application/wasmsql-wasm.wasm
// http请求拦截器
service.interceptors.request.use(config => {let token = common.getToken();//console.log('token:', token);if (token) {// bus.$emit('toggleloading', true)//显示loading// Loading.service(options);//如果token存在config.headers['Authorization'] = `Bearer ${token}`;//console.log('token 1:', token);}return config;},error => {Promise.reject(error);}
)// http response 服务器响应拦截器,
// 这里拦截401错误,并重新跳入登页重新获取token
service.interceptors.response.use(response => {if (response.status === 200) {//通讯成功// Toast.clear();// console.log(response);/************** response.data.status === 0 错误* response.data.status === 100 成功* response.data.status === 401 token过期** *************///  response.data.head.errorCode// bus.$emit('toggleloading', false)//隐藏loadingif (response.data.state == 401) {//未授权//如果是token过期,跳转至登录// console.log("401");//common.goLogin();message.error("未授权 请联系管理员!");//store.commit('setToken', '');} else if (response.data.state == 0) {// Message.error(response.data.message);return response.data;} else {// util.goLogin();return response.data;}}},error => {//请求失败// ;const response = error.response;if (response.status === 401) {// Toast.fail(response.data.message);message.error("未授权 请联系管理员!");//util.goLogin();} else if (response.status === 403) {$router.push({name: '403'});} else {// Toast.fail(response.data.message ? response.data.message : '系统错误请联系管理员');// message.error({//     message: '无服务,请联系管理员'// });}return Promise.reject(error);}
);export default service;

API js

import http from '../../utils/http'export default {// 上传文件uploadFileAsync:(params) => {return http.postMongoDBFile("adminapi/FileUpload/UploadFileAsync",params);},// 下载文件download:(params) => {return http.postMongoDBdownloadFile("adminapi/FileUpload/Download?id="+params)}
};

完成。

END

相关文章:

Net Core 使用Mongodb操作文件(上传,下载)

Net Core 使用Mongodb操作文件&#xff08;上传&#xff0c;下载&#xff09; 1.Mongodb GridFS 文件操作帮助类。 GridFS 介绍 https://baike.baidu.com/item/GridFS/6342715?fraladdin DLL源码&#xff1a;https://gitee.com/chenjianhua1985/mongodb-client-encapsulati…...

适用于系统版本:CentOS 6/7/8的基线安全检测脚本

#!/bin/bash #适用于系统版本&#xff1a;CentOS 6/7/8 echo "----------------检测是否符合密码复杂度要求----------------" #把minlen&#xff08;密码最小长度&#xff09;设置为8-32位&#xff0c;把minclass&#xff08;至少包含小写字母、大写字母、数字、特殊…...

Seata源码流程图

1.第一阶段分支事务的注册 流程图地址&#xff1a;https://www.processon.com/view/link/6108de4be401fd6714ba761d 2.第一阶段开启全局事务 流程图地址&#xff1a;https://www.processon.com/view/link/6108de13e0b34d3e35b8e4ef 3.第二阶段全局事务的提交 流程图地址…...

英飞凌电源管理PMIC的安全应用

摘要 本篇文档主要用来介绍英飞凌电源管理芯片TLF35584的使用&#xff0c;基于电动助力转向应用来介绍。包含一些安全机制的执行。 TLF35584介绍 TLF35584是英飞凌推出的针对车辆安全应用的电源管理芯片&#xff0c;符合ASIL D安全等级要求&#xff0c;具有高效多电源输出通道&…...

快速在Linux系统安装MySQL

虚拟机使用docker安装MySQL 使用docker拉去镜像 查看mysql的镜像 docker search mysql拉去mysql镜像 docker pull mysql查看下载的镜像 docker images启动容器 docker start mysql进入MySQL容器 docker exec -it mysql /bin/bash登录mysql mysql -u root -p检查是否进入…...

数据库相关理论知识(有目录便于直接锁定相关知识点+期末复习)

一&#xff0c;数据模型&#xff0c;关系型数据模型&#xff0c;网状模型&#xff0c;层次模型 1.数据库模型是用来描述和表示现实世界中的事物、概念以及它们之间的关系的工具&#xff0c;但是并不是越专业越好&#xff0c;还要平衡它的模型的复杂性、通用性和成本效益等因素…...

NCC环境配置

一、后端配置 1.安装eclipse汉化插件 2.安装svn插件...

用python实现Dubins曲线生成

Dubins曲线是连接两个具有指定方向和位置的点的最短路径&#xff0c;其中路径受到固定曲率约束&#xff08;如车辆的转向限制&#xff09;。Dubins曲线常用于机器人路径规划、车辆轨迹规划等领域。 Dubins曲线可以分为三种类型&#xff1a;CCC (Curve-Curve-Curve), CCL (Curv…...

智能技术上的“是”并不代表具体领域的“应该”

技术上的“是”并不代表具体领域的“应该” 。技术上的“是”仅仅是指某种方法或技术在实践中是否可行或有效&#xff0c;而不涉及是否该采取这种方法或技术。决定是否采取某种方法或技术还需要考虑伦理、法律、可行性等其他方面的因素。技术的发展可能会有各种可能性&#xff…...

永热爱 敢向前 | Paraverse平行云的2023 年终总结

永热爱&#xff0c;敢向前 值此新年&#xff0c;回顾2023&#xff0c;仅以此句&#xff0c;献给所有XR产业信仰者 2023 年&#xff0c;是XR产业技术和场景承上启下的关键之年 在这场波澜壮阔的技术潮中 「Paraverse平行云」踏浪前行 已是第八个年头&#xff0c;让我们一起…...

c/c++的内存分配,详细说一下栈、堆和静态存储区

栈区&#xff08;Stack&#xff09;&#xff1a;由编译器自动分配和回收&#xff0c;栈中存放函数调用的相关信息&#xff0c;栈帧&#xff08;记录函数的栈帧开始的位置&#xff09;&#xff0c;参数&#xff0c;局部变量&#xff0c;返回地址。其操作方法类似于数据结构中的栈…...

每日构造题训练——C. Divan and bitwise operations

每日构造题训练 题目链接: 题目传送门 前置知识: 按位或运算 一、题意: 1 1 1、 有一个长度为 n n n的但是元素未知的数组 a a a, 给定 m m m个约束&#xff0c;每个约束都有 l , r , x l, r, x l,r,x, 并且满足 1 ≤ l ≤ r ≤ n , 1 ≤ x < 2 30 , a [ l ] ∣ a [ l 1 …...

【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 一、虚函数与重写1.1 虚函数1.2 虚函数的重写1.3 重写的特例1.4 final和override&#xff08;C11&#xff09;1.…...

如何在Windows系统安装Node.js环境并制作html页面发布公网远程访问?

文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 前言 Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation&#xff0…...

C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

Hilbert, David (1862-1943) 1 希尔伯特(Hilbert) 德国数学家,在《几何学基础》中提出了第一套严格的几何公理(1899年)。他还证明了自己的系统是自洽的。他发明了一条简单的空间填充曲线,即埃里克魏斯汀的数学世界,即希尔伯特曲线,埃里克魏斯汀的数学世界,并证明了不…...

【C++教程从0到1入门编程】第八篇:STL中string类的模拟实现

一、 string类的模拟实现 下面是一个列子 #include <iostream> namespace y {class string{public: //string() //无参构造函数// :_str(nullptr)//{}//string(char* str) //有参构造函数// :_str(str)//{}string():_str(new char[1]){_str[0] \0;}string(c…...

学生时期学习资源同步-1 第一学期结业考试题6

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载...

迁移学习怎么用

如果想实现一个计算机视觉应用&#xff0c;而不想从零开始训练权重&#xff0c;比方从随机初始化开始训练&#xff0c;更快的方式是下载已经训练好权重的网络结构&#xff0c;把这个作为预训练&#xff0c;迁移到你感兴趣的新任务上。ImageNet、PASCAL等等数据库已经公开在线。…...

医疗手持智能终端读取条码二维码的难点有哪些?

在医疗科技行业信息化的大潮中&#xff0c;医疗手持式智能终端的应用越发普及&#xff0c;医疗手持式智能终端对条码二维码技术应用显得尤为关键&#xff0c;作为信息朔源载体的条码二维码读取方面&#xff0c;在实际应用中却面临着诸多问题&#xff0c;我们该如何应对&#xf…...

Python小设计

1. 五个PPT上的界面打印【print、input函数】 &#xff08;1&#xff09;英雄商城登陆界面 print(英雄联盟商城登录界面 ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~1. 用户登录2. 新用户注册3. 退出系统 ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~…...

今日讲讲父子传值~

今天来讲讲父子传值中的几种方法~ 项目中往往会把一些常用的公共代码抽离出来&#xff0c;写成一个子组件。或者在一个页面中的代码太多&#xff0c;可以根据功能的不同抽离出相关代码写成子组件&#xff0c;这样代码结构会更加简洁明了&#xff0c;后续维护更加方便。…...

三、HarmonyOS 应用开发入门之运行Hello World

目录 1、课程对象 1.1、有移动端开发经验 1.2、无移动端开发经验 1.3、对 HarmonyOS 感兴趣 2、DevEco Studio 的使用 2.1、DevEco Studio 的关键特性 智能代码编辑 低代码开发 多段双向实时预览 多端模拟仿真 2.2、安装配置 DevEco Studio 2.2.1、官网开发工具下载地…...

国科大网络行为学导论代码作业--更新中

一、Xray安装 参考自&#xff1a;Xray的安装与使用&#xff08;超详细&#xff09;_xray使用教程-CSDN博客 下载网址&#xff1a;Releases chaitin/xray GitHub 解压 双击安装 生成证书 cd到xray目录&#xff0c;生成证书 复制链接 然后cd到xray目录 .\xray_windows_amd6…...

JAVA后端开发面试基础知识(九)——SpringBoot

启动原理 SpringBoot启动非常简单,因其内置了Tomcat,所以只需要通过下面几种方式启动即可: @SpringBootApplication(scanBasePackages = {"cn.dark"}) public class SpringbootDemo {public static void main(String[] args) {// 第一种SpringApplication.run(S…...

C#调用Halcon出现尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException

一、现象 在C#中调用Halcon&#xff0c;出现异常提示&#xff1a;尝试读取或写入受保护的内存,这通常指示其他内存已损坏。System.AccessViolationException 二、原因 多个线程同时访问Halcon中的某个公共变量&#xff0c;导致程序报错 三、测试 3.1 Halcon代码 其中tsp_width…...

ts基础知识

1. any 类型&#xff0c;unknown 类型&#xff0c;never 类型 TypeScript 有两个“顶层类型”&#xff08;any和unknown&#xff09;&#xff0c;但是“底层类型”只有never唯一一个 1、any 1.1 基本含义 any 类型表示没有任何限制&#xff0c;该类型的变量可以赋予任意类型的…...

KLayout Python Script ------ 绘制1个 Box 物体

KLayout Python Script ------ 绘制两个 Box 物体 引言正文引言 本人通常使用 IPKISS 进行版图绘制,然而很多时候,IPKISS 的功能十分鸡肋。因此,萌生了一种自己写绘制软件的想法,因为 IPKISS 绘制的版图最终也是使用 KLayout 来呈现的,因此,再研究了 KLayout 提供的 API…...

c# 编辑、删除一条数据

1、编辑数据 [HttpPost] public MessageModel<string> Put([FromBody] Dtable request) { var data new MessageModel<string>(); request.UPDATETIME DateTime.Now; if (request.ID>0) { …...

高性能服务系列【八】C10M时代,网络IO库需要重建

在目前网络上能搜索到的&#xff0c;关于网络IO模型的文章&#xff0c;基本都是关于多路复用的iocp/epoll的&#xff0c;这些技术是为了解决C10K问题而提出的解决方案。现代网卡已经普遍支持10Gb&#xff0c;100Gb也不少见&#xff0c;这些解决方案已经无法提升性能的需求。 我…...

Go语言与Rust哪一个更有发展前景?

Go语言和Rust都是目前非常受欢迎的编程语言&#xff0c;它们各自具有独特的优势和适用场景。关于哪一个更有发展前景&#xff0c;这实际上取决于多个因素&#xff0c;包括个人偏好、项目需求、社区支持以及未来技术的发展趋势等。 Go语言是由Google推出的&#xff0c;具有简洁…...