C# 探秘:PDFiumCore 开启PDF读取魔法之旅
一、引言
在当今数字化时代,PDF 文件就像一个个神秘的宝盒,里面装满了各种信息。无论是项目文档、学术论文还是产品说明书,PDF 格式凭借其良好的兼容性和稳定性,成为了信息传递的重要载体。想象一下,你接到一个紧急任务,需要从大量的 PDF 报告中提取关键数据,手动翻阅查找显然效率低下。这时,要是有一把神奇的 “钥匙”,能让你用代码轻松打开这些 PDF 宝盒,快速获取所需信息,那该多好!
而 PDFiumCore,就是这把神奇的 “钥匙”!它是一个基于 Google PDFium 项目的 C# 封装库,专门为.NET 开发者打造,让我们能够在 C# 应用程序中轻松地读取、操作 PDF 文件。无论是获取文档的基本信息,如页数、页面尺寸,还是提取页面中的文字、图像,PDFiumCore 都能轻松搞定。有了它,你可以像一位经验丰富的探险家,在 PDF 的世界里自由穿梭,挖掘出那些隐藏的宝藏信息。接下来,就让我们一起踏上这场用 C# 和 PDFiumCore 读取 PDF 文件的奇幻之旅吧!
二、PDFiumCore 初相识
2.1 什么是 PDFiumCore
PDFiumCore 是一座连接 C# 与强大 PDF 处理能力的桥梁 ,它基于 Google PDFium 项目精心打造,是一个专门为.NET 开发者量身定制的 C# 封装库。Google PDFium 作为 Chrome 浏览器内置 PDF 阅读器的核心组件,是一款开源的 PDF 渲染引擎,最初由 Foxit Software 提供,后被 Google 采用并不断优化。它具备高效将 PDF 文件绘制成图像的能力,支持多种格式和选项,在 PDF 处理领域享有盛誉。而 PDFiumCore 则巧妙地将 PDFium 的强大功能封装起来,提供了简洁、易用的.NET 接口,让开发者能够在 C# 语言的环境中,轻松调用 PDFium 的各种功能,实现对 PDF 文件的读取、渲染、解析以及其他复杂操作 。
2.2 特性亮点
-
跨平台支持:无论是在 Windows 系统上进行企业级应用开发,还是在 Linux 服务器上构建后台服务,亦或是在 macOS 系统上打造精致的桌面应用,PDFiumCore 都能完美适配,让开发者无需为不同操作系统的兼容性问题而烦恼。这使得基于 PDFiumCore 开发的应用能够拥有更广泛的受众和应用场景,极大地拓展了应用的部署范围。
-
高性能表现:继承了 PDFium 的高性能特性,PDFiumCore 在处理 PDF 文件时速度极快。在面对大量 PDF 文件需要批量处理,或者需要实时渲染 PDF 页面以提供流畅的阅读体验时,PDFiumCore 能够快速响应,高效地完成任务。例如,在开发一个电子文档管理系统时,使用 PDFiumCore 可以快速加载和显示 PDF 文件,提升用户操作的流畅性,减少等待时间,提高工作效率。
-
功能丰富全面:从最基本的 PDF 文件渲染,到复杂的表单填充、注释添加以及文本提取,PDFiumCore 都提供了完善的支持。比如在开发一个合同管理系统时,不仅可以利用 PDFiumCore 读取合同文档的内容,还能实现对合同中表单字段的自动填充,以及添加电子签名等注释信息,满足各种实际业务需求。
-
易于集成使用:作为一个.NET 库,PDFiumCore 可以非常方便地集成到现有的.NET 项目中。通过熟悉的 C# 语法和开发工具,开发者可以轻松地将 PDF 处理功能融入到自己的应用程序中。以一个ASP.NET Web 应用为例,只需简单地添加 PDFiumCore 的引用,就能在控制器或页面代码中调用相关功能,实现对 PDF 文件的在线预览、下载等操作,大大降低了开发成本和难度。
三、搭建魔法舞台(准备工作)
3.1 开发环境准备
首先,我们需要一个强大的开发工具来开启这场魔法之旅,Visual Studio 就是我们的得力助手。它是一款由微软开发的集成开发环境(IDE),功能强大,广泛应用于各种.NET 应用程序的开发。你可以从Visual Studio 官方网站下载并安装最新版本。在安装过程中,记得选择与.NET 开发相关的工作负载,确保安装程序包含了我们后续开发所需的基本组件。
同时,为了确保我们的代码能够在.NET 环境中顺利运行,还需要安装.NET SDK(软件开发工具包)。.NET SDK 提供了编译、运行.NET 应用程序所需的工具和库。你可以从.NET 官方下载页面获取适合你操作系统的.NET SDK 版本进行安装。安装完成后,通过在命令行中输入dotnet --version来验证是否安装成功,如果输出版本号,那就说明一切准备就绪啦!
3.2 安装 PDFiumCore
有了开发环境这个坚实的舞台,接下来就要请出我们的主角 PDFiumCore 了。在 Visual Studio 中,通过 NuGet 包管理器安装 PDFiumCore 是非常简单的。具体步骤如下:
-
打开 Visual Studio,加载你的项目。如果是新建项目,在创建项目时选择合适的.NET 项目模板,比如控制台应用程序、Windows Forms 应用程序或者ASP.NET Web 应用程序等,这里我们以控制台应用程序为例。
-
在解决方案资源管理器中,右键点击你的项目,选择 “管理 NuGet 包”。这就像是打开了一个神奇的软件宝库,里面有各种各样的库供我们选择使用。
-
在打开的 “NuGet 包管理器” 窗口中,选择 “浏览” 选项卡。在左上角的搜索框中输入 “PdfiumCore”,然后按下回车键,你会看到 PdfiumCore 包出现在搜索结果中。
-
点击 PdfiumCore 包,在右侧的详细信息窗格中可以选择要安装的版本。一般情况下,我们选择最新的稳定版本即可。如果想要包括预发行版版本,可以勾选 “包括预发行版” 选项。
-
最后,点击 “安装” 按钮,Visual Studio 会自动下载并安装 PdfiumCore 及其依赖项。安装过程中,可能会弹出一些提示框,如接受许可条款等,按照提示操作即可。安装完成后,你可以在 “已安装” 选项卡中看到 PdfiumCore 包,并且在项目的解决方案资源管理器中的 “依赖项 > 包” 节点下也能找到它。
3.3 导入命名空间
安装好 PDFiumCore 后,就像我们把一件强大的魔法道具放进了工具箱,但还需要正确地引用它,才能发挥出它的魔力。在 C# 代码中,我们通过导入命名空间来实现这一点。在你的代码文件开头,添加以下代码:
using PdfiumCore;
这行代码就像是一把钥匙,打开了通往 PDFiumCore 功能世界的大门。它告诉编译器,我们在这个文件中要使用 PdfiumCore 命名空间下的类型和功能。如果不导入这个命名空间,当我们在代码中使用 PDFiumCore 相关的类和方法时,编译器就会报错,就像在黑暗中摸索,找不到正确的方向。所以,千万不要忘记这关键的一步哦!
四、魔法咒语(核心代码实现)
4.1 加载 PDF 文件
在 C# 中使用 PDFiumCore 加载 PDF 文件非常简单,只需要几行代码就能打开 PDF 这个神秘的 “宝盒”。下面是具体的代码示例:
string filePath = "path_to_your_pdf_file.pdf";// 需要替换为实际的PDF文件路径,就像你要找到宝藏必须先知道它藏在哪里一样
using (PdfDocument pdfDoc = new PdfDocument(filePath))
{// 这里开始对pdfDoc进行各种操作,比如获取页面信息等
}
在这段代码中,我们首先定义了一个字符串变量filePath,它存储了要读取的 PDF 文件的路径。这里的路径可以是绝对路径,例如C:\Users\YourUsername\Documents\example.pdf,也可以是相对路径,相对路径是相对于当前项目的目录结构而言的。如果 PDF 文件与当前代码文件在同一目录下,那么直接写文件名即可。
然后,我们使用using语句创建了一个PdfDocument对象pdfDoc,并将其初始化为指定路径的 PDF 文件。using语句的作用非常重要,它会在代码块结束时自动调用Dispose方法,释放PdfDocument对象占用的非托管资源 ,就像你用完一个工具后,把它放回原位,清理好现场一样,避免资源浪费和内存泄漏。PdfDocument类是 PDFiumCore 库中的核心类之一,它代表了一个 PDF 文档,通过这个类,我们可以对 PDF 文件进行各种操作,如获取页面数量、加载特定页面、提取页面内容等。
4.2 获取页面信息
成功加载 PDF 文件后,我们可以像探索宝藏地图一样,获取 PDF 文件的各种页面信息。例如,获取 PDF 的总页数以及特定页面的宽度和高度,代码如下:
string filePath = "path_to_your_pdf_file.pdf";
using (PdfDocument pdfDoc = new PdfDocument(filePath))
{// 获取总页数int pageCount = pdfDoc.GetPageCount();Console.WriteLine($"这个PDF总共有{pageCount}页");// 获取第一页的宽高信息(第0页是第一页)PdfPage page = pdfDoc.LoadPage(0);int width = (int)page.GetWidth();int height = (int)page.GetHeight();Console.WriteLine($"第一页的宽度为{width},高度为{height}");
}
在上述代码中,通过pdfDoc.GetPageCount()方法,我们轻松地获取了 PDF 文件的总页数,并将其存储在pageCount变量中,然后使用Console.WriteLine方法将总页数输出到控制台,就像你数清楚了宝藏地图一共有多少张一样。
接着,我们使用pdfDoc.LoadPage(0)方法加载了 PDF 文件的第一页(在编程中,索引通常从 0 开始,所以第 0 页就是第一页),并将返回的PdfPage对象赋值给page变量。PdfPage类代表了 PDF 文档中的一页,通过它可以获取该页面的各种属性和进行相关操作 。之后,通过page.GetWidth()和page.GetHeight()方法分别获取了第一页的宽度和高度,并将其转换为整数类型后输出到控制台,这样我们就对第一页的大小有了清晰的了解。
4.3 读取页面内容(可选,文本提取等)
有时候,我们不仅想知道 PDF 页面的基本信息,还想深入挖掘页面中的具体内容,比如提取文本。虽然 PDF 文件的结构比较复杂,文本的提取可能会受到字体、布局等多种因素的影响,但 PDFiumCore 为我们提供了相对便捷的方式来实现这一功能。下面是一个简单的文本提取示例代码:
string filePath = "path_to_your_pdf_file.pdf";
using (PdfDocument pdfDoc = new PdfDocument(filePath))
{PdfPage page = pdfDoc.LoadPage(0);using (PdfTextReader reader = new PdfTextReader(page)){string text = reader.ReadText();Console.WriteLine($"第一页的文本内容是:{text}");}
}
在这段代码中,首先加载了 PDF 文件的第一页。然后,创建了一个PdfTextReader对象reader,并将其初始化为当前页面page。PdfTextReader类专门用于从 PDF 页面中读取文本内容。通过调用reader.ReadText()方法,就可以将第一页的文本内容读取出来,并存储在text变量中,最后输出到控制台。不过需要注意的是,对于一些包含复杂格式、图像或特殊字体的 PDF 文件,提取的文本可能需要进一步处理和整理,以确保准确性和可读性。
4.4 提取页面图像
如果我们想要将 PDF 页面转换为图像,以便更直观地展示或进行其他处理,PDFiumCore 同样可以满足我们的需求。下面是将 PDF 页面渲染为图像并保存为 PNG 格式的完整代码:
using System.Drawing;
using System.IO;
using PdfiumCore;string filePath = "path_to_your_pdf_file.pdf";
using (PdfDocument pdfDoc = new PdfDocument(filePath))
{PdfPage page = pdfDoc.LoadPage(0);int width = (int)page.GetWidth();int height = (int)page.GetHeight();using (MemoryStream ms = new MemoryStream()){var bitmap = page.Render(width, height, RotateDegreesClockwise.None, PdfRenderFlags.Printing);bitmap.Save(ms, ImageFormat.Png);byte[] imageBytes = ms.ToArray();// 将图像数据保存到文件,这里保存为page1.pngusing (FileStream fs = new FileStream("page1.png", FileMode.Create)){fs.Write(imageBytes, 0, imageBytes.Length);}}
}
在这段代码中,首先加载了 PDF 文件的第一页,并获取了该页面的宽度和高度。然后,创建了一个MemoryStream对象ms,用于存储图像数据。通过page.Render方法将 PDF 页面渲染为一个Bitmap对象bitmap,Render方法的参数指定了渲染的宽度、高度、旋转角度以及渲染标志。这里设置旋转角度为无旋转,渲染标志为打印模式,以确保图像的质量和准确性 。接着,将渲染后的bitmap对象保存到MemoryStream中,通过ToArray方法将MemoryStream中的数据转换为字节数组imageBytes。最后,使用FileStream将字节数组中的图像数据写入到文件系统中,保存为名为page1.png的 PNG 图像文件。
4.5 清理资源
在完成对 PDF 文件的各种操作后,一定要记得清理资源,就像探险结束后收拾好自己的装备一样。这不仅是良好的编程习惯,也是确保程序稳定运行、避免资源泄漏的关键步骤。在使用 PDFiumCore 时,主要是关闭PdfDocument对象,释放其占用的资源,代码如下:
string filePath = "path_to_your_pdf_file.pdf";
PdfDocument pdfDoc = new PdfDocument(filePath);
// 进行各种操作
//...
// 操作完成后关闭文档
pdfDoc.Close();
在上述代码中,当对pdfDoc进行完所有需要的操作后,调用pdfDoc.Close()方法关闭 PDF 文档。这个方法会释放PdfDocument对象占用的非托管资源,如文件句柄、内存等,确保系统资源得到合理回收,避免因资源未释放而导致的程序性能下降或其他潜在问题。如果不关闭PdfDocument对象,可能会导致在后续操作中无法再次访问该文件,或者占用过多内存,影响系统的整体性能。所以,千万不要忘记这重要的一步哦!
五、魔法进阶(常见问题与优化)
5.1 常见问题及解决
在使用 PDFiumCore 读取 PDF 文件的过程中,可能会遇到一些问题,下面为大家列举一些常见问题及解决方法:
-
文件路径错误:这是最容易出现的问题之一。如果指定的 PDF 文件路径不正确,程序将无法找到并加载文件,从而抛出异常。例如,在 Windows 系统中,路径分隔符应该使用反斜杠(\),但由于反斜杠在 C# 字符串中是转义字符,所以需要使用双反斜杠(\)或者使用逐字字符串(以@开头)。如string filePath = @“C:\Users\YourUsername\Documents\example.pdf”; 。如果使用相对路径,要确保路径是相对于当前项目的正确位置。解决方法是仔细检查文件路径是否正确,包括文件名的拼写、文件所在目录以及路径分隔符的使用。可以通过在文件资源管理器中手动定位文件,然后复制正确的路径来避免此类错误。
-
格式不兼容:虽然 PDFiumCore 支持大多数标准的 PDF 文件格式,但仍有可能遇到一些特殊格式或损坏的 PDF 文件无法正常加载的情况。对于特殊格式的 PDF 文件,可能需要检查 PDFiumCore 的版本是否支持,或者尝试使用其他工具将其转换为更常见的标准格式后再进行读取。如果是损坏的 PDF 文件,可以尝试使用一些 PDF 修复工具,如福昕 PDF 编辑器等,对文件进行修复后再使用 PDFiumCore 读取。
-
内存不足:当处理大型 PDF 文件或同时加载多个 PDF 文件时,可能会导致内存不足的问题,使程序运行缓慢甚至崩溃。为了避免这种情况,可以尽量减少不必要的内存占用,例如在读取完 PDF 文件或页面后,及时释放相关资源,使用using语句来确保对象在使用完毕后正确释放。同时,可以考虑分块读取 PDF 文件,而不是一次性加载整个文件到内存中。比如在读取大型 PDF 文件的文本内容时,可以逐页读取并处理,而不是一次性读取所有页面的文本。
-
依赖项缺失:PDFiumCore 可能依赖于一些其他的库或组件,如果这些依赖项缺失或版本不兼容,也会导致程序出错。在安装 PDFiumCore 时,要确保通过 NuGet 包管理器正确安装了所有依赖项。如果出现依赖项问题,可以查看 NuGet 包的文档或相关论坛,了解如何解决依赖冲突或安装缺失的依赖项。例如,某些版本的 PDFiumCore 可能依赖于特定版本的.NET 运行时,需要确保项目所使用的.NET 版本与 PDFiumCore 的要求一致。
5.2 性能优化建议
为了让程序在使用 PDFiumCore 读取 PDF 文件时更加高效,以下是一些性能优化建议:
-
内存管理优化:在代码中,合理使用using语句来管理PdfDocument、PdfPage、PdfTextReader等对象的生命周期,确保它们在使用完毕后及时释放资源,避免内存泄漏。例如,在读取完 PDF 文件的所有页面信息后,及时关闭PdfDocument对象。对于不再使用的中间变量,如临时存储页面内容的字符串或图像数据,也应及时释放内存。可以将不再使用的对象设置为null,以便垃圾回收器能够及时回收这些对象占用的内存。
-
渲染参数优化:在渲染 PDF 页面时,根据实际需求调整渲染参数。例如,如果只是需要快速预览页面内容,可以适当降低渲染的分辨率,减少渲染的像素数量,从而提高渲染速度。可以通过修改page.Render方法的参数来实现,如var bitmap = page.Render(width / 2, height / 2, RotateDegreesClockwise.None, PdfRenderFlags.Printing); ,这里将渲染的宽度和高度都减半。另外,根据具体情况选择合适的渲染标志,如PdfRenderFlags.Printing适合打印场景,渲染质量较高但速度可能稍慢;PdfRenderFlags.Screen适合屏幕显示,渲染速度较快但质量相对较低 。
-
缓存机制:对于频繁访问的 PDF 页面或内容,可以考虑实现缓存机制。例如,使用一个字典(Dictionary)来存储已经加载或渲染的页面信息,当再次需要访问同一页面时,先从缓存中查找,避免重复加载和渲染,从而提高程序的响应速度。如下代码示例:
private Dictionary<int, PdfPage> pageCache = new Dictionary<int, PdfPage>();
public PdfPage GetPageFromCache(PdfDocument pdfDoc, int pageIndex)
{if (pageCache.TryGetValue(pageIndex, out PdfPage page)){return page;}page = pdfDoc.LoadPage(pageIndex);pageCache.Add(pageIndex, page);return page;
}
- 异步处理:如果在 UI 应用程序中读取 PDF 文件,为了避免阻塞主线程,导致界面卡顿,可以将 PDF 文件的读取和处理操作放在后台线程中进行。在 C# 中,可以使用Task类来实现异步操作。例如,使用Task.Run(() => { /* 读取PDF文件的代码 */ });将读取 PDF 文件的代码封装在一个Task中,使其在后台线程中执行,这样主线程可以继续处理 UI 相关的操作,保证界面的流畅性。
六、总结与展望
在这场用 C# 和 PDFiumCore 读取 PDF 文件的奇幻之旅中,我们首先认识了 PDFiumCore 这个强大的工具,了解了它基于 Google PDFium 项目,为我们在.NET 应用程序中处理 PDF 文件打开了方便之门。通过准备开发环境、安装 PDFiumCore 以及导入命名空间这些前期准备工作,我们搭建好了探索 PDF 世界的舞台。
在核心代码实现部分,我们学会了使用几行简洁的代码加载 PDF 文件,获取其页面信息,包括总页数、特定页面的宽高,还能进一步读取页面内容,甚至将页面提取为图像。这些操作就像掌握了一系列神奇的魔法咒语,让我们能够自由地探索 PDF 文件中的各种信息。同时,我们也没有忘记在操作完成后清理资源,这是确保程序稳定运行和资源合理利用的关键步骤。
在魔法进阶阶段,我们探讨了在使用 PDFiumCore 过程中可能遇到的常见问题及解决方法,如文件路径错误、格式不兼容、内存不足和依赖项缺失等,并且给出了相应的解决方案。还分享了性能优化建议,从内存管理、渲染参数优化、缓存机制到异步处理等方面,帮助大家让程序运行得更加高效。
展望未来,随着数字化信息的不断增长,PDF 文件的应用场景也将越来越广泛。PDFiumCore 在 PDF 处理方面有着巨大的潜力,我们可以进一步拓展其应用。例如,在文档管理系统中,实现更复杂的 PDF 文件搜索和分类功能;在电子发票处理中,自动提取发票中的关键信息,实现自动化的财务流程;在教育领域,开发基于 PDF 的互动学习材料,通过读取 PDF 内容并结合其他技术,为学生提供更丰富的学习体验。相信在不断的探索和实践中,PDFiumCore 将在更多的领域发挥重要作用,帮助我们更高效地处理和利用 PDF 文件中的信息 。
相关文章:
C# 探秘:PDFiumCore 开启PDF读取魔法之旅
一、引言 在当今数字化时代,PDF 文件就像一个个神秘的宝盒,里面装满了各种信息。无论是项目文档、学术论文还是产品说明书,PDF 格式凭借其良好的兼容性和稳定性,成为了信息传递的重要载体。想象一下,你接到一个紧急任…...
计算机网络-运输层
重点内容: 运输层 是整个网络体系结构中的关键层次之一。一定要弄清以下一些重要概念: (1) 运输层为相互通信的应用进程提供逻辑通信。 (2) 端口和套接字的意义。 (3) 无连接的 UDP 的特点。 (4) 面向连接的 TCP 的特点。 (5) 在不可靠的网…...
TLF35584 基本介绍
1 概述 1)多电压电源芯片,包含6路输出电压。 LDO_Com:低降后调节器 5V/200mA 通信电源。LDO_C :低降后调节器 5V/600mA (TLF35584xxVS1)/3.3 V/600mA (TLF35584xxVS2) uC电源。Volt_Ref :参考电压5.0 V /- 1%/150mA …...
【Python】第四弹---深入理解Python控制流:从顺序到循环的全面解析
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、顺序语句 2、条件语句 2.1、什么是条件语句 2.2、语法格式 2.3、缩进和代码块 2.4、练习 2.5、空…...
PBFT算法
在我的博客中对于RAFT算法也有详细的介绍,raft算法包含三种角色,分别是:跟随者( follower ),候选人(candidate )和领导者( leader )。集群中的一个节点在某一…...
软件过程模型
软件过程概念 软件生命周期 软件过程 在工作产品构建过程中,所需完成的工作活动,动作和任务的集合。 软件过程模型 软件过程评估 能力成熟度模型(CMM) 传统软件过程模型 瀑布模型(第一个软件过程模型ÿ…...
【Ubuntu】安装SSH启用远程连接
【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端: sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端: sudo systemctl start ssh贰、配置SSH(可跳过) 配置文件 …...
代码随想录算法【Day31】
Day31 56. 合并区间 class Solution { public://按照左边界,从小到大排序static bool cmp(const vector<int>& a, const vector<int>& b){return a[0] < b[0];} vector<vector<int>> merge(vector<vector<int>>…...
Apache Tomcat文件包含漏洞复现(详细教程)
1.漏洞原理 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,其安装后会默认开启ajp连接器,方便与其他web服务器通过ajp协议进行交互。属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发…...
C#高级:常用的扩展方法大全
1.String public static class StringExtensions {/// <summary>/// 字符串转List(中逗 英逗分隔)/// </summary>public static List<string> SplitCommaToList(this string data){if (string.IsNullOrEmpty(data)){return new List&…...
麒麟操作系统基础知识保姆级教程(二十一)进入单用户模式
如果你想拥有你从未拥有过的东西,那么你必须去做你从未做过的事情 在咱们运维工作中,服务器的密码长度,密码复杂度,修改时间,超时时间,用户权限管理,root直接远程连接,普通用户su到r…...
基于C语言的数组从入门到精通
简介:本篇文章主要介绍了一维数组,二维数组,字符数组的定义,数组的应用,数组的核心代码解析,适用于0基础的初学者. C语言数组 1.一维数组 1.1定义 1.1.1声明 语法:数据类型 数组名[数组大小];示例:int arr[5]; 1.1.2初始化 a.静态初始化 完全初始化:int arr[5] {1…...
CLOUDFLARE代理请求重定向你太多次
现象 使用CLOUDFLARE代理前请求正常,使用CLOUDFLARE代理请求后出现 原因分析 以下是我的猜测,在默认情况下 CLOUDFLARE代理,可能是直接请求我们服务器的IP,比如:http://1.1.1.1 而不是通过域名的方式(如…...
算法随笔_21:字符的最短距离
上一篇:算法随笔_20:区间子数组个数 -CSDN博客 题目描述如下: 给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符。 返回一个整数数组 answer ,其中 answer.length s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。 …...
第19个项目:蛇年特别版贪吃蛇H5小游戏
下载地址:https://download.csdn.net/download/mosquito_lover1/90308956 游戏玩法: 点击"开始游戏"按钮开始 使用键盘方向键控制蛇的移动 吃到红色食物可以得分 撞到墙壁或自己会结束游戏 核心源码: class SnakeGame { constructor() { this.canvas = docum…...
Vue3 30天精进之旅:Day01 - 初识Vue.js的奇妙世界
引言 在前端开发领域,Vue.js是一款极具人气的JavaScript框架。它以其简单易用、灵活高效的特性,吸引了大量开发者。本文是“Vue 3之30天系列学习”的第一篇博客,旨在帮助大家快速了解Vue.js的基本概念和核心特性,为后续的深入学习…...
单值二叉树(C语言详解版)
一、摘要 今天要讲的是leetcode单值二叉树,这里用到的C语言,主要提供的是思路,大家看了我的思路之后可以点击链接自己试一下。 二、题目简介 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单…...
贵州端午黔粽探源:贵州味道与黔味文化与糯米的融合?
黔粽的由来? 黔粽的贵州味道?探索贵州“黔味文化”找寻答案! 黔粽的特色由来与贵州味道 贵州粽,简称黔粽。黔粽的主要特色是“酸辣”,以其独特的“酸辣”口味和地域特色,与浙粽、京粽、粤粽、川粽、云粽、闽粽、台湾粽并列为“全国八大粽子派别”之一,并与甜味粽、咸味粽共…...
【Project】CupFox电影网站数据爬取分析与可视化
数据采集清洗与数据存储流程如下图所示。 数据分析与数据可视化流程设计如下 1.使用pymongo从数据库中查询所需的数据。对数据进行处理和分析,进行统计、分类、聚合等操作,提取关键指标和洞察。分析结果可以通过编写Python代码进一步优化、筛选和整理&a…...
Spring Boot 后端跨域解决方案:解锁前后端通信的障碍
随着前后端分离架构的普及,跨域资源共享(Cross-Origin Resource Sharing, CORS)问题成为了许多开发者必须面对的一个挑战。当Web浏览器尝试从一个源加载资源到另一个不同的源时,出于安全考虑,它会实施同源策略…...
Linux如何设置用户登录超时(/etc/profile)
Linux如何设置用户登录超时(/etc/profile) 1. 针对所有用户 # vi /etc/profile ... export TMOUT900 # 设置闲置时间为15分钟,单位为秒;如果没有此行则直接添加进去 ... vi /etc/profile TMOUT18000000000000 export QT_IM_MODULEfcitx readonly TMOUT expor…...
Elastic Cloud Serverless 获得主要合规认证
作者:来自 Elastic Oliver Mao 我们很高兴地宣布,Elastic Cloud Serverless 已获得多项重要的合规性认证。这一里程碑加强了我们对安全性、隐私性和法规遵从性的承诺。Elastic Cloud Serverless 现已通过以下行业领先框架的审核或认证:SOC 2 …...
渐变颜色怎么调?
渐变颜色的调整是设计中非常重要的一部分,尤其是在创建具有视觉吸引力和深度感的设计作品时。以下是一些在不同设计软件中调整渐变颜色的详细步骤和技巧: 一、Adobe Photoshop 1. 创建渐变 打开渐变工具: 选择工具栏中的“渐变工具”&#x…...
DDD该怎么去落地实现(1)关键是“关系”
DDD落地的关键是“关系” 这些年,我认为DDD走到了一个死胡同里了,因为落地实现过于困难。很多团队在经过一段时间的学习,清楚理解了DDD那些晦涩的概念,根据业务绘制出领域模型,这都不困难。但绘制领域模型不是我们最终…...
基于本地事务表+MQ实现分布式事务
基于本地事务表MQ实现分布式事务 引言1、原理2、本地消息表优缺点3、本地启动rocketmq4、代码实现及验证4.1、核心代码4.2、代码执行流程4.3、项目结构4.4、项目源码 引言 本地消息表的方案最初由ebay的工程师提出,核心思想是将分布式事务拆分成本地事务进行处理。…...
第17篇:python进阶:详解数据分析与处理
第17篇:数据分析与处理 内容简介 本篇文章将深入探讨数据分析与处理在Python中的应用。您将学习如何使用pandas库进行数据清洗与分析,掌握matplotlib和seaborn库进行数据可视化,以及处理大型数据集的技巧。通过丰富的代码示例和实战案例&am…...
S4 HANA Tax相关的定价过程
本文主要介绍在S4 HANA OP中Tax相关的定价过程相关设置。具体请参照如下内容: 目录 1. 定义定价过程(OBYZ) 2. 将定价过程分配给国家(OBBG)编辑编辑 3. 新增Transaction Key(OBCN) 1. 定义定价过程(OBYZ) 定价过程就是为了将“条件类型”和“事务”关联起来…...
Linux下php8安装phpredis扩展的方法
Linux下php8安装phpredis扩展的方法 下载redis扩展执行安装编辑php.ini文件重启php-fpmphpinfo 查看 下载redis扩展 前提是已经安装好redis服务了 php-redis下载地址 https://github.com/phpredis/phpredis 执行命令 git clone https://github.com/phpredis/phpredis.git执行…...
K8S 启动探测、就绪探测、存活探测
先来思考一个问题: 在 Deployment 执行滚动更新 web 应用的时候,总会出现一段时间,Pod 对外提供网络访问,但是页面访问却发生404,这个问题要如何解决呢?学完今天的内容,相信你会有自己的答案。 …...
rust学习-rust中的保留字
rust学习-rust中的保留字 已使用的保留字未来可能使用的保留字 保留字是语言中预定义的标识符,不能用作变量名、函数名或其他自定义标识符,Rust的保留字大致可以分为两类:已使用的保留字和未来可能使用的保留字 已使用的保留字 as࿱…...
-bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录
终端报错: -bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录原因:由于文件行尾符不匹配导致的。当脚本文件在Windows环境中创建或编辑后,行尾符为CRLF(即回车和换行,\r\n)…...
【C】memory 详解
<memory.h> 是一个 C 标准库头文件,提供了一组内存管理函数,用于分配、释放和操作动态内存。这些函数主要操作的是未初始化的内存块,是早期 C 编程中常用的内存操作工具。 尽管在现代 C 编程中更推荐使用<cstring>或<memory&…...
Android实训九 数据存储和访问
实训9 数据存储和访问 一、【实训目的】 1、 SharedPreferences存储数据; 2、 借助Java的I/O体系实现文件的存储, 3、使用Android内置的轻量级数据库SQLite存储数据; 二、【实训内容】 1、实现下图所示的界面,实现以下功能: 1ÿ…...
Redis vs. 其他数据库:深度解析,如何选择最适合的数据库?
一、如何为项目选择合适的数据库? 选择合适的数据库是一个复杂的过程,需要综合考虑多个因素。下面几个维度来详细阐述: 1.数据模型 关系型数据库(RDBMS):适用于高度结构化、关联性强的数据,如电…...
docker 安装 mysql 详解
在平常的开发工作中,我们经常需要用到 mysql 数据库。那么在docker容器中,应该怎么安装mysql数据库呢。简单来说,第一步:拉取镜像;第二步:创建挂载目录并设置 my.conf;第三步:启动容…...
C++实现设计模式---桥接模式 (Bridge)
桥接模式 (Bridge) 桥接模式 是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立变化。桥接模式的核心思想是使用组合(而非继承)来扩展功能。 意图 将抽象部分与实现部分分离,使它们都可以独立地变…...
LangChain + llamaFactory + Qwen2-7b-VL 构建本地RAG问答系统
单纯仅靠LLM会产生误导性的 “幻觉”,训练数据会过时,处理特定知识时效率不高,缺乏专业领域的深度洞察,同时在推理能力上也有所欠缺。 正是在这样的背景下,检索增强生成技术(Retrieval-Augmented Generati…...
pycharm 运行远程环境问题 Error:Failed to prepare environment.
问题排查 拿到更详细的报错信息: Help > Diagnostic Tools > Debug Log Settings section: 添加下面的配置 com.intellij.execution.configurations.GeneralCommandLine 重显报错,我这里是再次运行代码打开 Help | Collect Logs and Diagnosti…...
Level2逐笔成交逐笔委托毫秒记录:今日分享优质股票数据20250124
逐笔成交逐笔委托下载 链接: https://pan.baidu.com/s/1UWVY11Q1IOfME9itDN5aZA?pwdhgeg 提取码: hgeg Level2逐笔成交逐笔委托数据分享下载 通过Level2逐笔成交与逐笔委托的详细数据,这种以毫秒为单位的信息能揭示许多关键点,如庄家意图、误导性行为…...
最新最详细的配置Node.js环境教程
配置Node.js环境 一、前言 (一)为什么要配置Node.js?(二)NPM生态是什么(三)Node和NPM的区别 二、如何配置Node.js环境 第一步、安装环境第二步、安装步骤第三步、验证安装第四步、修改全局模块…...
【Address Overfitting】解决过拟合的三种方法
目录 1. 收集更多数据实践方法:适用场景:优缺点: 2. 特征选择方法介绍:实践示例:适用场景:优缺点: 3. 正则化(Regularization)正则化类型:实践示例࿱…...
【缘于J2ME】
我与 J2ME 的不解之缘 那年我 25 岁,如今已即将退休。 在那个娱乐生活并不丰富的年代,每每响起「小霸王其乐无穷啊」,小伙伴们就会摩拳擦掌、轮番上阵,而我却痴迷于 G-BASIC 编程。 最大的乐趣就是对着仅有的两页说明,…...
c#使用log4Net配置日志文件
1.# 写一个通用类 LogHelper using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using log4net;namespace WindowsFormsApplication22 {public class LogHelper{static ILog mylog LogManager.GetLogge…...
[ACTF2020 新生赛]Include1
题目 点击tips后: 使用PHP伪协议直接读取flag /?filephp://filter/readconvert.base64-encode/resourceflag.php base64解码 拿下flag flag{6cce5a3d-997a-4c8a-ba07-f6652ee462a9}...
【数据结构】树的基本:结点、度、高度与计算
树是数据结构中一种重要的非线性结构,广泛应用于计算机科学的各个领域,例如文件系统、数据库索引、编译器等。理解树的各种性质,如结点数、度、高度等,对于解决实际问题至关重要。 本文将会探讨树的基本概念,以及给出几…...
1.24 共享内存和信号灯集
使用共享内存信号灯集实现两个进程之间相互对话。 程序代码: #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stst.h> #include <fcntl.h> #…...
正则表达式以及Qt中的使用
目录 一、正则表达式 1、基本匹配: 2、元字符: 2.1 .运算符: 2.2 字符集: 2.3 重复次数: 2.4 量词{} 2.5 特征标群() 2.6 或运算符 2.7 \反斜线转码特殊字符 2.8 锚点 3、简写字符 4、零宽度断言 4.1 正…...
STM32简介
STM32简介 STM32是ST公司基于ARMCortex-M内核开发的32位微控制器 (Microcontroller) MCU微控制器、MPU微处理器、CPU中央处理器 1.应用领域 STM32常应用于嵌入式领域。 如智能车:循迹小车 读取光电传感器或者摄像头的数据,…...
【设计模式-行为型】访问者模式
一、什么是访问者模式 说起来访问者模式,其实很少用。我一直在思考该用什么样的例子把这个设计模式表述清晰,最近突然想到一个例子也许他就是访问者。港片有过很辉煌的年代,小的时候一直在看港片觉得拍的非常好,而且演员的演技也在…...
上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天冲高回落,深成指、创业板指午后翻绿。大金融板块全天强势,天茂集团…...