三种读写传统xls格式文件开源库libxls、xlslib、BasicExcel的比较

最近准备读写传统xls格式文件,而不是较新的xlsx,询问DeepSeek有哪些开源库,他给出了如下的简介和建议,还给出了相应链接,不过有的链接已失效。最后还不忘提醒,现在该用xlsx格式了。

以下是几个可以处理传统 .xls (Excel 97-2003) 格式的 C++ 库推荐:


1. libxls (推荐)

  • 特点
    • 纯C库,但可轻松用于C++项目
    • 轻量级,只读操作
    • 专门解析二进制.xls格式
  • 安装:
    # Ubuntu
    sudo apt-get install libxls-dev
    
  • 示例代码:
    #include <xls.h>void read_xls(const char* filename) {xlsWorkBook* pWB = xls_open(filename, "UTF-8");xlsWorkSheet* pWS = xls_getWorkSheet(pWB, 0);xls_parseWorkSheet(pWS);for (int row=0; row<pWS->rows.lastrow; row++) {for (int col=0; col<pWS->rows.lastcol; col++) {std::cout << pWS->rows.sheet[row].cells[col].str << "\t";}std::cout << std::endl;}xls_close_WS(pWS);xls_close_WB(pWB);
    }
    

2. BasicExcel

  • 特点
    • 纯头文件库
    • 支持读写操作
    • 仅支持基本功能(无图表、公式等)
  • GitHub: https://github.com/stephenquan/BasicExcel错误链接
  • 示例代码:
    #include "BasicExcel.hpp"void read_xls(const char* filename) {YExcel::BasicExcel excel;excel.Load(filename);YExcel::BasicExcelWorksheet* sheet = excel.GetWorksheet(0);for (size_t row=0; row<sheet->GetTotalRows(); row++) {for (size_t col=0; col<sheet->GetTotalCols(); col++) {YExcel::BasicExcelCell* cell = sheet->Cell(row, col);std::cout << cell->GetString() << "\t";}std::cout << std::endl;}
    }
    

3. xlslib (已停止维护)

  • 特点
    • 支持读写
    • 跨平台
  • 官网: http://xlslib.sourceforge.net
  • 示例:
    #include "xlslib.h"
    using namespace xlslib_core;void read_xls(const char* filename) {workbook wb;wb.Load(filename);worksheet* ws = wb.GetSheet(0);for (unsigned row=0; row<ws->LastRow(); row++) {for (unsigned col=0; col<ws->LastCol(); col++) {cell_t* cell = ws->FindCell(row, col);std::cout << cell->GetString() << "\t";}std::cout << std::endl;}
    }
    

4. Qt XLS (QXlsx)

  • 特点
    • 需要Qt框架
    • 支持读写
  • GitHub: https://github.com/QtExcel/QXlsx
  • 示例:
    #include <QXlsx/Workbook.h>void read_xls(const QString& filename) {QXlsx::Document xls(filename);for (int row=1; row<=xls.dimension().lastRow(); row++) {for (int col=1; col<=xls.dimension().lastColumn(); col++) {std::cout << xls.cellAt(row, col)->value().toString().toStdString() << "\t";}std::cout << std::endl;}
    }
    

选择建议:

  1. 只需读取 → 选libxls(最稳定)
  2. 需要简单读写 → 选BasicExcel
  3. 已使用Qt → 选QXlsx
  4. 需要完整功能 → 考虑用libreofficepoi的C++封装

注意:现代项目建议优先使用.xlsx格式(可用libxlsxwriterOpenXLSX库)。


以下是实际测试

版本

对我的小功能而言,Qt太重了,而且项目网页说“QXlsx is excel file(*.xlsx) reader/writer library”,也就是它其实不支持xls格式文件。所以下面比较前三种。

经过一番搜索,libxls原主页https://sourceforge.net/projects/libxls/,迁移到https://github.com/libxls/libxls了。最新的版本是libxls-1.6.3.tar.gz。

xlslib主页https://sourceforge.net/projects/xlslib/,还在,能正常下载。最新的版本是xlslib-package-2.5.0.zip。

BasicExcel我没找到软件网页,只找到作者Yap Chun Wei在2006年发表的一篇文章,但源代码链接已失效,于是又一通搜索,找到了存有该代码的的个人github项目,https://github.com/haorenhl007/BasicExcel,源码包。版本号是Version 1.14 (6 August 2006)。

libxls虽然也有apt安装和pkgs.org上可下载的软件包,但考虑公平比较,也顺便编译一遍源代码。

编译

libxls编译很简单,gnu软件的常规做法,解压、configure、make、make install即可。如果aarch64平台遇到编译器的问题,在安卓手机的termux+prooot环境中也能编译成功,然后这个so文件可拷贝到其他linux系统使用。
xlslib编译在x64平台相对顺利,参照libxls步骤即可。在aarch64平台编译会遇到问题,解决方法见前文。
BasicExcel无需单独编译,当然为了减少编译时间,也可以将它编译成动态链接库。方法如下:

g++ -std=c++14 -fPIC -c BasicExcel.cpp -o BasicExcel.o -O3
g++ -shared -o libbasic_excel.so BasicExcel.o

注意编译时加-O3参数,这样动态链接库的执行速度最快。调用它的主程序,因为没有大量实际操作,是否加-O3参数反而不重要了。

调用

将上述软件的头文件所在目录记录下来,在编译时用-I 参数提供。
将上述软件的so文件所在目录加入LIBRARY_PATH和LD_LIBRARY_PATH环境变量,前者是链接自己的程序时用,后者是运行时用。
如果用make install安装,则两者都在搜索路径中了。

功能

DeepSeek的简介已经写得很明白了,libxls只读、xlslib只写,功能全面,BasicExcel可读写,但只有基本功能。作者自己写的BasicExcel局限性如下:
它不支持格式化
它不支持公式
它不支持图表
它不支持Unicode UTF-32
它支持的东西如下:
读写数字(整数,实数)和字符串(ANSI,UTF16)
添加工作表
重命名工作表
删除工作表
获取工作表的名称
其实对我而言,这些功能也够用了。所以我的想法是,将它们做一个性能比较,最后各留下读性能和写性能最好的一个。

性能比较

我让DeepSeek编写了一个测试程序,提示词如下,

请把你列举的几个库用一个整合的main函数来测试读写(如果有)功能的计时,各种库写的示例xls文件,9个sheet,每个sheet分别是5列、10列、15列,分别是1百行,3百行,6百行,各种组合中都包括文本列、数字列、日期列。最后用BasicExcel输出一个存储比较结果,比较文件大小和读取或写入时间的excel表格

值得一提的是,它忘记了xlslib是只写的工具,所以还提交了测试读的代码,当然编译出错,现已删除。

#include <iostream>
#include <chrono>
#include <vector>
#include <string>
#include <iomanip>
#include <fstream>// 测试配置
const std::vector<int> COLUMNS = {5,10};
const std::vector<int> ROWS = {8000};
const int SHEET_COUNT = 9;// 测试数据生成
struct TestData {std::string text;double number;std::string date;
};TestData generate_data(int row, int col) {return {"Text_" + std::to_string(row) + "_" + std::to_string(col),row * 0.1 + col,"2023-" + std::to_string(1 + col % 12) + "-" + std::to_string(1 + row % 28)};
}// 测试结果存储
struct BenchmarkResult {std::string library;int columns;int rows;double write_time;double read_time;size_t file_size;
};std::vector<BenchmarkResult> results;// ----------------------------
// libxls 测试 (只读)
// ----------------------------
#ifdef USE_LIBXLS
#include <xls.h>
using namespace xls;
void test_libxls_read(const std::string& filename, int cols, int rows) {auto start = std::chrono::high_resolution_clock::now();xlsWorkBook* pWB = xls_open(filename.c_str(), "UTF-8");if (!pWB) {std::cerr << "Failed to open " << filename << std::endl;return;}for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {xlsWorkSheet* pWS = xls_getWorkSheet(pWB, sheet);xls_parseWorkSheet(pWS);// 简单验证数据if (pWS->rows.lastrow != rows || pWS->rows.lastcol != cols -1) {std::cerr << "Data mismatch in sheet " << sheet << pWS->rows.lastrow  <<" "<< rows   <<" "<< pWS->rows.lastcol  <<" "<< cols <<std::endl;}xls_close_WS(pWS);}xls_close_WB(pWB);auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> elapsed = end - start;std::ifstream file(filename, std::ios::binary | std::ios::ate);size_t size = file.tellg();results.push_back({"libxls", cols, rows, 0.0, // 无写入测试elapsed.count(),size});
}
#endif// ----------------------------
// BasicExcel 测试
// ----------------------------
#ifdef USE_BASICEXCEL
#include "BasicExcel.hpp"void test_basic_excel(const std::string& filename, int cols, int rows) {// 写入测试auto write_start = std::chrono::high_resolution_clock::now();YExcel::BasicExcel excel;for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {YExcel::BasicExcelWorksheet* ws = excel.AddWorksheet(("Sheet" + std::to_string(sheet)).c_str());// 写入标题for (int col = 0; col < cols; ++col) {ws->Cell(0, col)->SetString(("Col_" + std::to_string(col)).c_str());}// 写入数据for (int row = 1; row <= rows; ++row) {TestData data = generate_data(row, cols);ws->Cell(row, 0)->SetString(data.text.c_str());ws->Cell(row, 1)->SetDouble(data.number);ws->Cell(row, 2)->SetString(data.date.c_str());// 填充剩余列for (int col = 3; col < cols; ++col) {ws->Cell(row, col)->SetString(("Extra_" + std::to_string(col)).c_str());}}}excel.SaveAs(filename.c_str());auto write_end = std::chrono::high_resolution_clock::now();// 读取测试auto read_start = std::chrono::high_resolution_clock::now();YExcel::BasicExcel excel2;if (!excel2.Load(filename.c_str())) {std::cerr << "Failed to load " << filename << std::endl;return;}for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {YExcel::BasicExcelWorksheet* ws = excel2.GetWorksheet(sheet);if (!ws) continue;// 简单验证数据if (ws->GetTotalRows() != rows + 1 || ws->GetTotalCols() != cols) {std::cerr << "Data mismatch in sheet " << sheet << ws->GetTotalRows()  <<" "<< rows + 1  <<" "<< ws->GetTotalCols()  <<" "<< cols <<std::endl;}}auto read_end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> write_elapsed = write_end - write_start;std::chrono::duration<double> read_elapsed = read_end - read_start;std::ifstream file(filename, std::ios::binary | std::ios::ate);size_t size = file.tellg();results.push_back({"BasicExcel", cols, rows,write_elapsed.count(),read_elapsed.count(),size});
}
// ----------------------------
// 生成比较报告
// ----------------------------
void generate_report() {YExcel::BasicExcel report;YExcel::BasicExcelWorksheet* ws = report.AddWorksheet("Results");// 标题行ws->Cell(0, 0)->SetString("Library");ws->Cell(0, 1)->SetString("Columns");ws->Cell(0, 2)->SetString("Rows");ws->Cell(0, 3)->SetString("Write Time (s)");ws->Cell(0, 4)->SetString("Read Time (s)");ws->Cell(0, 5)->SetString("File Size (KB)");// 数据行for (size_t i = 0; i < results.size(); ++i) {const auto& res = results[i];int row = i + 1;ws->Cell(row, 0)->SetString(res.library.c_str());ws->Cell(row, 1)->SetDouble(res.columns);ws->Cell(row, 2)->SetDouble(res.rows);ws->Cell(row, 3)->SetDouble(res.write_time);ws->Cell(row, 4)->SetDouble(res.read_time);ws->Cell(row, 5)->SetDouble(res.file_size / 1024.0);}report.SaveAs("benchmark_results.xls");std::cout << "Benchmark report saved to benchmark_results.xls" << std::endl;
}
#endif// ----------------------------
// xlslib 测试
// ----------------------------
#ifdef USE_XLSLIB
#include "xlslib.h"void test_xlslib(const std::string& filename, int cols, int rows) {// 写入测试auto write_start = std::chrono::high_resolution_clock::now();xlslib_core::workbook wb;for (int sheet = 0; sheet < SHEET_COUNT; ++sheet) {xlslib_core::worksheet* ws = wb.sheet(("Sheet" + std::to_string(sheet)).c_str());// 写入标题for (int col = 0; col < cols; ++col) {ws->label(0, col, ("Col_" + std::to_string(col)).c_str());}// 写入数据for (int row = 1; row <= rows; ++row) {TestData data = generate_data(row, cols);ws->label(row, 0, data.text.c_str());ws->number(row, 1, data.number);ws->label(row, 2, data.date.c_str());// 填充剩余列for (int col = 3; col < cols; ++col) {ws->label(row, col, ("Extra_" + std::to_string(col)).c_str());}}}wb.Dump(filename.c_str());auto write_end = std::chrono::high_resolution_clock::now();// 读取测试auto read_start = std::chrono::high_resolution_clock::now();
/*  删除读取代码
*/    auto read_end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> write_elapsed = write_end - write_start;std::chrono::duration<double> read_elapsed = read_end - read_start;std::ifstream file(filename, std::ios::binary | std::ios::ate);size_t size = file.tellg();results.push_back({"xlslib", cols, rows,write_elapsed.count(),read_elapsed.count(),size});
}
#endif// ----------------------------
// 主函数
// ----------------------------
int main() {// 测试所有组合for (int cols : COLUMNS) {for (int rows : ROWS) {std::string base_name = "test_" + std::to_string(cols) + "x" + std::to_string(rows);#ifdef USE_BASICEXCELtest_basic_excel(base_name + "_basic.xls", cols, rows);#endif#ifdef USE_XLSLIBtest_xlslib(base_name + "_xlslib.xls", cols, rows);#endif#ifdef USE_LIBXLS// 需要先用其他库生成文件test_libxls_read(base_name + "_basic.xls", cols, rows);#endif}}// 生成比较报告#ifdef USE_BASICEXCELgenerate_report();#endifreturn 0;
}

将测试程序命名为excel_benchmark.cpp,编译脚本如下:

#1.只测试BasicExcel
#如果提前将BasicExcel编译成动态链接库
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark.o -DUSE_BASICEXCEL -O3
g++ -o excel_benchmark excel_benchmark.o  -L ./ -lbasic_excel
#如果一次性编译
g++ -o excel_benchmark excel_benchmark.cpp -DUSE_BASICEXCEL -O3#2.只测试xlslib,因为数据量稍大,超过5000行,BasicExcel就执行出错
g++ -std=c++14 excel_benchmark.cpp -o excel_benchmark2 -DUSE_XLSLIB -I /par/xlslib/src -O3 -lxls#3.测试BasicExcel+libxls
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark3.o -DUSE_BASICEXCEL -DUSE_LIBXLS -I /usr/local/include/xlslib -O3
g++ -o excel_benchmark3 excel_benchmark3.o  -L ./ -lbasic_excel -lxlsreader#4.测试BasicExcel+xlslib
g++ -std=c++14 -c excel_benchmark.cpp -o excel_benchmark4.o -DUSE_BASICEXCEL -DUSE_XLSLIB -I /usr/local/include/xlslib -O3
g++ -o excel_benchmark4 excel_benchmark4.o  -L ./ -lbasic_excel -lxls

因为两个软件都定义了 ‘unsigned64_t’,编译冲突,没有测试xlslib+libxls的组合

各种规模的xls文件读写测试如下表所示,因为x64和arm配置不同不可比, 除了一开始显示BasicExcel过慢的写速度时跨平台比较外,其余均只测大家都正常的arm平台。

xlslib写2个8000行文件测试结果:

time ./excel_benchmark2real	0m2.223s
user	0m2.116s
sys		0m0.076s

一个问题有待解决,BasicExcel在x64平台上的速度离奇地慢,1.3MB的文件写入用时13秒,约为aarch64上的百倍。更大的问题是,当文件稍大,比如10列5000行,就会发生内存分配错误,而代码中对这类错误并没有异常捕获机制,导致不能自动退出,而是耗尽系统资源。

所以结论就是, 各种库的兼容性都不错,都能跨平台使用。
xlslib在功能多很多的情况下,用时与BasicExcel相当或略慢,而且支持更大的文件,缺点是生成的文件较大。libxls的读速比BasicExcel快很多。

不同规模读写比较

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

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

相关文章

从测试角度看待CI/CD,敏捷开发

什么是敏捷开发&#xff1f; 是在高强度反馈的情况下&#xff0c;短周期&#xff0c;不断的迭代产品&#xff0c;满足用户需求&#xff0c;抢占更多的市场 敏捷开发是什么&#xff1f; 是一种产品快速迭代的情况下&#xff0c;降低出错的概率&#xff0c;具体会落实到公司的…

figma MCP + cursor如何将设计稿生成前端页面

一、准备工作 figma MCP需要通过figma key来获取设计稿权限&#xff0c;key的生成步骤如下 1. 打开figma网页版/APP&#xff0c;进入账户设定 2. 点击生成token 3. 填写内容生成token(一定要确认复制了&#xff0c;不然关闭弹窗后就不会显示了) 二、配置MCP 4. 进入到cursor…

git互联GitHub 使用教程

一、下载git Git 公司 右键 git config --global user.name "name" git config --global user.email "email" ssh-keygen -t rsa -C email &#xff1a;生成的ssh密钥需要到github 网站中保存ssh 二、GitHub新建repository 三、本地git互联GitHub 找…

“轻量应用服务器” vs. “云服务器CVM”:小白入门腾讯云,哪款“云机”更适合你?(场景、配置、价格对比解析)

更多云服务器知识&#xff0c;尽在hostol.com 当你第一次踏入腾讯云这个“数字百货大楼”&#xff0c;面对琳琅满目的“云产品”&#xff0c;是不是有点眼花缭乱&#xff0c;特别是看到“轻量应用服务器”和“云服务器CVM”这两位都号称能帮你“安家落户”的“云主机”时&…

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…

Qt学习及使用_第1部分_认识Qt---Qt简介

前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾斜下划线…

Python语法基础篇(包含类型转换、拷贝、可变对象/不可变对象,函数,拆包,异常,模块,闭包,装饰器)

Python语法基础篇&#xff08;二&#xff09; 类型转换拷贝可变对象与不可变对象可变对象不可变对象 函数拆包异常模块闭包装饰器 &#x1f439;&#x1f439;&#x1f439;&#x1f439;&#x1f439;一只正在努力学习计算机技术的小仓鼠&#xff0c;尾部有课程链接哦~&#x…

录制mp4

目录 单线程保存mp4 多线程保存mp4 rtsp ffmpeg录制mp4 单线程保存mp4 import cv2 import imageiocv2.namedWindow(photo, 0) # 0窗口大小可以任意拖动&#xff0c;1自适应 cv2.resizeWindow(photo, 1280, 720) url "rtsp://admin:aa123456192.168.1.64/h264/ch1/main…

ISBN书号查询接口如何用PHP实现调用?

一、什么是ISBN书号查询接口 ISBN数据查询接口是一项图书信息查询服务。它基于全球通用的ISBN编码系统&#xff0c;帮助用户快速获取图书的详细信息&#xff0c;包括书名、作者、出版社、出版时间、价格、封面等关键字段。 该接口广泛应用于电商平台、图书馆管理系统、二手书…

Redis底层数据结构之深入理解跳表(2)

上一篇文章中我们详细讲述了跳表的增添、查找和修改的操作&#xff0c;这篇文章我们来讲解一下跳表在多线程并发时的安全问题。在Redis中&#xff0c;除了网络IO部分和大文件的后台复制涉及到多线程外&#xff0c;其余任务执行时全部都是单线程&#xff0c;这也就意味着在Redis…

Go语言依赖管理与版本控制-《Go语言实战指南》

在现代软件开发中&#xff0c;项目的第三方依赖和版本控制扮演着至关重要的角色。Go 语言自 Go 1.11 引入 Modules&#xff08;模块化管理&#xff09;以来&#xff0c;已经实现了内建的依赖管理机制&#xff0c;彻底摆脱了传统 GOPATH 模式的限制。 本章将深入探讨如何使用 Go…

Appium+python自动化(十一)- 元素定位- 下

1、 List定位 List顾名思义就是一个列表&#xff0c;在python里面也有list这一个说法&#xff0c;如果你不是很理解什么是list&#xff0c;这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合&#xff0c;那么他的个数也就成了不确定性&#xff0c;所以这里需要用复…

stress 服务器压力测试的工具学习

一、stress 工具介绍 tress 是一种工具&#xff0c;可以对符合 POSIX 标准的操作系统施加可配置数量的 CPU、内存、I/O 或磁盘压力&#xff0c;并报告其检测到的任何错误。 stress 不是一个基准测试。它是由系统管理员用来评估其系统扩展性的工具&#xff0c;由内核程序员用来…

不止抓请求:5种开发场景中的抓包组合策略(含 Charles 等工具)

很多开发者用抓包&#xff0c;只在“接口调不通”的时候。 但在复杂项目中&#xff0c;抓包早已不仅是调错工具&#xff0c;更是开发节奏提速器、协作问题解耦器、架构瓶颈探测器。 关键在于——不同场景下&#xff0c;你要用对方法、配对工具。 以下是我根据日常开发实战&a…

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…

计算机系统大作业——程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 物联网工程 学   号 2022112820 班 级 2237301 学 生 孟宇航 指 导 教 师 吴 锐 计算机科学与技术学院 2024年…

〈软件安装管家软件目录〉▷Windows系统版

①装机常用 ☞压缩解压WinRAR7-ZIPBandZip360压缩☞文件工具EverythingOneCommander XYplorer ReNamer ☞卸载软件CCleanerIObitUninstallerUninstall toolGeekAutodesk卸载Adobe卸载Ashampoo☞驱动软件驱动人生&#xff08;离线版&#xff09;驱动精灵&#xff08;离线版&…

CentOS Stream 8 Unit network.service not found

一、问题现象 在 CentOS Stream 8 操作系统中&#xff0c;配置完静态IP 信息&#xff0c;想重启网络服务。 执行如下命令&#xff1a; systemctl restart network 提示信息如下&#xff1a; Failed to restart network.service: Unit network.service not found. 二、问题…

极空间z4pro配置gitea mysql,内网穿透

极空间z4pro配置gitea mysql等记录&#xff0c;内网穿透 1、mysql、gitea镜像下载&#xff0c;极空间不成功&#xff0c;先用自己电脑科学后下载镜像,拉取代码&#xff1a; docker pull --platform linux/amd64 gitea/gitea:1.23 docker pull --platform linux/amd64 mysql:5.…

[假面骑士] 龙骑浅谈

作为一个伪二次元的我&#xff0c;总感觉目前没有什么好番可追。结果某一天在小破站刷到了一个假面骑士相关的视频&#xff0c;我就突发奇想&#xff0c;要不把假面骑士补完算了。 搜了搜&#xff0c;版权全在企鹅哪儿&#xff0c;不想充&#xff0c;于是去找了某盘的资源。果…