尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

0289-KVS-读取目录中的文件

0289-KVS-读取目录中的文件
📅 发布时间:2026/6/19 3:42:41

环境

  • Time 2022-12-16
  • WSL-Ubuntu 22.04
  • Rust 1.65.0

前言

说明

参考:https://github.com/pingcap/talent-plan

目标

在上一节的基础上,根据提供的目录,到目录中进行文件的读取。

Cargo.toml

[package]
edition = "2021"
name = "kvs"
version = "1.0.0"[dependencies]
clap = {version = "4", features = ["derive"]}
serde = {version = "1", features = ["derive"]}
serde_json = "1"

log.rs

use std::collections::BTreeMap;
use std::path::Path;use crate::cmd::{Command, Index};use self::{reader::PosBufReader, writer::PosBufWriter};mod reader;
mod writer;pub struct CommandLog {reader: PosBufReader,writer: PosBufWriter,index: Index,
}pub type KvResult = anyhow::Result<Option<String>>;impl CommandLog {pub fn new() -> anyhow::Result<Self> {let path = Path::new("/root/log");let writer = PosBufWriter::new(path)?;let mut index = BTreeMap::default();let mut reader = PosBufReader::new(path)?;reader.load(&mut index)?;Ok(Self {reader,writer,index,})}pub fn get(&mut self, key: &str) -> KvResult {self.reader.read(self.index.get(key))}pub fn set(&mut self, key: String, value: String) -> KvResult {let result = self.reader.read(self.index.get(&key));let command = Command::Set {key: key.to_string(),value,};let json = serde_json::to_string(&command)?;let position = self.writer.write(json.as_bytes())?;self.index.insert(key, position);result}pub fn remove(&mut self, key: String) -> KvResult {let result = self.reader.read(self.index.get(&key));let command = Command::Remove {key: key.to_string(),};let json = serde_json::to_string(&command)?;self.writer.write(json.as_bytes())?;self.index.remove(&key);result}
}

reader.rs

use std::ffi::OsStr;
use std::fs::{File, OpenOptions};
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::{Path, PathBuf};use serde_json::Deserializer;use crate::cmd::{Command, CommandPosition, Index};use super::KvResult;pub struct PosBufReader {reader: BufReader<File>,
}impl PosBufReader {pub fn new(path: &Path) -> anyhow::Result<PosBufReader> {let number = *sorted_gen_list(path)?.first().unwrap();let path = path.join(format!("{}.log", number));let file = OpenOptions::new().read(true).open(&path)?;let reader = BufReader::new(file);Ok(Self { reader })}pub fn load(&mut self, map: &mut Index) -> anyhow::Result<()> {let reader = &mut self.reader;let mut old = reader.seek(SeekFrom::Start(0))? as usize;let mut stream = Deserializer::from_reader(reader).into_iter();while let Some(cmd) = stream.next() {let new = stream.byte_offset();match cmd? {Command::Set { key, .. } => {map.insert(key, CommandPosition::new(old, new - old));}Command::Remove { .. } => (),};old = new;}Ok(())}pub fn read(&mut self, position: Option<&CommandPosition>) -> KvResult {let position = match position {Some(position) => position,None => return Ok(None),};self.reader.seek(SeekFrom::Start(position.pos as u64))?;let command = (&mut self.reader).take(position.len as u64);match serde_json::from_reader(command)? {Command::Set { value, .. } => Ok(Some(value)),_ => unreachable!(),}}
}fn sorted_gen_list(path: &Path) -> anyhow::Result<Vec<u64>> {let mut list: Vec<u64> = path.read_dir()?.flat_map(|res| res.map(|entry| entry.path())).filter(|path| path.is_file()).flat_map(file_name_to_number).collect();list.sort_unstable();Ok(list)
}fn file_name_to_number(path: PathBuf) -> Option<u64> {let name = path.file_name().and_then(OsStr::to_str)?;match name.ends_with(".log") {false => None,true => name.trim_end_matches(".log").parse().ok(),}
}

writer.rs

use std::fs::{File, OpenOptions};
use std::io::{BufWriter, Seek, SeekFrom, Write};
use std::path::Path;use crate::cmd::CommandPosition;pub struct PosBufWriter {writer: BufWriter<File>,pos: usize,
}impl PosBufWriter {pub fn new(path: &Path) -> anyhow::Result<Self> {let path = path.join("1.log");let file = OpenOptions::new().append(true).create(true).open(path)?;let mut writer = BufWriter::new(file);let pos = writer.seek(SeekFrom::End(0))? as usize;Ok(Self { writer, pos })}pub fn write(&mut self, buf: &[u8]) -> anyhow::Result<CommandPosition> {let result = CommandPosition::new(self.pos, buf.len());self.writer.write_all(buf)?;self.writer.flush()?;self.pos += result.len;Ok(result)}
}

总结

根据提供的目录,到目录中读取文件,然后将文件中的内容加入到索引中。

附录

相关新闻

  • 0288-KVS-根据索引读取文件
  • GMT0009 SM2密钥算法使用规范
  • 2025发泡混凝土领域厂家推荐榜:云南锦乐建筑领衔,多企业助力绿色建材发展​ 随着

最新新闻

  • 终极Windows USB设备安全弹出解决方案:告别“设备正在使用中“的烦恼
  • 大朗镇美客多入驻培训:墨西哥市场0-1突破 - 东莞选校指南
  • 杭州瓷砖空鼓松动修复:当地反馈比较好的 5 家正规靠谱门店推荐 | 卫生间 / 客厅空鼓专修(2026 最新) - 金修达家庭维修
  • 好的创业项目推荐
  • NXP IEC60730B安全库看门狗测试函数FS_WDOG_Check深度解析与应用实战
  • 2026年当下津市商务车内饰包覆正规门店哪家强:宏骏一站式汽车服务中心常德店深度解析 - 品牌鉴赏官2026

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号