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

鸿蒙OSUniApp 开发的文件上传与下载功能#三方框架 #Uniapp

使用 UniApp 开发的文件上传与下载功能

前言

在移动应用开发中,文件上传与下载是非常常见且重要的功能需求。无论是上传用户头像、提交表单附件,还是下载资源文件、缓存图片,这些需求几乎存在于每一个成熟的应用中。UniApp 作为一个跨平台开发框架,提供了丰富的 API 来支持文件的上传与下载操作,使开发者能够便捷地实现相关功能。

本文将详细介绍如何在 UniApp 中实现文件上传与下载功能,包括基本使用方法、进度监控、断点续传等高级特性,并提供实际案例代码,帮助开发者快速掌握这些功能的开发技巧。

UniApp 文件操作基础

在深入讲解上传下载功能前,我们先来了解 UniApp 中与文件操作相关的几个基础 API:

  1. uni.uploadFile: 上传文件到服务器
  2. uni.downloadFile: 下载文件
  3. uni.saveFile: 保存文件到本地
  4. uni.chooseImage: 从相册选择图片或使用相机拍照
  5. uni.chooseVideo: 选择视频
  6. uni.chooseFile: 选择文件(仅支持特定平台)

这些 API 为我们实现文件上传下载功能提供了基础支持。接下来,我们将详细探讨如何利用这些 API 实现具体功能。

文件上传功能实现

基本文件上传

最简单的文件上传功能可以通过 uni.uploadFile 方法来实现。以上传图片为例:

// 选择图片
uni.chooseImage({count: 1, // 默认9success: (chooseImageRes) => {const tempFilePaths = chooseImageRes.tempFilePaths;// 上传图片uni.uploadFile({url: 'https://your-server-url/upload', // 仅为示例,非真实接口地址filePath: tempFilePaths[0],name: 'file',formData: {'user': 'test'},success: (uploadFileRes) => {console.log('上传成功', uploadFileRes.data);// 可以在这里处理服务器返回的数据},fail: (error) => {console.error('上传失败', error);}});}
});

上传进度监控

在实际应用中,特别是上传大文件时,我们通常需要向用户展示上传进度。UniApp 提供了 onProgressUpdate 回调函数来监控上传进度:

const uploadTask = uni.uploadFile({url: 'https://your-server-url/upload',filePath: tempFilePaths[0],name: 'file',success: (res) => {console.log('上传成功', res.data);}
});uploadTask.onProgressUpdate((res) => {console.log('上传进度', res.progress);console.log('已经上传的数据长度', res.totalBytesSent);console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend);// 更新界面上的进度条this.uploadProgress = res.progress;
});

多文件上传

在很多场景下,我们需要同时上传多个文件。这可以通过循环调用 uni.uploadFile 或使用 Promise.all 来实现:

// 选择多张图片
uni.chooseImage({count: 9,success: async (chooseImageRes) => {const tempFilePaths = chooseImageRes.tempFilePaths;const uploadPromises = tempFilePaths.map(filePath => {return new Promise((resolve, reject) => {uni.uploadFile({url: 'https://your-server-url/upload',filePath: filePath,name: 'file',success: (res) => {resolve(res);},fail: (error) => {reject(error);}});});});try {const results = await Promise.all(uploadPromises);console.log('所有文件上传成功', results);} catch (error) {console.error('文件上传失败', error);}}
});

断点续传实现

对于大文件上传,断点续传是一个非常有用的功能,可以在网络中断后继续上传,而不必重新开始。UniApp 本身并没有直接提供断点续传功能,但我们可以结合服务端实现:

  1. 前端分片上传:将大文件分成多个小块
  2. 记录已上传的分片
  3. 上传中断后,只上传未完成的分片

下面是一个简化的分片上传实现:

// 文件分片上传示例
export default {data() {return {chunkSize: 1024 * 1024, // 1MB一个分片uploadedChunks: [], // 已上传的分片索引totalChunks: 0, // 总分片数fileId: '', // 文件唯一标识}},methods: {// 选择文件并开始上传async chooseAndUploadFile() {// 选择文件(H5平台示例)uni.chooseFile({count: 1,extension: ['.zip', '.doc', '.pdf'],success: (res) => {const tempFilePath = res.tempFilePaths[0];const file = res.tempFiles[0];// 生成文件唯一标识this.fileId = this.generateFileId(file.name, file.size);// 计算分片数量this.totalChunks = Math.ceil(file.size / this.chunkSize);// 检查已上传的分片this.checkUploadedChunks(this.fileId).then(() => {// 开始上传未完成的分片this.uploadChunks(tempFilePath, file);});}});},// 生成文件IDgenerateFileId(fileName, fileSize) {return `${fileName}-${fileSize}-${Date.now()}`;},// 检查已上传的分片async checkUploadedChunks(fileId) {try {const res = await uni.request({url: 'https://your-server-url/check-chunks',data: { fileId }});if (res.data.code === 0) {this.uploadedChunks = res.data.data.uploadedChunks || [];}} catch(error) {console.error('检查已上传分片失败', error);this.uploadedChunks = [];}},// 上传分片async uploadChunks(filePath, file) {// 此处仅为示例逻辑,实际实现可能需要根据平台特性调整// 在H5平台可以使用File API进行分片,其他平台可能需要其他方式for (let i = 0; i < this.totalChunks; i++) {// 如果分片已上传,则跳过if (this.uploadedChunks.includes(i)) {continue;}try {// 这里简化处理,实际中可能需要读取文件分片内容await this.uploadChunk(filePath, i, this.fileId);// 记录已上传的分片this.uploadedChunks.push(i);// 保存上传进度,用于断点续传uni.setStorageSync(`upload-progress-${this.fileId}`, {uploadedChunks: this.uploadedChunks,totalChunks: this.totalChunks});} catch (error) {console.error(`分片${i}上传失败`, error);break;}}// 检查是否所有分片都已上传if (this.uploadedChunks.length === this.totalChunks) {// 通知服务器合并分片this.mergeChunks(this.fileId, file.name);}},// 上传单个分片uploadChunk(filePath, chunkIndex, fileId) {return new Promise((resolve, reject) => {uni.uploadFile({url: 'https://your-server-url/upload-chunk',filePath: filePath, // 实际应该是分片后的文件路径name: 'chunk',formData: {chunkIndex,fileId,totalChunks: this.totalChunks},success: (res) => {if (res.statusCode === 200) {resolve(res.data);} else {reject(res);}},fail: reject});});},// 通知服务器合并分片async mergeChunks(fileId, fileName) {try {const res = await uni.request({url: 'https://your-server-url/merge-chunks',method: 'POST',data: { fileId, fileName }});if (res.data.code === 0) {console.log('文件上传完成', res.data);// 清除上传进度缓存uni.removeStorageSync(`upload-progress-${fileId}`);}} catch (error) {console.error('合并分片失败', error);}}}
}

需要注意的是,上述代码仅为示例,实际实现时需要结合具体的服务端接口和业务需求进行调整。

文件下载功能实现

基本文件下载

使用 uni.downloadFile 可以实现文件下载功能:

uni.downloadFile({url: 'https://your-server-url/example.pdf',success: (res) => {if (res.statusCode === 200) {console.log('下载成功', res.tempFilePath);// 保存文件到本地uni.saveFile({tempFilePath: res.tempFilePath,success: (saveRes) => {console.log('文件保存成功', saveRes.savedFilePath);// 可以使用 savedFilePath 在应用内查看文件}});}}
});

下载进度监控

与上传类似,下载也可以监控进度:

const downloadTask = uni.downloadFile({url: 'https://your-server-url/example.pdf',success: (res) => {console.log('下载完成', res);}
});downloadTask.onProgressUpdate((res) => {console.log('下载进度', res.progress);console.log('已经下载的数据长度', res.totalBytesWritten);console.log('预期需要下载的数据总长度', res.totalBytesExpectedToWrite);// 更新界面上的进度条this.downloadProgress = res.progress;
});

文件下载与打开

下载完成后,我们常常需要打开文件供用户查看。UniApp 提供了 uni.openDocument 方法来打开文件:

uni.downloadFile({url: 'https://your-server-url/example.pdf',success: (res) => {if (res.statusCode === 200) {// 打开文档uni.openDocument({filePath: res.tempFilePath,showMenu: true, // 是否显示菜单success: () => {console.log('打开文档成功');}});}}
});

实战案例:多媒体文件管理器

下面是一个集成了上传、下载和文件管理功能的实例,实现一个简易的多媒体文件管理器:

<template><view class="container"><view class="header"><view class="title">文件管理器</view><view class="actions"><button type="primary" size="mini" @click="chooseAndUploadFile">上传文件</button></view></view><!-- 上传进度展示 --><view class="progress-section" v-if="showUploadProgress"><text>上传进度: {{ uploadProgress }}%</text><progress :percent="uploadProgress" stroke-width="4" /><button size="mini" @click="cancelUpload">取消</button></view><!-- 文件列表 --><view class="file-list"><view class="file-item" v-for="(item, index) in fileList" :key="index"><view class="file-info"><image class="file-icon" :src="getFileIcon(item.fileType)"></image><view class="file-detail"><text class="file-name">{{ item.fileName }}</text><text class="file-size">{{ formatFileSize(item.fileSize) }}</text></view></view><view class="file-actions"><button size="mini" @click="downloadFile(item)">下载</button><button size="mini" type="warn" @click="deleteFile(item.id)">删除</button></view></view></view><!-- 下载进度弹窗 --><view class="download-modal" v-if="showDownloadProgress"><view class="modal-content"><text>正在下载: {{ currentDownloadFile.fileName }}</text><progress :percent="downloadProgress" stroke-width="4" /><text>{{ downloadProgress }}%</text><button type="primary" size="mini" @click="cancelDownload">取消</button></view></view></view>
</template><script>
export default {data() {return {fileList: [],uploadProgress: 0,downloadProgress: 0,showUploadProgress: false,showDownloadProgress: false,currentUploadTask: null,currentDownloadTask: null,currentDownloadFile: {}}},onLoad() {// 加载文件列表this.loadFileList();},methods: {// 加载文件列表async loadFileList() {try {const res = await uni.request({url: 'https://your-server-url/files',method: 'GET'});if (res.data.code === 0) {this.fileList = res.data.data.files || [];}} catch (error) {console.error('获取文件列表失败', error);uni.showToast({title: '获取文件列表失败',icon: 'none'});}},// 选择并上传文件chooseAndUploadFile() {// 由于平台差异,这里以H5为例// 实际开发中需要根据平台使用不同的APIuni.chooseFile({count: 1,success: (res) => {const tempFilePath = res.tempFilePaths[0];const file = res.tempFiles[0];this.uploadFile(tempFilePath, file);}});},// 上传文件uploadFile(filePath, file) {this.showUploadProgress = true;this.uploadProgress = 0;this.currentUploadTask = uni.uploadFile({url: 'https://your-server-url/upload',filePath: filePath,name: 'file',formData: {fileName: file.name,fileSize: file.size,fileType: file.type || this.getFileTypeByName(file.name)},success: (res) => {if (res.statusCode === 200) {try {const data = JSON.parse(res.data);if (data.code === 0) {uni.showToast({title: '上传成功',icon: 'success'});// 刷新文件列表this.loadFileList();} else {throw new Error(data.message || '上传失败');}} catch (error) {uni.showToast({title: error.message || '上传失败',icon: 'none'});}} else {uni.showToast({title: '服务器响应错误',icon: 'none'});}},fail: (error) => {console.error('上传失败', error);uni.showToast({title: '上传失败',icon: 'none'});},complete: () => {this.showUploadProgress = false;this.currentUploadTask = null;}});this.currentUploadTask.onProgressUpdate((res) => {this.uploadProgress = res.progress;});},// 取消上传cancelUpload() {if (this.currentUploadTask) {this.currentUploadTask.abort();this.showUploadProgress = false;uni.showToast({title: '已取消上传',icon: 'none'});}},// 下载文件downloadFile(fileItem) {this.showDownloadProgress = true;this.downloadProgress = 0;this.currentDownloadFile = fileItem;this.currentDownloadTask = uni.downloadFile({url: fileItem.downloadUrl,success: (res) => {if (res.statusCode === 200) {// 保存文件uni.saveFile({tempFilePath: res.tempFilePath,success: (saveRes) => {uni.showToast({title: '文件已保存',icon: 'success'});// 打开文件this.openFile(saveRes.savedFilePath, fileItem.fileType);},fail: (error) => {console.error('保存文件失败', error);uni.showToast({title: '保存文件失败',icon: 'none'});}});}},fail: (error) => {console.error('下载失败', error);uni.showToast({title: '下载失败',icon: 'none'});},complete: () => {this.showDownloadProgress = false;this.currentDownloadTask = null;}});this.currentDownloadTask.onProgressUpdate((res) => {this.downloadProgress = res.progress;});},// 取消下载cancelDownload() {if (this.currentDownloadTask) {this.currentDownloadTask.abort();this.showDownloadProgress = false;uni.showToast({title: '已取消下载',icon: 'none'});}},// 打开文件openFile(filePath, fileType) {uni.openDocument({filePath: filePath,fileType: this.getDocumentFileType(fileType),success: () => {console.log('打开文档成功');},fail: (error) => {console.error('打开文档失败', error);uni.showToast({title: '无法打开此类型文件',icon: 'none'});}});},// 删除文件async deleteFile(fileId) {try {uni.showModal({title: '提示',content: '是否确认删除此文件?',success: async (res) => {if (res.confirm) {const deleteRes = await uni.request({url: 'https://your-server-url/delete-file',method: 'POST',data: { fileId }});if (deleteRes.data.code === 0) {uni.showToast({title: '删除成功',icon: 'success'});// 刷新文件列表this.loadFileList();} else {throw new Error(deleteRes.data.message || '删除失败');}}}});} catch (error) {console.error('删除文件失败', error);uni.showToast({title: error.message || '删除失败',icon: 'none'});}},// 根据文件名获取文件类型getFileTypeByName(fileName) {const ext = fileName.split('.').pop().toLowerCase();const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];const videoTypes = ['mp4', 'avi', 'mov', 'wmv', 'flv'];const docTypes = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt'];if (imageTypes.includes(ext)) return 'image';if (videoTypes.includes(ext)) return 'video';if (docTypes.includes(ext)) return 'document';return 'other';},// 获取文件图标getFileIcon(fileType) {const iconMap = {image: '/static/icons/image.png',video: '/static/icons/video.png',document: '/static/icons/document.png',other: '/static/icons/file.png'};return iconMap[fileType] || iconMap.other;},// 格式化文件大小formatFileSize(size) {if (size < 1024) {return size + 'B';} else if (size < 1024 * 1024) {return (size / 1024).toFixed(2) + 'KB';} else if (size < 1024 * 1024 * 1024) {return (size / (1024 * 1024)).toFixed(2) + 'MB';} else {return (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB';}},// 获取文档类型(用于openDocument)getDocumentFileType(fileType) {if (fileType === 'document') {return 'pdf'; // 默认作为PDF处理,实际应根据具体后缀判断}return '';}}
}
</script><style>
.container {padding: 20rpx;
}.header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 30rpx;
}.title {font-size: 36rpx;font-weight: bold;
}.progress-section {margin: 20rpx 0;padding: 20rpx;background-color: #f5f5f5;border-radius: 8rpx;
}.file-list {margin-top: 20rpx;
}.file-item {display: flex;justify-content: space-between;align-items: center;padding: 20rpx;border-bottom: 1rpx solid #eee;
}.file-info {display: flex;align-items: center;
}.file-icon {width: 60rpx;height: 60rpx;margin-right: 20rpx;
}.file-detail {display: flex;flex-direction: column;
}.file-name {font-size: 30rpx;margin-bottom: 6rpx;
}.file-size {font-size: 24rpx;color: #999;
}.file-actions button {margin-left: 10rpx;
}.download-modal {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;z-index: 999;
}.modal-content {width: 80%;padding: 30rpx;background-color: #fff;border-radius: 10rpx;text-align: center;
}.modal-content progress {margin: 20rpx 0;
}
</style>

常见问题与解决方案

1. 上传大文件失败

问题:上传大文件时经常会失败。
解决方案

  1. 实现上文中提到的分片上传和断点续传
  2. 检查服务器的上传大小限制
  3. 检查网络连接稳定性

2. 不同平台的兼容性问题

问题:在不同平台(iOS、Android、H5)上文件操作API的行为可能有差异。
解决方案

  1. 使用条件编译处理平台差异
  2. 使用 uni.getSystemInfo() 检测平台
  3. 测试各个平台的表现
// 条件编译示例
// #ifdef H5
// H5 平台特有代码
uni.chooseFile({count: 1,success: (res) => {// ...}
});
// #endif// #ifdef APP-PLUS
// App 平台特有代码
uni.chooseImage({count: 1,success: (res) => {// ...}
});
// #endif

3. 文件类型限制

问题:无法指定允许用户选择的具体文件类型。
解决方案

  • 在 H5 平台,可以使用 uni.chooseFileextension 参数
  • 在 App 平台,需要通过 plus.io API 来实现更细粒度的控制
  • 也可以在选择文件后进行类型检查,不符合要求则给出提示

4. 下载文件后无法正确打开

问题:某些文件下载后无法通过 uni.openDocument 正确打开。
解决方案

  1. 检查文件类型是否受支持
  2. 对于特定文件,可能需要安装第三方应用来打开
  3. 在 App 平台,可以使用原生 API 提供更多打开方式

性能优化与最佳实践

  1. 使用缓存策略:对于频繁下载的文件,可以实现缓存机制,避免重复下载。

  2. 优化上传文件大小:在上传前压缩图片或其他可压缩的文件,减少传输时间和带宽消耗。

// 压缩图片示例
uni.compressImage({src: tempFilePath,quality: 80,success: (res) => {// 使用压缩后的图片路径上传this.uploadFile(res.tempFilePath);}
});
  1. 批量处理优化:对于批量上传或下载,可以控制并发数量,避免同时进行太多请求。

  2. 错误重试机制:添加自动重试逻辑,提高操作的成功率。

// 带重试的下载示例
function downloadWithRetry(url, maxRetries = 3) {let retryCount = 0;function attempt() {return new Promise((resolve, reject) => {uni.downloadFile({url,success: resolve,fail: (error) => {if (retryCount < maxRetries) {retryCount++;console.log(`下载失败,第${retryCount}次重试`);resolve(attempt());} else {reject(error);}}});});}return attempt();
}
  1. 合理的进度反馈:避免在界面上频繁更新进度,可以设置节流,如每秒更新几次。

  2. 安全性考虑:校验文件类型和大小,防止用户上传恶意文件。

总结

本文详细介绍了如何在 UniApp 中实现文件上传与下载功能,从基本用法到高级特性,再到实战案例,希望能帮助开发者在实际项目中更好地处理文件操作需求。文件上传下载虽然是常见功能,但要做好做全面并不简单,需要考虑用户体验、性能优化、安全性等多方面因素。

在实际开发中,建议根据具体的业务需求和目标平台特点,灵活运用本文提供的方法,打造出更加完善的文件处理功能。

你可能还需要了解服务端如何处理文件上传和分片合并,这部分内容因为涉及后端开发,本文未做详细展开。如有需要,可查阅相关服务端技术文档。

相关文章:

鸿蒙OSUniApp 开发的文件上传与下载功能#三方框架 #Uniapp

使用 UniApp 开发的文件上传与下载功能 前言 在移动应用开发中&#xff0c;文件上传与下载是非常常见且重要的功能需求。无论是上传用户头像、提交表单附件&#xff0c;还是下载资源文件、缓存图片&#xff0c;这些需求几乎存在于每一个成熟的应用中。UniApp 作为一个跨平台开…...

【MySQL】基础知识

MySQL(一)基础知识 MySQL 一、结构 1.客户端 2.服务器 分布式系统 二、存储 1.空间 1.1内存 1.1.1速度 1.1.2稳定性 1.1.3大小 1.1.4使用 1.2硬盘 1.2.1速度 1.2.2稳定性 1.2.3大小 1.2.4【Java学习】反射-CSDN博客 2.体系 表-数据库-服务器 3.特点 3.1…...

产品销量数据爬虫通用模板

最近遇到各行各业的需要爬取销售数据&#xff0c;每次写一个教程相对麻烦&#xff0c;所以思前考后我还是觉得写一个通用模板更适合。所以模板需要足够的灵活性&#xff0c;让用户能够自定义选择器。比如&#xff0c;产品标题、价格、销量的CSS选择器可能因网站而异&#xff0c…...

一文讲透 Vue3 + Three.js 材质属性之皮革篇【扫盲篇】

文章目录 前言一、Three.js材质系统基础1.1 为什么选择PBR材质&#xff1f;1.2 关键参数解析 二、不同类型皮革的材质配置2.1 牛皮材质实现2.2 羊皮材质实现2.3 仿皮材质实现 三、高级贴图技术3.1 贴图制作流程3.2 组合贴图实战 四、性能优化策略4.1 贴图压缩技术4.2 材质共享4…...

mysql读写分离

一、读写分离原理 客户端连接代理层&#xff0c;代理层&#xff08;中间件&#xff09;来实现读操作给从服务器&#xff0c;写操作给主服务器。 二、示例 mycat实现读写分离 读写分离在主从复制的基础上 1客户机1代理1主2从1、网络主 192.168.10.101从1 192.168.10.102从2 …...

Java集合框架

集合 概念&#xff1a;对象的容器&#xff0c;定义了对多个对象进行操作的常用方法。可实现数组的功能 和数组的区别 数组长度固定&#xff0c;集合长度不固定 数组可以存储基本类型和引用类型&#xff0c;集合只能存储引用类型 位置&#xff1a;java.util.* Collection体…...

salesforce如何导出所有字段

在 Salesforce 中&#xff0c;导出所有字段信息&#xff08;包括字段名、API 名、字段类型、是否可报表、是否可搜索等&#xff09;通常不是一个“一键完成”的操作&#xff0c;但可以通过几种方法实现。以下是常用的几种方法&#xff1a; ✅ 方法一&#xff1a;使用 Salesforc…...

一招解决Tailwindcss4.x与其他库样式冲突问题

当项目中引入tailwindcss&#xff0c;并与其他UI库混用时&#xff0c;可能会出现样式冲突问题&#xff0c;因为tailwindcss重置了一些基础样式&#xff0c;例如&#xff1a;引入tailwindcss后&#xff0c;原生button按钮没有了默认的样式。 在老版本中解决这个问题&#xff0c…...

[Harmony]封装一个可视化的数据持久化工具

1.添加权限 在module.json5文件中添加权限 // 声明应用需要请求的权限列表 "requestPermissions": [{"name": "ohos.permission.DISTRIBUTED_DATASYNC", // 权限名称&#xff1a;分布式数据同步权限"reason": "$string:distrib…...

关于AI人工智能的知识图谱简介

人工智能是计算机科学的一个重要领域&#xff0c;旨在理解和构建智能行为。人工智能可以被划分为多个子领域或分支&#xff0c;包括机器学习、深度学习、自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;、计算机视觉&#xff08;Computer Vis…...

uniapp,小程序中实现文本“展开/收起“功能的最佳实践

文章目录 示例需求分析实现思路代码实现1. HTML结构2. 数据管理3. 展开/收起逻辑4. CSS样式 优化技巧1. 性能优化2. 防止事件冒泡3. 列表更新处理 实际效果总结 在移动端应用开发中&#xff0c;文本内容的"展开/收起"功能是提升用户体验的常见设计。当列表项中包含大…...

RabbitMQ 消息模式实战:从简单队列到复杂路由(一)

RabbitMQ 初相识 在当今分布式系统大行其道的技术领域中&#xff0c;消息队列作为实现系统间异步通信、解耦以及流量削峰的关键组件&#xff0c;发挥着不可或缺的作用。而 RabbitMQ&#xff0c;无疑是消息队列领域中一颗耀眼的明星。自 2007 年诞生以来&#xff0c;RabbitMQ 凭…...

阿里云ECS部署Dify

一&#xff1a;在ECS上面安装Docker 关防火墙 sudo systemctl stop firewalld 检查防火墙状态 systemctl status firewalld sudo yum install -y yum-utils device-mapper-persistent-data lvm2 设置阿里镜像源&#xff0c;安装并启动docker [base] nameCentOS-$releas…...

Missashe考研日记—Day37-Day43

Missashe考研日记—Day37-Day43 写在面前 本系列博客用于记录博主一周的学习进度&#xff0c;具体知识总结在目前已有的笔记中&#xff1a; 1.高数强化学习笔记2.计网复习笔记 本周五到周日有其他安排&#xff0c;所以今天就把这一周的先更新了。 专业课408 这周学了计网的…...

DB-GPT扩展自定义app配置说明

简介 文章主要介绍了如何扩展一个自定义app插件&#xff0c;这里先看下生成效果&#xff0c;生成的内容其实还是有问题的&#xff0c;后续博主会调整提示词看看能不能优化生成效果 修改代码 代码详情 # chat_di是从chat_normal复制过来的&#xff0c;这里只改了提示词 from d…...

2025年11月软考各科目难度及适合人群分析

2025上半年软考考试报名已结束&#xff0c;不少小伙伴已经在咨询下半年的考试科目了&#xff0c;今天就给大家推荐几个好考的科目。 一、2025下半年软考考试科目 2025下半年软考考试时间为11月8日至11日。 根据计考办发布的《关于2025年度计算机技术与软件专业技术资格&…...

vue异步导入

vue的异步导入 大家开发vue的时候或多或少路由的异步导入 component: () >import(“/views/A_centerControl/intelligent-control/access-user-group”),当然这是路由页面&#xff0c;那么组件也是可以异步导入的 使用方式 组件的异步导入非常简单&#xff0c;主要是一个…...

[IMX] 03.时钟树 - Clock Tree

目录 1.PLL 时钟源 2.Clock Tree 时钟树 3.ARM 内核时钟 3.1.频率设置 - CCM_ANALOG_PLL_ARMn 3.2.时钟分频 - CCM_CACRR 3.3.时钟源选择 - CCM_CCSR 3.4.修改 ARM 内核时钟 4.PFD 时钟 4.1.PLL2_PFD 频率 - CCM_ANALOG_PFD_528n 4.2.PLL3_PFD 频率 - CCM_ANALOG_PFD…...

低功耗实现方法思路总结

1.硬件选型最重要&#xff0c;比如stm 8l &#xff0c;MSP430&#xff0c;瑞萨rl78,lpc11等 2.开发仿真务必使用高精度万用表如fluke 3.在整体规划层面&#xff0c;避免引脚未配置的浮空状态 a)在设计开发层面&#xff0c;对于使用的信号&#xff0c;使用上下拉电阻或者推挽…...

广州SMT贴片技术优势与工艺解析

内容概要 作为电子制造领域的关键技术&#xff0c;广州SMT贴片工艺凭借其高精度与高效性&#xff0c;已成为现代电子装配的核心支撑。本文通过系统性梳理表面贴装技术&#xff08;SMT&#xff09;的全流程&#xff0c;重点聚焦广州地区在该领域的独特技术优势。内容涵盖从焊膏…...

乡村地区无人机医药配送路径规划与优化仿真

本代码意在通过对无人机路径规划和载具选择进一步帮助乡村振兴&#xff0c;提高农村卫生条件&#xff0c;让患者足不出户就可享受到医疗服务&#xff0c;旨在完善乡村基础设施建设&#xff0c;积极响应国家“十四五”规划的号召。 先选择适合在该地区配送医药物资环境下的载具材…...

AWS Elastic Beanstalk部署极简Spring工程(EB CLI失败版)

弃用 这里我没有走通EB CLI方式部署。 问题 最近又加入了AWS项目组&#xff0c;又要再次在AWS云上面部署Spring服务&#xff0c;我这里使用的使用AWS中国云。需要使用AWS Elastic Beanstalk部署一个极简Spring工程。 EB CLI安装 安装EB CLI之前需要先在本地安装好Git&…...

[训练和优化] 3. 模型优化

&#x1f44b; 你好&#xff01;这里有实用干货与深度分享✨✨ 若有帮助&#xff0c;欢迎&#xff1a;​ &#x1f44d; 点赞 | ⭐ 收藏 | &#x1f4ac; 评论 | ➕ 关注 &#xff0c;解锁更多精彩&#xff01;​ &#x1f4c1; 收藏专栏即可第一时间获取最新推送&#x1f514;…...

element-ui的el-cascader增加全选按钮实现(附源码)

最近遇到了在级联选择器上添加全选框的需求 &#xff0c;但是项目使用的是Vue2 Element UI的架构&#xff0c;而我们都知道Element UI提供的级联选择器el-cascader是不支持全选框的&#xff0c;而我又没有在网上找到适合我项目的实现&#xff0c;索性自己实现一个组件&#xf…...

OpenCV人脸识别EigenFace算法、案例解析

文章目录 前言一、EigenFace 核心原理二、Python 实战&#xff1a;手把手搭建 EigenFace 识别系统1. 环境准备2. 代码实现与步骤详解3. 加载数据集函数4. 训练EigenFace模型函数5. 预测函数6.主程序部分7. 可视化结果8. 代码分步解读 三、优化技巧四、总结 前言 在人脸识别领域…...

Python模块化编程

Python模块化编程 记得我刚学Python那会儿&#xff0c;特别喜欢把所有代码都写在一个文件里。直到有一天&#xff0c;我的项目膨胀到了2000多行代码&#xff0c;每次修改都要翻半天…这才痛定思痛&#xff0c;开始研究模块化编程。今天就跟大家聊聊这个让代码变得优雅的魔法。…...

Java对象的GC回收年龄的研究

目录 1、介绍 2、内存结构 2.1、普通对象 2.2、数组对象 2.3、数组长度作用 2.4、为什么 age 用 4 位&#xff1f; 3、对象头组成 3.1、Mark Word&#xff08;标记字段&#xff09; 3.2、Class Pointer&#xff08;类指针&#xff09; 4、GC 发生的位置 4.1、新生代…...

IT系统的基础设施:流量治理、服务治理、资源治理,还有数据治理。

文章目录 引言I IT系统的基础设施流量治理、服务治理、资源治理,还有数据治理。开发语言的选择数据治理(监控系统):整体运维的数据其他II 基础知识的重要性第一,知道原理第二,当遇到一些比较难解的问题时,基础知识就会派上用场。例子III 快速学会一门编程语言把语言照着…...

SpringBoot应用启动过程

Spring 应用抽象 Springboot 是一个用来快速创建 Spring 应用的微服务框架&#xff0c;启动引导器是org.springframework.boot.SpringApplication 这个类&#xff0c;每个 SpringApplication 实例就表示一个 Spring 应用的启动类&#xff1b;Spring 应用生命周期包括创建、启动…...

傻子学编程之——Java并发编程的问题与挑战

傻子学编程之——Java并发编程的问题与挑战 Java并发编程能让程序跑得更快&#xff0c;但也像走钢丝一样充满风险。本文用最直白的语言和代码示例&#xff0c;带你直面并发编程的四大「致命陷阱」&#xff0c;并给出解决方案。 一、资源竞争&#xff1a;多个线程打架怎么办&am…...

groovy 如何遍历 postgresql 所有的用户表 ?

在 Groovy 中遍历 PostgreSQL 所有用户表&#xff0c;你可以使用 JDBC 连接数据库并执行 SQL 查询。以下是一个完整的示例&#xff1a; Groovy 代码示例 import groovy.sql.Sqldef config [url: jdbc:postgresql://localhost:5432/your_database,user: your_username,passwo…...

CPU cache基本原理

CPU cache基本原理 存储器层次结构存储器层次结构中的缓存高速缓存存储器直接映射高速缓存组相联高速缓存全相联高速缓存 多核 CPU 下缓存问题内存的读写操作流程数据一致性与并发控制 高速缓存&#xff08;cache&#xff09;是一个小而快速地存储设备&#xff0c;它作为存储在…...

【Java学习笔记】【第一阶段项目实践】零钱通(面向过程版本)

零钱通&#xff08;面向过程版本&#xff09; 需求分析 1. 需要实现的功能 (1) 收益入账 (2) 消费 (3 )查看明细 (4 )退出系统 2. 代码优化部分 (1) 对用户输入 4 退出时&#xff0c;给出提示 “你确定要退出吗&#xff1f;y/n”&#xff0c;必须输入正确的 y/n&#xff0c…...

Cursor无法使用C/C++调试的解决办法

背景 这几天在二开ffmpeg&#xff0c;发现用cursor无法使用cppdbg进行调试&#xff0c;只能上机gdb&#xff0c;比较麻烦。 配置文件 // launch.json {// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// Fo…...

VSTO(C#)Excel开发进阶2:操作图片 改变大小 滚动到可视区

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 入…...

嵌入式自学第二十二天(5.15)

顺序表和链表 优缺点 存储方式&#xff1a; 顺序表是一段连续的存储单元 链表是逻辑结构连续物理结构&#xff08;在内存中的表现形式&#xff09;不连续 时间性能&#xff0c; 查找顺序表O(1)&#xff1a;下标直接查找 链表 O(n)&#xff1a;从头指针往后遍历才能找到 插入和…...

高云FPGA-新增输出管脚约束

module led (input sys_clk, // clk inputinput sys_rst_n, // reset inputoutput reg [5:0] led, // 6 LEDS pinoutput reg gpio // 1 GPIO pin 25 ); 在原来的代码基础上新增加一个gpio输出&#xff0c;绑定到25管脚上 打开工程文件夹中的cts文件…...

Nginx 返回 504 状态码表示 网关超时(Gateway Timeout)原因排查

Nginx 返回 504 状态码表示 网关超时&#xff08;Gateway Timeout&#xff09;&#xff0c;这意味着 Nginx 作为反向代理服务器&#xff0c;在等待上游服务器&#xff08;如后端应用服务器、数据库服务器等&#xff09;响应时&#xff0c;超过了预设的时间限制&#xff0c;最终…...

单片机 | 基于STM32的智能马桶设计

基于STM32的智能马桶设计结合了传感器技术、嵌入式控制及物联网功能,旨在提升用户体验并实现健康监测。以下是其设计原理、功能模块及代码框架的详细解析: 一、系统架构与核心功能 智能马桶的系统架构通常分为主控模块、传感器模块、执行器模块、通信模块及用户交互模块,主…...

2900. 最长相邻不相等子序列 I

2900. 最长相邻不相等子序列 I class Solution:def getLongestSubsequence(self, words: List[str], groups: List[int]) -> List[str]:n len(groups) # 获取 groups 列表的长度ans [] # 初始化一个空列表&#xff0c;用于存储结果for i, g in enumerate(groups): # 遍…...

欧姆龙 CJ/CP 系列 PLC 串口转网口模块:工业通信升级的智能之选

在工业自动化领域&#xff0c;欧姆龙 CJ/CP 系列 PLC 凭借高可靠性和灵活扩展性&#xff0c;广泛应用于汽车制造、食品加工、能源化工等关键行业。然而&#xff0c;传统串口通信的局限性&#xff08;如距离受限、协议兼容性差、难以实现远程监控&#xff09;却成为企业智能化升…...

BGP选路实验

一.需求 1.使用PreVal策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2.使用As_Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3.配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4.使用Local Preference策略&#xff0c;确保R1通过R2到达192.168.1.0/2…...

Linux服务之lvs+keepalived nginx+keepalived负载均衡实例解析

目录 一.LVSKeepAlived高可用负载均衡集群的部署 二.NginxKeepAlived高可用负载均衡集群的部署 一.LVSKeepAlived高可用负载均衡集群的部署 实验环境 主keepalived&#xff1a;192.168.181.10 lvs &#xff08;7-1&#xff09; 备keepalived&#xff1a;192.168.181.10…...

idea整合maven环境配置

idea整合maven 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#xff1a;每个知识点&#xff0c;都是写出代码…...

pytest框架 - 第二集 allure报告

一、断言assert 二、Pytest 结合 allure-pytest 插件生成美观的 Allure 报告 (1) 安装 allure 环境 安装 allure-pytest 插件&#xff1a;pip install allure-pytest在 github 下载 allure 报告文件 地址&#xff1a;Releases allure-framework/allure2 GitHub下载&#x…...

互联网大厂Java求职面试:构建高并发直播平台的架构设计与优化

标题&#xff1a;互联网大厂Java求职面试&#xff1a;构建高并发直播平台的架构设计与优化 引言 在互联网大厂的Java求职面试中&#xff0c;技术总监级别的面试官通常会提出一系列复杂且前沿的技术问题&#xff0c;以评估候选人的真实技术水平。本篇文章将围绕构建一个千万级…...

Ruby 循环与迭代器

Ruby 循环与迭代器 循环迭代器timesuptostep 循环 。。。。 迭代器 迭代器本质上可以理解为是循环的一种类型 times 3.times do print "Ho! " end begin Ho! Ho! Ho! end上述代码表示我们对当前 block 部分中的内容循环三次。最终&#xff0c;我们打印出了三个…...

pyenv简单的Python版本管理器(macOS版)

问题 python版本是真的多&#xff0c;需要用一个版本管理器管理Python多版本安装在同一台机器的问题。接下来&#xff0c;我们就尝试使用pyenv来管理。 安装pyenv brew update brew install pyenv配置Zsh echo export PYENV_ROOT"$HOME/.pyenv" >> ~/.zshr…...

Automatic Recovery of the Atmospheric Light in Hazy Images论文阅读

Automatic Recovery of the Atmospheric Light in Hazy Images 1. 论文的研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、模型与公式2.1 方法框架2.1.1 方向估计(Orientation Estimation)2.1.2 幅值估计(Magnitude Estimation)2.2 与传统方法的对…...

Vuex和Vue的区别

Vue和Vuex有着不同的功能和定位&#xff0c;主要区别如下&#xff1a; 概念与功能 - Vue&#xff1a;是一个构建用户界面的JavaScript框架&#xff0c;专注于视图层的开发&#xff0c;采用组件化的方式构建应用程序&#xff0c;通过数据绑定和指令系统&#xff0c;能方便地…...