当前位置: 首页 > news >正文

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

环境

  • 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)}
}

总结

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

附录

http://www.jsqmd.com/news/24822/

相关文章:

  • 0288-KVS-根据索引读取文件
  • 2025年南京机械钻井工程服务权威推荐榜单:砖井工程/打桩工程/环保检测井工程源头公司精选
  • 如何在 Mac 上恢复已删除的文件:解决方案和预防技巧
  • GMT0009 SM2密钥算法使用规范
  • 2025精密/五金/冲压/塑料/模具配件/司筒/镶件/零件企业推荐榜:锦鸿深耕三十载筑服务网络,这些实力派值得关注​
  • 2025发泡混凝土领域厂家推荐榜:云南锦乐建筑领衔,多企业助力绿色建材发展​ 随着
  • 2025年泳池水循环设备厂家权威推荐榜单:泳池水净化设备 /钢结构泳池/泳池恒温设备源头厂家精选
  • EasyExcel碰到问题记录
  • 2025年修护/二硫化硒去屑/香氛/控油蓬松/洗发水推荐榜:西安悦己容生物主打植萃护理,四大品牌以精准配方适配多元发质
  • 2025喷涂/聚脲涂料领域源头厂家推荐榜:宁国创遂新材料领衔,多企业助力防腐防护升级​
  • 2025弯管领域源头厂家推荐榜:合肥市翼达机械领衔,多企业助力工业管件加工升级​
  • 2025不锈钢剪板折弯推荐榜:上海一步一金属主打定制加工,四大企业以精准工艺赋能工业制造
  • 2025年碳氢肥料生产厂家权威推荐榜单:农产品用料/增产用肥/碳氢核肥邮沃源头厂家精选
  • 算法分析--分治--3.矩阵乘法
  • 三立轴承:精密轴承安装后怎么检查?
  • 2025年灭火装置厂家推荐排行榜,气体灭火装置,自动灭火装置,机床灭火装置,七氟丙烷灭火装置,二氧化碳灭火装置,清洗机灭火装置,走心机灭火装置,搓丝机灭火装置,磨床灭火装置,火花机灭火装置公司推荐
  • CF2038B Make It Equal
  • 2025年高温线缆优质厂家盘点:实力派企业守护工业核心需求,铁氟龙高温线,硅胶高温线,高压高温线厂家推荐
  • my.conf脚本备份
  • 详细介绍:SQL中的CTE(公用表表达式)完全指南:从入门到精通
  • MySQL 安全审计日志保留与定期备份整改操作文档
  • Alibaba Cloud Linux 3 +Docker 部署 ThinkPHP6 (宝塔环境)-问题篇 - 实践
  • MES 文摘
  • 从网页到桌面:自定义URL协议让应用无缝衔接
  • 2025 年西宁靠谱旅行社,青海出国游报团旅行社,青甘环线旅行社最新推荐,聚焦资质、案例、售后的五家旅行社深度解读
  • Oracle案例:tar安装数据库并从10.2.0.4.8升级到10.2.0.4.9
  • 2025 年西北环线旅行社,青海口碑最好的旅行社,青甘大环线旅行社最新推荐,聚焦资质、案例、售后的五家旅行社深度解读
  • 读书笔记:Oracle分区黑科技:间隔引用分区与虚拟列分区详解
  • 2025 年青海旅行社,青海性价比高的旅行社,西宁旅行社最新推荐,聚焦资质、案例、售后的五家旅行社深度解读
  • 2025年在线折光浓度仪厂家权威推荐榜单:在线折光计/在线近红外光谱仪/在线折光率仪源头厂家精选