You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
25 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE HTML>
<html lang="zh-CN" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>目录访问 - Rusty Book(锈书)</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../theme/style1.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../about.html">Rusty Book</a></li><li class="chapter-item expanded affix "><li class="part-title">Awesome</li><li class="spacer"></li><li class="chapter-item expanded "><a href="../daily-dev.html">日常开发常用库</a></li><li class="chapter-item expanded "><a href="../superstar.html">Rust 明星项目</a></li><li class="chapter-item expanded "><a href="../empowering-js.html">使用 Rust 增强 JS</a></li><li class="chapter-item expanded "><a href="../games.html">Rust开发的游戏</a></li><li class="chapter-item expanded "><a href="../gamedev.html">游戏引擎</a></li><li class="chapter-item expanded affix "><li class="part-title">Awesome + Cookbook</li><li class="spacer"></li><li class="chapter-item expanded "><a href="../algos/awesome.html">实用算法</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../algos/randomness.html">生成随机值</a></li><li class="chapter-item expanded "><a href="../algos/sorting.html">Vec 排序</a></li><li class="chapter-item expanded "><div>压缩算法</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../algos/compression/tar.html">使用.tar包</a></li></ol></li><li class="chapter-item expanded "><div>密码学</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../algos/cryptography/hashing.html">哈希</a></li><li class="chapter-item "><a href="../algos/cryptography/encryption.html">加密</a></li></ol></li><li class="chapter-item expanded "><div>数学计算</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item "><a href="../algos/math/linear-algebra.html">线性代数</a></li><li class="chapter-item "><a href="../algos/math/trigonometry.html">三角函数</a></li><li class="chapter-item "><a href="../algos/math/complex.html">复数</a></li><li class="chapter-item "><a href="../algos/math/statistics.html">统计学</a></li><li class="chapter-item "><a href="../algos/math/misc.html">杂项</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../datastructures/awesome.html">数据结构</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../datastructures/bitfield.html">位字段</a></li></ol></li><li class="chapter-item expanded "><a href="../cmd/awesome.html">命令行</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../cmd/parsing.html">参数解析</a></li><li class="chapter-item expanded "><a href="../cmd/ansi.html">终端输出格式化</a></li></ol></li><li class="chapter-item expanded "><a href="../os/awesome.html">操作系统</a><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../os/processor.html">处理器</a></li><li class="chapter-item expanded "><a href="../os/command.html">调用系统命令</a></li></ol></li><li class="chapter-item expanded "><div>并发</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../cocurrency/threads.html">线程</a></li><li class="chapter-item expanded "><a href="../cocurrency/parallel.html">使用rayon并行处理数据</a></li></ol></li><li class="chapter-item expanded "><div>数据库</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../database/sqlite.html">SQLite</a></li><li class="chapter-item expanded "><a href="../database/postgres.html">Postgres</a></li></ol></li><li class="chapter-item expanded "><div>日期和时间</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../datetime/duration.html">时间计算和转换</a></li><li class="chapter-item expanded "><a href="../datetime/parsing.html">解析和显示</a></li></ol></li><li class="chapter-item expanded "><div>开发者工具</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../devtools/log.html">日志</a></li><li class="chapter-item expanded "><a href="../devtools/config-log.html">配置日志</a></li><li class="chapter-item expanded "><a href="../devtools/version.html">版本号</a></li><li class="chapter-item expanded "><a href="../devtools/build-tools.html">构建时工具</a></li></ol></li><li class="chapter-item expanded "><div>编解码</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../encoding/strings.html">字符编码</a></li><li class="chapter-item expanded "><a href="../encoding/csv.html">CSV</a></li><li class="chapter-item expanded "><a href="../encoding/structured.html">结构化数据</a></li></ol></li><li class="chapter-item expanded "><div>错误处理</div></li><li class="chapter-item expanded "><div>文件操作</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../files/read-write.html">文件读写</a></li><li class="chapter-item expanded "><a href="../files/dir.html" class="active">目录访问</a></li></ol></li><li class="chapter-item expanded "><div>内存管理</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../memory/global-vars.html">全局变量</a></li></ol></li><li class="chapter-item expanded "><div>网络协议</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../protocols/tcpip.html">TCP/IP</a></li></ol></li><li class="chapter-item expanded "><div>文本处理</div><a class="toggle"><div></div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../text/regex.html">正则表达式</a></li><li class="chapter-item expanded "><a href="../text/string.html">字符串解析</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rusty Book(锈书)</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/studyrs/rusty-book" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/studyrs/rusty-book/edit/main/src/files/dir.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<!-- Page table of contents -->
<div class="sidetoc"><nav class="pagetoc"></nav></div>
<main>
<h1 id="目录访问"><a class="header" href="#目录访问">目录访问</a></h1>
<h3 id="获取24小时内被修改过的文件"><a class="header" href="#获取24小时内被修改过的文件">获取24小时内被修改过的文件</a></h3>
<p>通过遍历读取目录中文件的 <a href="https://doc.rust-lang.org/std/fs/struct.Metadata.html#method.modified">Metadata::modified</a> 属性,来获取目标文件名列表。</p>
<pre><pre class="playground"><code class="language-rust editable edition2021">use error_chain::error_chain;
use std::{env, fs};
error_chain! {
foreign_links {
Io(std::io::Error);
SystemTimeError(std::time::SystemTimeError);
}
}
fn main() -&gt; Result&lt;()&gt; {
let current_dir = env::current_dir()?;
println!(
&quot;Entries modified in the last 24 hours in {:?}:&quot;,
current_dir
);
for entry in fs::read_dir(current_dir)? {
let entry = entry?;
let path = entry.path();
let metadata = fs::metadata(&amp;path)?;
let last_modified = metadata.modified()?.elapsed()?.as_secs();
if last_modified &lt; 24 * 3600 &amp;&amp; metadata.is_file() {
println!(
&quot;Last modified: {:?} seconds, is read only: {:?}, size: {:?} bytes, filename: {:?}&quot;,
last_modified,
metadata.permissions().readonly(),
metadata.len(),
path.file_name().ok_or(&quot;No filename&quot;)?
);
}
}
Ok(())
}
</code></pre></pre>
<h3 id="获取给定路径的-loops"><a class="header" href="#获取给定路径的-loops">获取给定路径的 loops</a></h3>
<p>使用 <a href="">same_file::is_same_file</a> 可以检查给定路径的 loopsloop 可以通过以下方式创建:</p>
<pre><code class="language-shell">mkdir -p /tmp/foo/bar/baz
ln -s /tmp/foo/ /tmp/foo/bar/baz/qux
</code></pre>
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::io;
use std::path::{Path, PathBuf};
use same_file::is_same_file;
fn contains_loop&lt;P: AsRef&lt;Path&gt;&gt;(path: P) -&gt; io::Result&lt;Option&lt;(PathBuf, PathBuf)&gt;&gt; {
let path = path.as_ref();
let mut path_buf = path.to_path_buf();
while path_buf.pop() {
if is_same_file(&amp;path_buf, path)? {
return Ok(Some((path_buf, path.to_path_buf())));
} else if let Some(looped_paths) = contains_loop(&amp;path_buf)? {
return Ok(Some(looped_paths));
}
}
return Ok(None);
}
fn main() {
assert_eq!(
contains_loop(&quot;/tmp/foo/bar/baz/qux/bar/baz&quot;).unwrap(),
Some((
PathBuf::from(&quot;/tmp/foo&quot;),
PathBuf::from(&quot;/tmp/foo/bar/baz/qux&quot;)
))
);
}
</code></pre></pre>
<h3 id="递归查找重复的文件名"><a class="header" href="#递归查找重复的文件名">递归查找重复的文件名</a></h3>
<p><a href="https://docs.rs/walkdir/latest/walkdir/">walkdir</a> 可以帮助我们遍历指定的目录。</p>
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::collections::HashMap;
use walkdir::WalkDir;
fn main() {
let mut filenames = HashMap::new();
// 遍历当前目录
for entry in WalkDir::new(&quot;.&quot;)
.into_iter()
.filter_map(Result::ok)
.filter(|e| !e.file_type().is_dir()) {
let f_name = String::from(entry.file_name().to_string_lossy());
let counter = filenames.entry(f_name.clone()).or_insert(0);
*counter += 1;
if *counter == 2 {
println!(&quot;{}&quot;, f_name);
}
}
}
</code></pre></pre>
<h3 id="递归查找满足条件的所有文件"><a class="header" href="#递归查找满足条件的所有文件">递归查找满足条件的所有文件</a></h3>
<p>下面的代码通过 <a href="https://docs.rs/walkdir/latest/walkdir/">walkdir</a> 来查找当前目录中最近一天内发生过修改的所有文件。</p>
<p><a href="https://docs.rs/walkdir/*/walkdir/struct.WalkDir.html#method.follow_links">follow_links</a><code>true</code> 时,那软链接会被当成正常的文件或目录一样对待,也就是说软链接指向的文件或目录也会被访问和检查。若软链接指向的目标不存在或它是一个 loops就会导致错误的发生。</p>
<pre><pre class="playground"><code class="language-rust editable edition2021"><span class="boring">use error_chain::error_chain;
</span>
use walkdir::WalkDir;
<span class="boring">error_chain! {
</span><span class="boring"> foreign_links {
</span><span class="boring"> WalkDir(walkdir::Error);
</span><span class="boring"> Io(std::io::Error);
</span><span class="boring"> SystemTime(std::time::SystemTimeError);
</span><span class="boring"> }
</span><span class="boring">}
</span>
fn main() -&gt; Result&lt;()&gt; {
for entry in WalkDir::new(&quot;.&quot;)
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok()) {
let f_name = entry.file_name().to_string_lossy();
let sec = entry.metadata()?.modified()?;
if f_name.ends_with(&quot;.json&quot;) &amp;&amp; sec.elapsed()?.as_secs() &lt; 86400 {
println!(&quot;{}&quot;, f_name);
}
}
Ok(())
}
</code></pre></pre>
<h3 id="遍历目录跳过隐藏文件"><a class="header" href="#遍历目录跳过隐藏文件">遍历目录跳过隐藏文件</a></h3>
<p>下面例子使用 <a href="https://docs.rs/walkdir/latest/walkdir/">walkdir</a> 来遍历一个目录,同时跳过隐藏文件 <code>is_not_hidden</code></p>
<pre><pre class="playground"><code class="language-rust editable edition2021">use walkdir::{DirEntry, WalkDir};
fn is_not_hidden(entry: &amp;DirEntry) -&gt; bool {
entry
.file_name()
.to_str()
.map(|s| entry.depth() == 0 || !s.starts_with(&quot;.&quot;))
.unwrap_or(false)
}
fn main() {
WalkDir::new(&quot;.&quot;)
.into_iter()
.filter_entry(|e| is_not_hidden(e))
.filter_map(|v| v.ok())
.for_each(|x| println!(&quot;{}&quot;, x.path().display()));
}
</code></pre></pre>
<h3 id="递归计算给定深度的文件大小"><a class="header" href="#递归计算给定深度的文件大小">递归计算给定深度的文件大小</a></h3>
<p>递归访问的深度可以使用 <a href="https://docs.rs/walkdir/*/walkdir/struct.WalkDir.html#method.min_depth">WalkDir::min_depth</a><a href="https://docs.rs/walkdir/2.3.2/walkdir/struct.WalkDir.html#method.max_depth">WalkDir::max_depth</a> 来控制。</p>
<pre><pre class="playground"><code class="language-rust editable edition2021">use walkdir::WalkDir;
fn main() {
let total_size = WalkDir::new(&quot;.&quot;)
.min_depth(1)
.max_depth(3)
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| entry.metadata().ok())
.filter(|metadata| metadata.is_file())
.fold(0, |acc, m| acc + m.len());
println!(&quot;Total size: {} bytes.&quot;, total_size);
}
</code></pre></pre>
<h3 id="递归查找所有-png-文件"><a class="header" href="#递归查找所有-png-文件">递归查找所有 png 文件</a></h3>
<p>例子中使用了 <a href="https://docs.rs/glob/">glob</a> 包,其中的 <code>**</code> 代表当前目录及其所有子目录,例如,<code>/media/**/*.png</code> 代表在 <code>media</code> 和它的所有子目录下查找 png 文件.</p>
<pre><pre class="playground"><code class="language-rust editable edition2021"><span class="boring">use error_chain::error_chain;
</span>
use glob::glob;
<span class="boring">error_chain! {
</span><span class="boring"> foreign_links {
</span><span class="boring"> Glob(glob::GlobError);
</span><span class="boring"> Pattern(glob::PatternError);
</span><span class="boring"> }
</span><span class="boring">}
</span>
fn main() -&gt; Result&lt;()&gt; {
for entry in glob(&quot;**/*.png&quot;)? {
println!(&quot;{}&quot;, entry?.display());
}
Ok(())
}
</code></pre></pre>
<h3 id="查找满足给定正则的所有文件且忽略文件名大小写"><a class="header" href="#查找满足给定正则的所有文件且忽略文件名大小写">查找满足给定正则的所有文件且忽略文件名大小写</a></h3>
<p><a href="https://docs.rs/glob/*/glob/fn.glob_with.html">glob_with</a> 函数可以按照给定的正则表达式进行查找,同时还能使用选项来控制一些匹配设置。</p>
<pre><pre class="playground"><code class="language-rust editable edition2021">use error_chain::error_chain;
use glob::{glob_with, MatchOptions};
error_chain! {
foreign_links {
Glob(glob::GlobError);
Pattern(glob::PatternError);
}
}
fn main() -&gt; Result&lt;()&gt; {
let options = MatchOptions {
case_sensitive: false,
..Default::default()
};
for entry in glob_with(&quot;/media/img_[0-9]*.png&quot;, options)? {
println!(&quot;{}&quot;, entry?.display());
}
Ok(())
}
</code></pre></pre>
<div id="giscus-container"></div>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../files/read-write.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../memory/global-vars.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../files/read-write.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../memory/global-vars.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../ace.js" type="text/javascript" charset="utf-8"></script>
<script src="../editor.js" type="text/javascript" charset="utf-8"></script>
<script src="../mode-rust.js" type="text/javascript" charset="utf-8"></script>
<script src="../theme-dawn.js" type="text/javascript" charset="utf-8"></script>
<script src="../theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
var pagePath = "files/dir.md"
</script>
<!-- Custom JS scripts -->
<script type="text/javascript" src="../assets/custom1.js"></script>
<script type="text/javascript" src="../assets/bigPicture.js"></script>
</body>
</html>