[疑难杂症2023-002]不就是Move一个文件吗,怎么会有这么多坑呢?

news2024/9/20 14:44:40

本文由Markdown语法编辑器编辑完成.

1. 前言:

近期在项目中遇到一个需求.
背景是,在一个QT封装的C/S架构的软件中,一个报告的预览页面,是由QT封装了QWebWidget, 里面放着一个网页.这个网页通过调用一定的逻辑,可以将当前看到的网页,生成一个pdf, 存储到一个路径下面.

由于前端在执行js(调用jsPdf库)时,无法设置存储路径,因此只能存储在软件安装的当前目录下面.比如,这个C/S架构的软件,是安装在了D盘下面的某个文件夹中.

但是,我们希望这个报告的pdf, 默认生成在C盘的一个指定目录下面.

因此,这个需求概括起来就是:
a> 前端默认将pdf生成在了D盘的某一个路径下面;
b> 后端如何在pdf生成后,将这个pdf文件,挪到用户指定的C盘的某个路径下面.
在这里插入图片描述

2. 解决方案探索:

2.1 前端通知后端,后端move到指定位置

根据需求,很容易想到的解决方案是,前端在生成pdf后,通知一下后端.后端去指定路径下面,找到生成的pdf, 通过os.move()或shutil.move()的指令,将pdf挪到到指定位置即可.
但是在实际的测试中,会遇到很多意向不到的问题.

2.1.1 前端异步生成pdf

由于前端在调用jsPdf组件生成pdf的操作,是一个异步操作.
因为生成报告的pdf时间很长,大约有80 ~ 120M左右.因此,前端不可能做成同步操作,只能是异步来进行.
这就会造成,前端在发出生成pdf的指令后,如果马上通知后端.
后端去指定的路径下,准备移动这个文件时,这个文件可能压根还没有生成出来呢,还是计算机的内存中呢.于是就会报"FileNotFound"之类的异常.

2.1.2 后端增加等待机制

为了解决FileNotFound的问题,后端能够想到的方法,自然是增加等待机制.通过轮询,每隔一定时间去查看一下pdf文件是否生成.比如,增加while循环.

import os
import shutil
......
while:
	if not os.path.exists("报告1.pdf"):
		sleep(1)
	else:
		break
shutil.move("D:/报告1.pdf", "C:/target")

但是实际测试时,会遇到进程阻塞的问题.
由于Python默认是单进程执行的.因此当这里增加了while循环这样的指令后,进程就会一直卡在这里.
客户端无法执行任何其他的操作,出现未响应之类的问题.

另一种方法,当然是通过创建多进程的方法.
比如,把判断pdf是否存在和挪动pdf, 放在另一个Process里面,不要影响主进程.
大致代码如下:

import os
from multiprocessing import Process

move_pdf_process = Process(target=move_pdf_file, args=("D:/报告1.pdf", ))
move_pdf_process.start()

def move_pdf_file(file_path):
	while:
		if not os.path.exists(file_path):
			sleep(1)
		else:
			shutil.move(file_path, "C:/target")

通过这种机制,解决了移动文件时,文件不存在的问题.
但是又会遇到新的问题.

2.1.3 文件正在写入,移动后文件不完整或为空

上面的方法,虽然解决了文件移动时,文件还不存在造成的问题.
但是之前忽略的一个问题时,这个文件虽然落盘了,但是文件可能还正在被写入中.因为文件内容很多,它不是一次性被写入的,而是有一个过程.
于是,就需要想办法来判断,这个文件什么时候写完了.
我尝试了两种方法吧,第1种是,每隔1秒,判断文件的大小有没有发生改变; 第2种是,每隔1秒,判断文件的修改时间有没有发生改变.
但是,这两种方法,在实际的使用中,还是会遇到问题.
比如,即使判断出,这个文件的大小和更新时间已经不变了,但是挪动后,查看文件还是为空.

2.1.4 通过创建硬链接的方式

在经历了上述的尝试后,直接挪动文件的方案,基本上被否决了.
后来,我想到的方法是创建硬链接.也就是将文件初始生成的路径,和想要挪到的目标路径,创建硬链接.
这样,原始文件的任何变化,都会同步到目标路径下.
创建硬链接的方式如下:

import os
os.link("D/报告1.pdf", "C/target/报告1.pdf")

但是,运行这条指令,在windows操作系统下,也会报错.
后来查询了一下,windows上,如果是在同一盘符下运行os.link没问题,但是跨越盘符运行时,会报错.
因此,这个方案也被否决了.

结论:

经过接近两三天的尝试,我最初的方案,被否决了.

虽然,独立进行功能测试时,比如,首先把一个现成的pdf文件,放到D盘,再运行shutil.move()来移动这个pdf文件到C盘,是完全没问题的.但是,在做集成测试,也就是前后端真正联调时,却会发生很多意想不到的状况.

因此,在涉及到前后端相互调用的功能时,一定要尽早地进行联调测试,不能仅满足于做模拟测试,或用mock数据测试.
同时,也是需要多积累相关的经验,越是感觉简单的功能,其实可能藏着很多的坑,要多思考各种情况,避免在软件交付的最后时刻,发生功能不可用的block级别的bug, 这会严重影响软件的顺利交付.

最后,由于自己的方案无法很好地解决该问题.后来,还是回归到本质问题:就是如何能够让前端生成的报告pdf, 默认保存在指定的位置.通过修改了配置文件的存放路径,让前端能够获取到配置的路径,才解决了这个问题.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172578.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文解读 TOOD: Task-aligned One-stage Object Detection

github: https://github.com/fcjian/TOOD paper: https://arxiv.org/pdf/2108.07755.pdf 关键点 思考起点 指出传统one-stage算法在在优化目标分类和定位问题中的不足(DecoupledHead分离了分类任务和回归任务[yolox表示解耦这是优点,yolo1-5都是使用y…

[oeasy]python0054_三引号_原样显示字符串_triple_quoted

三引号 回忆上次内容 \ 首先是转义字符 可以 和别的字符 构成转义序列 \a是 ␇ (bell),\b 退回一格\t 水平制表符\v、\f LineFeed\\ 输出 \\" 输出 "\ 输出 \xhh 通过 16 进制数值转义\nnn 通过 8 进制数值转义\ 还是 续行字符 放在 行尾可以让 下一行和本行 连成一…

Linux2

4.Linux的文件系统4.1.linux中所有的一切都是文件万事万物皆文件windows是盘符,linux是树windows是\(翘)linux是/4.2.查找文件方式:1. 绝对路径 有/2. 相对路径 4.3.挂载:执行挂载命令:mount 设备文件名 挂…

CentOS 安装 MinIO Server

1) 下载 MinIO 服务 wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod x minio sudo mv minio /usr/local/bin/ 2) 创建systemd服务文件 sudo vim /etc/systemd/system/minio.service [Unit] DescriptionMinIO Documentationhttps:…

C语言文件操作(2) “流”的拓展介绍

tips 1. 打开一个文件 -> 内存里面就会创建一个对应关联的文件信息区 -> 文件信息区其实就是一个FILE类型的结构体 -> 各个结构体成员记录了该文件的种种信息 -> 结构体(文件信息区)由FILE* 结构体指针来维护 -> 有了指针,一切都好说了 2. 使用文…

文献阅读(45)——使用自监督学习对AMD分类

使用自监督学习对AMD分类 文章目录使用自监督学习对AMD分类一、简介二、先验知识三、文章核心内容四、使用方法1. 非参数化实例歧视(中文翻译过来总是奇奇怪怪,其实就是NPID)a 挑战b 解决方案c 转化!2. 数据集3. 数据预处理五、结…

Python之拉盖尔多项式

文章目录拉盖尔多项式简介微分与积分求根和反演采样和拟合拉盖尔多项式简介 拉盖尔多项式是拉盖尔方程的标准解,但其更著名的应用是薛定谔方程在解氢原子的时候,其径向函数最后要乘上一个Ln−l−12l1(2rnaμ)L^{2l1}_{n-l-1}(\frac{2r}{na_\mu})Ln−l−…

TCP/IP应用层常见协议总结

TCP/IP应用层常见协议总结1.HTTP:超文本传输协议2.SMTP:简单邮件传输(发送)协议3.POP3/IMAP:邮件接收的协议4.FTP:文件传输协议5.Telnet:远程登陆协议6.SSH:安全的网络传输协议1.HTTP:超文本传输协议 超文本传输协议 主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。当我…

浏览器的通信能力

用户代理 浏览器可以代替用户完成http请求,代替用户解析响应结果,所以我们称之为:用户代理 user agent 在网络层面,对于前端开发者,必须要知道浏览器拥有的两大核心能力 自动发出请求的能力自动解析响应的能力 自动…

『51单片机』串口通信配置

🚩write in front🚩 🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5&#xff5…

技术分享 | 黑盒测试方法论—因果图

因果图法是一种利用图解法分析输入与输出的各种组合情况,从而设计测试用例的方法,它适合于检查程序输入条件的各种组合情况。 因果图法比较适合输入条件比较多的情况,可以测试所有的输入条件的排列组合。因果图的 “ 因 ” 就是输入条件&…

Flutter滚动悬浮效果

有以下几种效果 1、tabBar透明度随偏移0-1渐变过度 2、app上下滚动触发tabBar同步滚动 3、tabBar切换触发app上下同步滚动 1、计算每个区块的高度 用keyList保存声明的key&#xff0c;用heightList保存每个key对应的组件高度 // key列表 List<GlobalKey> keyList [Gl…

lower_bound与upper_bound的应用

<1>lower_bound (1). . 上述代码返回在升序排序的序列a中第一个大于等于 t 的元素的地址. 示例: (2) 上述代码返回在升序排序的序列a中第一个大于等于 t 的元素的下标. 示例: 例题: P2249 【深基13.例1】查找 P2249 【深基13.例1】查找 - 洛谷 | 计算机科学教育新生…

JavaSE(多态、abstract、接口)

1.多态 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同 的状态。 向上转型 向上转型&#xff1a;实际就是创建一个子类对象&#xff0c;将其当成父类对象来使用。 语法格式&…

(牛客)小杜跑酷

链接&#xff1a;https://ac.nowcoder.com/acm/contest/49244/F?&headNavacm 来源&#xff1a;牛客网 题目描述 小杜又在玩游戏了&#xff01;这回他玩的是跑酷游戏&#xff01; 已知该跑酷地图长为n&#xff0c;有3层&#xff0c;可以理解为一张3n的地图。令人新奇的是&…

Shiro学习看这一篇文章就够了

第一章 Shiro简介 第1节 shiro介绍 1官网地址: http://shiro.apache.org/Apache Shiro 是一个功能强大,易于使用的Java安全框架,他执行认证、授权、加密、会话管理等功能,使用Shiro易于理解的API,使你能够轻松的保护任何应用,如移动端应用,大型web应用以及企业级应用. Shiro可…

当前主流的后端语言,谁能夺得桂冠,果然是后生可畏!

主流后端语言 如今编程语言遍地开花&#xff0c;烟花迷乱&#xff0c;小编整理了最流行的几种编程语言如下&#xff1a; 这几种语言都是经久不衰&#xff0c;占领着后端编程界的半壁江山。TIOBE上的语言排名&#xff1a; C、Java、python&#xff0c;C&#xff0c; C#鏖战榜首…

元宇宙浪潮下,数智人拒绝“标品”

作者 | 曾响铃 文 | 响铃说 在各地文博会、生活节等大型文娱活动上&#xff0c;在博物馆等各类场馆的线上平台&#xff0c;在企业与用户交互的窗口&#xff0c;在政务平台滚动政策宣讲片中&#xff0c;尤其是&#xff0c;在各大卫视的跨年晚会上…… 2022年末、2023年年初&a…

MyBatis Generator ORM层面的代码自动生成器

在日常开发工作中&#xff0c;我们往往需要自己去构建各种数据表所对应的持久化对象&#xff08;POJO&#xff09;、用于操作数据库的接口&#xff08;DAO&#xff09;以及跟 DAO 所绑定的对应 XML。这都是一些重复性的操作&#xff0c;不需要多大技术含量。MyBatis Generator工…

优思学院|Minitab中的子组大小应该怎样填写?

关于SPC中的均值极差控制图&#xff08;X-bar-R Chart&#xff09;&#xff0c;都是质量管理和六西格玛最常用的工具之一&#xff0c;学生经常都会问及SPC和子组的问题。 所谓的子组&#xff08;Subgroup&#xff09;&#xff0c;是指在同一组条件&#xff08;包括人、机、物、…