`basic_filebuf`、`basic_ifstream`、`basic_ofstream`和 `basic_fstream`。

C++ 文件 I/O 模板类深度解析

文章目录

  • C++ 文件 I/O 模板类深度解析
    • 1. basic_filebuf 深度解析
      • 1.1 类模板定义详解
      • 1.2 关键成员变量
      • 1.3 核心成员函数实现原理
        • 1.3.1 open() 函数实现
        • 1.3.2 overflow() 函数实现
      • 1.4 完整示例:自定义缓冲策略
    • 2. basic_ifstream 深度解析
      • 2.1 类继承体系
      • 2.2 构造函数实现原理
      • 2.3 文件读取机制
      • 2.4 完整示例:大文件分块读取
    • 3. basic_ofstream 深度解析
      • 3.1 类继承体系
      • 3.2 文件写入优化策略
      • 3.3 完整示例:高性能日志系统
    • 4. basic_fstream 深度解析
      • 4.1 类继承体系
      • 4.2 随机访问实现原理
      • 4.3 完整示例:数据库式文件操作
    • 5. 高级主题:自定义文件系统适配器
    • 6. 性能优化技巧
      • 6.1 缓冲区大小优化
      • 6.2 内存映射文件示例

我将从底层原理到高级应用,全面详细地解析 C++ 文件 I/O 模板类,包括 basic_filebufbasic_ifstreambasic_ofstreambasic_fstream

1. basic_filebuf 深度解析

basic_filebuf是文件 I/O 的核心缓冲类,继承自 basic_streambuf

1.1 类模板定义详解

template<class CharT,                       // 字符类型 (char, wchar_t 等)class Traits = std::char_traits<CharT> // 字符特性类
> 
class basic_filebuf : public std::basic_streambuf<CharT, Traits>

1.2 关键成员变量

protected:FILE* _M_file;      // 底层C文件指针bool _M_is_open;    // 文件打开状态__c_locale _M_ctype;// 本地化信息// 缓冲区管理相关成员...

1.3 核心成员函数实现原理

1.3.1 open() 函数实现
basic_filebuf<CharT, Traits>* 
basic_filebuf<CharT, Traits>::open(const char* s, ios_base::openmode mode)
{if (is_open())return nullptr;// 转换打开模式为C风格const char* c_mode = translate_mode(mode);if (!c_mode)return nullptr;// 打开文件_M_file = fopen(s, c_mode);if (!_M_file)return nullptr;_M_is_open = true;// 初始化缓冲区_M_initialize_buffers();return this;
}
1.3.2 overflow() 函数实现

处理输出缓冲区满的情况:

typename basic_filebuf<CharT, Traits>::int_type
basic_filebuf<CharT, Traits>::overflow(int_type c)
{if (!_M_is_open)return Traits::eof();// 刷新缓冲区if (_M_write_buf_size > 0) {if (fwrite(_M_write_buf, sizeof(CharT), _M_write_buf_size, _M_file) != _M_write_buf_size)return Traits::eof();_M_write_buf_size = 0;}// 如果有额外字符,直接写入if (!Traits::eq_int_type(c, Traits::eof())) {CharT ch = Traits::to_char_type(c);if (fwrite(&ch, sizeof(CharT), 1, _M_file) != 1)return Traits::eof();}return Traits::not_eof(c);
}

1.4 完整示例:自定义缓冲策略

#include <iostream>
#include <fstream>
#include <vector>template<typename CharT, typename Traits = std::char_traits<CharT>>
class custom_filebuf : public std::basic_filebuf<CharT, Traits> {
public:using int_type = typename Traits::int_type;// 自定义缓冲区大小explicit custom_filebuf(size_t buf_size = 1024) : buffer(buf_size) {this->setp(buffer.data(), buffer.data() + buffer.size());}protected:// 重写 overflow 实现自定义刷新策略int_type overflow(int_type c) override {if (!this->is_open())return Traits::eof();// 获取当前缓冲区内容CharT* base = this->pbase();CharT* current = this->pptr();// 写入缓冲区内容if (base && current > base) {if (fwrite(base, sizeof(CharT), current - base, this->_M_file) != static_cast<size_t>(current - base))return Traits::eof();}// 处理额外字符if (!Traits::eq_int_type(c, Traits::eof())) {CharT ch = Traits::to_char_type(c);if (fwrite(&ch, sizeof(CharT), 1, this->_M_file) != 1)return Traits::eof();}// 重置缓冲区指针this->setp(buffer.data(), buffer.data() + buffer.size());return Traits::not_eof(c);}private:std::vector<CharT> buffer;
};int main() {// 使用自定义文件缓冲custom_filebuf<char> cfb;cfb.open("custom_buffer.txt", std::ios_base::out);std::ostream os(&cfb);for (int i = 0; i < 1000; ++i) {os << "Line " << i << "\n";}cfb.close();return 0;
}

2. basic_ifstream 深度解析

2.1 类继承体系

basic_istream<CharT, Traits>↑
basic_ifstream<CharT, Traits>

2.2 构造函数实现原理

template<typename CharT, typename Traits>
basic_ifstream<CharT, Traits>::basic_ifstream(const char* filename, ios_base::openmode mode): basic_istream<CharT, Traits>(&_M_filebuf),_M_filebuf()
{if (filename && !_M_filebuf.open(filename, mode | ios_base::in)) {this->setstate(ios_base::failbit);}
}

2.3 文件读取机制

template<typename CharT, typename Traits>
std::streamsize 
basic_ifstream<CharT, Traits>::readsome(CharT* s, std::streamsize n)
{// 检查流状态if (!this->good())return 0;// 获取缓冲区中可用数据std::streamsize avail = this->rdbuf()->in_avail();if (avail <= 0)return 0;// 读取不超过n的字符std::streamsize count = std::min(n, avail);return this->rdbuf()->sgetn(s, count);
}

2.4 完整示例:大文件分块读取

#include <iostream>
#include <fstream>
#include <vector>
#include <chrono>template<typename CharT>
void read_large_file(const std::basic_string<CharT>& filename, size_t chunk_size = 4096) {std::basic_ifstream<CharT> ifs(filename, std::ios_base::binary);if (!ifs) {std::basic_ostream<CharT>(std::cerr) << "Failed to open file\n";return;}auto start = std::chrono::high_resolution_clock::now();std::vector<CharT> buffer(chunk_size);size_t total_bytes = 0;while (ifs) {ifs.read(buffer.data(), chunk_size);std::streamsize count = ifs.gcount();if (count > 0) {total_bytes += count;// 处理数据块...}}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);std::cout << "Read " << total_bytes << " bytes in " << duration.count() << " ms\n";
}int main() {// 读取大文件(4KB块)read_large_file<char>("large_file.bin");// 宽字符版本read_large_file<wchar_t>(L"large_wide_file.bin");return 0;
}

3. basic_ofstream 深度解析

3.1 类继承体系

basic_ostream<CharT, Traits>↑
basic_ofstream<CharT, Traits>

3.2 文件写入优化策略

template<typename CharT, typename Traits>
basic_ofstream<CharT, Traits>& 
basic_ofstream<CharT, Traits>::write(const CharT* s, std::streamsize n)
{// 检查流状态if (!this->good())return *this;// 尝试直接写入缓冲区std::streamsize remaining = n;while (remaining > 0) {std::streamsize avail = this->rdbuf()->sputn(s, remaining);if (avail <= 0) {this->setstate(ios_base::badbit);break;}s += avail;remaining -= avail;}return *this;
}

3.3 完整示例:高性能日志系统

#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <mutex>
#include <vector>template<typename CharT>
class ThreadSafeLogger {
public:explicit ThreadSafeLogger(const std::basic_string<CharT>& filename): _ofs(filename, std::ios_base::app) {}~ThreadSafeLogger() {std::lock_guard<std::mutex> lock(_mutex);_ofs.close();}void log(const std::basic_string<CharT>& message) {std::lock_guard<std::mutex> lock(_mutex);if (_ofs) {auto now = std::chrono::system_clock::now();auto time = std::chrono::system_clock::to_time_t(now);_ofs << std::put_time(std::localtime(&time), "%Y-%m-%d %X") << " | " << message << '\n';// 立即刷新以确保日志及时写入_ofs.flush();}}private:std::basic_ofstream<CharT> _ofs;std::mutex _mutex;
};void test_logger(ThreadSafeLogger<char>& logger, int thread_id) {for (int i = 0; i < 100; ++i) {logger.log("Thread " + std::to_string(thread_id) + " log message " + std::to_string(i));}
}int main() {ThreadSafeLogger<char> logger("thread_safe.log");std::vector<std::thread> threads;for (int i = 0; i < 10; ++i) {threads.emplace_back(test_logger, std::ref(logger), i);}for (auto& t : threads) {t.join();}return 0;
}

4. basic_fstream 深度解析

4.1 类继承体系

basic_iostream<CharT, Traits>↑
basic_fstream<CharT, Traits>

4.2 随机访问实现原理

template<typename CharT, typename Traits>
typename basic_fstream<CharT, Traits>::pos_type
basic_fstream<CharT, Traits>::seekg(pos_type pos)
{if (!this->fail()) {pos_type new_pos = this->rdbuf()->pubseekpos(pos, std::ios_base::in);if (new_pos == pos_type(-1))this->setstate(std::ios_base::failbit);return new_pos;}return pos_type(-1);
}

4.3 完整示例:数据库式文件操作

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>template<typename CharT>
class SimpleFileDB {struct RecordHeader {size_t id;size_t length;bool deleted;};public:explicit SimpleFileDB(const std::basic_string<CharT>& filename): _filename(filename), _next_id(1) {load_index();}~SimpleFileDB() {save_index();}size_t insert(const std::basic_string<CharT>& data) {std::basic_fstream<CharT> fs(_filename, std::ios_base::in | std::ios_base::out | std::ios_base::binary);if (!fs) {fs.open(_filename, std::ios_base::out | std::ios_base::binary);fs.close();fs.open(_filename, std::ios_base::in | std::ios_base::out | std::ios_base::binary);}RecordHeader header{_next_id++, data.length(), false};// 移动到文件末尾fs.seekp(0, std::ios_base::end);// 写入记录头fs.write(reinterpret_cast<CharT*>(&header), sizeof(header));// 写入数据fs.write(data.data(), data.length());// 更新索引_index.push_back({header.id, fs.tellp() - static_cast<std::streampos>(data.length())});return header.id;}bool get(size_t id, std::basic_string<CharT>& out) {auto it = std::find_if(_index.begin(), _index.end(), [id](const auto& entry) { return entry.first == id; });if (it == _index.end())return false;std::basic_ifstream<CharT> ifs(_filename, std::ios_base::binary);ifs.seekg(it->second);RecordHeader header;ifs.read(reinterpret_cast<CharT*>(&header), sizeof(header));if (header.deleted)return false;out.resize(header.length);ifs.read(&out[0], header.length);return true;}bool remove(size_t id) {auto it = std::find_if(_index.begin(), _index.end(), [id](const auto& entry) { return entry.first == id; });if (it == _index.end())return false;std::basic_fstream<CharT> fs(_filename, std::ios_base::in | std::ios_base::out | std::ios_base::binary);fs.seekp(it->second + offsetof(RecordHeader, deleted));bool deleted = true;fs.write(reinterpret_cast<CharT*>(&deleted), sizeof(deleted));return true;}private:void load_index() {std::basic_ifstream<CharT> ifs(_filename, std::ios_base::binary);if (!ifs)return;while (ifs) {std::streampos pos = ifs.tellg();RecordHeader header;ifs.read(reinterpret_cast<CharT*>(&header), sizeof(header));if (!ifs)break;_index.emplace_back(header.id, pos);_next_id = std::max(_next_id, header.id + 1);// 跳过数据ifs.seekg(header.length, std::ios_base::cur);}}void save_index() {// 在实际应用中,可以保存索引到单独文件}std::basic_string<CharT> _filename;std::vector<std::pair<size_t, std::streampos>> _index;size_t _next_id;
};int main() {SimpleFileDB<char> db("simple_db.dat");size_t id1 = db.insert("First record data");size_t id2 = db.insert("Second record data");std::string data;if (db.get(id1, data)) {std::cout << "Record " << id1 << ": " << data << "\n";}db.remove(id2);if (!db.get(id2, data)) {std::cout << "Record " << id2 << " not found (deleted)\n";}return 0;
}

5. 高级主题:自定义文件系统适配器

#include <iostream>
#include <streambuf>
#include <vector>
#include <memory>// 内存文件系统适配器
template<typename CharT, typename Traits = std::char_traits<CharT>>
class memory_filebuf : public std::basic_streambuf<CharT, Traits> {
public:using int_type = typename Traits::int_type;explicit memory_filebuf(std::vector<CharT>& storage): _storage(storage), _pos(0) {this->setg(_storage.data(), _storage.data(), _storage.data() + _storage.size());this->setp(_storage.data(), _storage.data() + _storage.size());}protected:// 读取操作int_type underflow() override {if (this->gptr() == this->egptr()) {if (_pos >= _storage.size())return Traits::eof();this->setg(_storage.data(), _storage.data() + _pos, _storage.data() + _storage.size());}return Traits::to_int_type(*this->gptr());}// 写入操作int_type overflow(int_type c) override {if (!Traits::eq_int_type(c, Traits::eof())) {if (_pos >= _storage.size()) {_storage.push_back(Traits::to_char_type(c));} else {_storage[_pos] = Traits::to_char_type(c);}_pos++;return c;}return Traits::not_eof(c);}// 定位操作std::streampos seekpos(std::streampos pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override {if (pos < 0 || pos > static_cast<std::streampos>(_storage.size()))return -1;_pos = static_cast<size_t>(pos);if (which & std::ios_base::in) {this->setg(_storage.data(), _storage.data() + _pos, _storage.data() + _storage.size());}if (which & std::ios_base::out) {this->setp(_storage.data() + _pos, _storage.data() + _storage.size());}return pos;}private:std::vector<CharT>& _storage;size_t _pos;
};template<typename CharT>
class memory_file : public std::basic_iostream<CharT> {
public:explicit memory_file(std::vector<CharT>& storage): std::basic_iostream<CharT>(new memory_filebuf<CharT>(storage)),_buf(static_cast<memory_filebuf<CharT>*>(this->rdbuf())) {}~memory_file() {this->rdbuf(nullptr);delete _buf;}private:memory_filebuf<CharT>* _buf;
};int main() {std::vector<char> storage;memory_file<char> mfile(storage);// 写入数据mfile << "Hello, Memory File!\n";mfile << "This is a test.\n";// 读取数据mfile.seekg(0);std::string line;while (std::getline(mfile, line)) {std::cout << line << "\n";}return 0;
}

6. 性能优化技巧

6.1 缓冲区大小优化

template<typename CharT>
void optimize_buffer_size(const std::basic_string<CharT>& filename) {// 测试不同缓冲区大小对性能的影响const size_t file_size = 100 * 1024 * 1024; // 100MBconst std::vector<size_t> buffer_sizes = {512, 1024, 4096, 8192, 16384, 65536};// 创建测试文件{std::basic_ofstream<CharT> ofs(filename, std::ios_base::binary);std::vector<CharT> data(file_size, 'A');ofs.write(data.data(), data.size());}// 测试不同缓冲区大小for (size_t buf_size : buffer_sizes) {std::vector<CharT> buffer(buf_size);auto start = std::chrono::high_resolution_clock::now();std::basic_ifstream<CharT> ifs(filename, std::ios_base::binary);ifs.rdbuf()->pubsetbuf(buffer.data(), buf_size);size_t total_read = 0;while (ifs) {ifs.read(buffer.data(), buf_size);total_read += ifs.gcount();}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);std::cout << "Buffer size: " << buf_size << " bytes, Time: " << duration.count() << " ms\n";}
}

6.2 内存映射文件示例

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endiftemplate<typename CharT>
class memory_mapped_file {
public:explicit memory_mapped_file(const std::basic_string<CharT>& filename) {
#ifdef _WIN32_hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (_hFile == INVALID_HANDLE_VALUE)throw std::runtime_error("Failed to open file");_hMapping = CreateFileMapping(_hFile, NULL, PAGE_READONLY, 0, 0, NULL);if (_hMapping == NULL) {CloseHandle(_hFile);throw std::runtime_error("Failed to create file mapping");}_data = static_cast<const CharT*>(MapViewOfFile(_hMapping, FILE_MAP_READ, 0, 0, 0));if (_data == NULL) {CloseHandle(_hMapping);CloseHandle(_hFile);throw std::runtime_error("Failed to map view of file");}DWORD sizeHigh;_size = GetFileSize(_hFile, &sizeHigh);_size |= (static_cast<uint64_t>(sizeHigh) << 32);
#else_fd = open(filename.c_str(), O_RDONLY);if (_fd == -1)throw std::runtime_error("Failed to open file");struct stat sb;if (fstat(_fd, &sb) == -1) {close(_fd);throw std::runtime_error("Failed to get file size");}_size = sb.st_size;_data = static_cast<const CharT*>(mmap(NULL, _size, PROT_READ, MAP_PRIVATE, _fd, 0));if (_data == MAP_FAILED) {close(_fd);throw std::runtime_error("Failed to map file");}
#endif}~memory_mapped_file() {
#ifdef _WIN32UnmapViewOfFile(_data);CloseHandle(_hMapping);CloseHandle(_hFile);
#elsemunmap(const_cast<CharT*>(_data), _size);close(_fd);
#endif}const CharT* data() const { return _data; }size_t size() const { return _size; }private:const CharT* _data;size_t _size;
#ifdef _WIN32HANDLE _hFile;HANDLE _hMapping;
#elseint _fd;
#endif
};int main() {try {memory_mapped_file<char> mmf("large_file.bin");std::cout << "File size: " << mmf.size() << " bytes\n";// 可以直接访问文件内容,无需读取操作const char* data = mmf.data();// 处理数据...} catch (const std::exception& e) {std::cerr << "Error: " << e.what() << "\n";}return 0;
}

以上内容全面深入地解析了 C++ 文件 I/O 模板类的各个方面,从基础用法到高级特性,从性能优化到自定义实现,涵盖了文件操作的所有关键知识点。

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

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

相关文章

计算机毕设 java 阿歹果园养鸡场管理系统 基于 SSM 框架的果园养鸡场全流程管理系统设计与实现 Java+MySQL 的养殖生产与进销存一体化平台开发

计算机毕设 java 阿歹果园养鸡场管理系统ky7dc9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09;本套源码可以先看具体功能演示视频领取&#xff0c;文末有联xi 可分享 随着农业养殖规模化发展&#xff0c;传统果园养鸡场依赖人工记录、纸质台账的管理模式&#xf…

生成式BI工具(WrenAI)

生成式 BI 工具支持自然语言查询数据库&#xff0c;自动生成 SQL 与可视化图表&#xff0c;被金融分析师和数据科学家广泛采用。 WrenAI是由Canner团队开发的开源生成式BI&#xff08;GenBI&#xff09;智能体&#xff0c;致力于通过自然语言交互实现数据库查询、可视化生成和洞…

论文Review 3DGS PGSR | TVCG2024 ZJU-3DV | 几何约束的3DGS表面重建

基本信息 题目&#xff1a;PGSR: Planar-based Gaussian Splatting for Efficient and High-Fidelity Surface Reconstruction 来源&#xff1a;TVCG2024 学校&#xff1a;ZJU-3DV 是否开源&#xff1a;https://github.com/zju3dv/PGSR 摘要&#xff1a;3DGS表面重建 最近…

最新After Effects2025下载安装(含安装包)AE 2025 保姆级下载一键安装图文教程

文章目录一、After Effects 2025下载二、After Effects 2025安装教程三、核心功能升级详解四、系统配置与兼容性说明一、After Effects 2025下载 ①夸克网盘下载链接&#xff1a;https://pan.quark.cn/s/a06e6200e64c 二、After Effects 2025安装教程 1.解压安装包:找到下载…

【网络安全领域】边界安全是什么?目前的发展及应用场景

在网络安全领域&#xff0c;边界安全&#xff08;Perimeter Security&#xff09; 是指围绕企业或组织网络的 “物理与逻辑边界” 构建的防护体系&#xff0c;核心目标是阻止未授权访问从外部网络&#xff08;如互联网、合作方网络&#xff09;侵入内部可信网络&#xff0c;同时…

虚拟机快照对内存与磁盘空间的影响

核心概念&#xff1a;快照是什么&#xff1f;虚拟机快照捕获的是在某个特定时间点上虚拟机的完整状态。这包括&#xff1a;磁盘状态&#xff1a;虚拟磁盘的数据。内存状态&#xff1a;当时虚拟机内存中的所有内容&#xff08;如果选择&#xff09;。配置状态&#xff1a;虚拟机…

免费开源的 Gemini 2.5 Flash 图片生成器

免费开源的 Gemini 2.5 Flash 图片生成器&#xff1a;gemini-nano-banana 项目详解 在 AI 图片生成领域&#xff0c;大多数工具要么收费昂贵&#xff0c;要么需要复杂的配置。今天为大家介绍一个完全免费开源的解决方案——gemini-nano-banana&#xff0c;一个基于 Google Gemi…

介绍分布式事务之Seata

简介 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式事务解决方案。 &#x1f680; 一、Seata 的四种主要模式 Seata 提供的分布式事…

安卓/ios按键精灵脚本开发工具:OpenCV.FindImgAll命令介绍

函数名称OpenCV.FindImgAll 找图返回全部结果函数功能使用OpenCV多尺度模板找图&#xff0c;返回全部结果与FindPic的区别&#xff1a;OpenCV找图&#xff1a;基于特征相似性的找图&#xff0c;允许一定几何形变或颜色差异&#xff0c;从而提高多分辨率容兼及抗干扰能力&#x…

Linux时间处理函数

gettimeofday 是 Linux 系统中一个用于获取当前时间的系统调用函数。它能够获取从 Unix 纪元&#xff08;1970年1月1日 00:00:00 UTC&#xff09;到当前时刻的秒数和微秒数。函数原型#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);参…

C++ 面试高频考点 力扣 34. 在排序数组中查找元素的第一个和最后一个位置 二分查找左右端点 题解 每日一题

文章目录二分查找进阶&#xff0c;精准定位左右边界题目描述先踩坑&#xff1a;朴素二分为什么搞不定重复元素&#xff1f;第一步&#xff1a;找左边界——如何定位“第一个target”&#xff1f;第二步&#xff1a;找右边界——如何定位“最后一个target”&#xff1f;完整代码…

在word以及latex中引用zotero中的参考文献

背景 如何在word以及latex中引用zotero中的参考文献 历史参考 恢复Zotero软件内的误删条目数据/文献-CSDN博客使用zotero保存 CNKI知网文章时发生错误。改为尝试用 Save as Webpage 保存。-CSDN博客 word 在word中引用zotero中的参考文献 打开word&#xff0c;点击引用 经典…

docker 部署Skywalking

创建网络 docker network create skywalking-network docker compose 安装SkyWalking docker-compose.yaml 文件 version: "3" services:# SkyWalking OAP server with Elasticsearch storageskywalking-oap:image: apache/skywalking-oap-server:8.9.0container…

动态UI的秘诀:React中的条件渲染

动态UI的秘诀&#xff1a;React中的条件渲染 作者&#xff1a;码力无边各位React探险家&#xff0c;欢迎回到我们的《React奇妙之旅》&#xff01;我是你们的老朋友码力无边。在之前的旅程中&#xff0c;我们已经学会了如何创建组件、传递数据&#xff08;Props&#xff09;、管…

ubuntu挂载外接硬盘

查看找到硬盘sudo fdisk -l例如&#xff1a;名字为&#xff1a;/dev/sda创建挂载点sudo mkdir -p /2TSSD手动挂载&#xff08;单次生效&#xff0c;关机会失效&#xff09;sudo mount /dev/sda1 /2TSSD开机自动挂载&#xff08;永远生效&#xff0c;关机会失效&#xff09;S1&a…

数学思想 | 数学思维过程对象封装

注&#xff1a;本文为 “数学思维过程对象封装” 相关译文。 英文引文&#xff0c;机翻未校。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 What is the object of the encapsulation of a process? 过程封装的对象是什么&#xff1f; David Tall#, Michael Th…

常见视频封装格式对比

一、核心概念&#xff1a;封装格式 vs 编码格式 编码格式 (Codec): 例如 H.264, H.265 (HEVC), AV1, VP9。它负责对原始视频和音频数据进行压缩&#xff0c;是决定视频体积和清晰度的关键。封装格式 (Container): 例如 MP4, MKV, AVI。它负责将已经压缩好的视频、音频、字幕等打…

Java实现PDF表格转换为CSV

在很多企业办公和数据分析的场景中&#xff0c;PDF 中常常存放着报表、清单或统计数据。相比 PDF&#xff0c;CSV 文件 更易于在 Excel 或数据库中进行进一步处理。因此&#xff0c;我们常常需要一种方式&#xff0c;将 PDF 中的表格数据批量抽取并导出为 CSV 文件。 本文将介…

具有类人先验知识的 Affordance-觉察机器人灵巧抓取

25年8月来自武汉大学、阿里达摩院、湖畔研究中心、浙大和清华的论文“Towards Affordance-Aware Robotic Dexterous Grasping with Human-like Priors”。 能够泛化抓取目标的灵巧手是开发通用具身人工智能的基础。然而&#xff0c;之前的方法仅仅关注低级抓取稳定性指标&#…

项目管理的关键成功因素

项目管理的关键成功因素包括&#xff1a;目标明确、科学规划、有效沟通、资源保障、风险管理、团队协作、持续监控与总结改进。目标明确保证方向不偏移、科学规划确保执行有章可循、有效沟通减少误解与冲突、资源保障提供坚实支撑、风险管理帮助预防问题、团队协作提升整体效率…