mpvrc/tokio/fs/index.html

156 lines
No EOL
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Asynchronous file utilities."><title>tokio::fs - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="tokio" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../../static.files/storage-59e33391.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../tokio/index.html">tokio</a><span class="version">1.42.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module fs</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#usage" title="Usage">Usage</a><ul><li><a href="#using-file" title="Using `File`">Using <code>File</code></a></li><li><a href="#tuning-your-file-io" title="Tuning your file IO">Tuning your file IO</a></li></ul></li></ul><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate tokio</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><span class="rustdoc-breadcrumbs"><a href="../index.html">tokio</a></span><h1>Module <span>fs</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/tokio/fs/mod.rs.html#1-317">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Asynchronous file utilities.</p>
<p>This module contains utility methods for working with the file system
asynchronously. This includes reading/writing to files, and working with
directories.</p>
<p>Be aware that most operating systems do not provide asynchronous file system
APIs. Because of that, Tokio will use ordinary blocking file operations
behind the scenes. This is done using the <a href="../task/fn.spawn_blocking.html" title="fn tokio::task::spawn_blocking"><code>spawn_blocking</code></a> threadpool to
run them in the background.</p>
<p>The <code>tokio::fs</code> module should only be used for ordinary files. Trying to use
it with e.g., a named pipe on Linux can result in surprising behavior,
such as hangs during runtime shutdown. For special files, you should use a
dedicated type such as <a href="../net/unix/pipe/index.html" title="mod tokio::net::unix::pipe"><code>tokio::net::unix::pipe</code></a> or <a href="../io/unix/struct.AsyncFd.html" title="struct tokio::io::unix::AsyncFd"><code>AsyncFd</code></a> instead.</p>
<p>Currently, Tokio will always use <a href="../task/fn.spawn_blocking.html" title="fn tokio::task::spawn_blocking"><code>spawn_blocking</code></a> on all platforms, but it
may be changed to use asynchronous file system APIs such as io_uring in the
future.</p>
<h2 id="usage"><a class="doc-anchor" href="#usage">§</a>Usage</h2>
<p>The easiest way to use this module is to use the utility functions that
operate on entire files:</p>
<ul>
<li><a href="fn.read.html" title="fn tokio::fs::read"><code>tokio::fs::read</code></a></li>
<li><a href="fn.read_to_string.html" title="fn tokio::fs::read_to_string"><code>tokio::fs::read_to_string</code></a></li>
<li><a href="fn.write.html" title="fn tokio::fs::write"><code>tokio::fs::write</code></a></li>
</ul>
<p>The two <code>read</code> functions reads the entire file and returns its contents.
The <code>write</code> function takes the contents of the file and writes those
contents to the file. It overwrites the existing file, if any.</p>
<p>For example, to read the file:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">let </span>contents = tokio::fs::read_to_string(<span class="string">"my_file.txt"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="macro">println!</span>(<span class="string">"File has {} lines."</span>, contents.lines().count());</code></pre></div>
<p>To overwrite the file:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">let </span>contents = <span class="string">"First line.\nSecond line.\nThird line.\n"</span>;
tokio::fs::write(<span class="string">"my_file.txt"</span>, contents.as_bytes()).<span class="kw">await</span><span class="question-mark">?</span>;</code></pre></div>
<h3 id="using-file"><a class="doc-anchor" href="#using-file">§</a>Using <code>File</code></h3>
<p>The main type for interacting with files is <a href="struct.File.html" title="struct tokio::fs::File"><code>File</code></a>. It can be used to read
from and write to a given file. This is done using the <a href="../io/trait.AsyncRead.html" title="trait tokio::io::AsyncRead"><code>AsyncRead</code></a> and
<a href="../io/trait.AsyncWrite.html" title="trait tokio::io::AsyncWrite"><code>AsyncWrite</code></a> traits. This type is generally used when you want to do
something more complex than just reading or writing the entire contents in
one go.</p>
<p><strong>Note:</strong> It is important to use <a href="../io/trait.AsyncWriteExt.html#method.flush" title="method tokio::io::AsyncWriteExt::flush"><code>flush</code></a> when writing to a Tokio
<a href="struct.File.html" title="struct tokio::fs::File"><code>File</code></a>. This is because calls to <code>write</code> will return before the write has
finished, and <a href="../io/trait.AsyncWriteExt.html#method.flush" title="method tokio::io::AsyncWriteExt::flush"><code>flush</code></a> will wait for the write to finish. (The write will
happen even if you dont flush; it will just happen later.) This is
different from <a href="https://doc.rust-lang.org/1.84.1/std/fs/struct.File.html" title="struct std::fs::File"><code>std::fs::File</code></a>, and is due to the fact that <code>File</code> uses
<code>spawn_blocking</code> behind the scenes.</p>
<p>For example, to count the number of lines in a file without loading the
entire file into memory:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::fs::File;
<span class="kw">use </span>tokio::io::AsyncReadExt;
<span class="kw">let </span><span class="kw-2">mut </span>file = File::open(<span class="string">"my_file.txt"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span><span class="kw-2">mut </span>chunk = <span class="macro">vec!</span>[<span class="number">0</span>; <span class="number">4096</span>];
<span class="kw">let </span><span class="kw-2">mut </span>number_of_lines = <span class="number">0</span>;
<span class="kw">loop </span>{
<span class="kw">let </span>len = file.read(<span class="kw-2">&amp;mut </span>chunk).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">if </span>len == <span class="number">0 </span>{
<span class="comment">// Length of zero means end of file.
</span><span class="kw">break</span>;
}
<span class="kw">for </span><span class="kw-2">&amp;</span>b <span class="kw">in </span><span class="kw-2">&amp;</span>chunk[..len] {
<span class="kw">if </span>b == <span class="string">b'\n' </span>{
number_of_lines += <span class="number">1</span>;
}
}
}
<span class="macro">println!</span>(<span class="string">"File has {} lines."</span>, number_of_lines);</code></pre></div>
<p>For example, to write a file line-by-line:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::fs::File;
<span class="kw">use </span>tokio::io::AsyncWriteExt;
<span class="kw">let </span><span class="kw-2">mut </span>file = File::create(<span class="string">"my_file.txt"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
file.write_all(<span class="string">b"First line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
file.write_all(<span class="string">b"Second line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
file.write_all(<span class="string">b"Third line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="comment">// Remember to call `flush` after writing!
</span>file.flush().<span class="kw">await</span><span class="question-mark">?</span>;</code></pre></div>
<h3 id="tuning-your-file-io"><a class="doc-anchor" href="#tuning-your-file-io">§</a>Tuning your file IO</h3>
<p>Tokios file uses <a href="../task/fn.spawn_blocking.html" title="fn tokio::task::spawn_blocking"><code>spawn_blocking</code></a> behind the scenes, and this has serious
performance consequences. To get good performance with file IO on Tokio, it
is recommended to batch your operations into as few <code>spawn_blocking</code> calls
as possible.</p>
<p>One example of this difference can be seen by comparing the two reading
examples above. The first example uses <a href="fn.read.html" title="fn tokio::fs::read"><code>tokio::fs::read</code></a>, which reads the
entire file in a single <code>spawn_blocking</code> call, and then returns it. The
second example will read the file in chunks using many <code>spawn_blocking</code>
calls. This means that the second example will most likely be more expensive
for large files. (Of course, using chunks may be necessary for very large
files that dont fit in memory.)</p>
<p>The following examples will show some strategies for this:</p>
<p>When creating a file, write the data to a <code>String</code> or <code>Vec&lt;u8&gt;</code> and then
write the entire file in a single <code>spawn_blocking</code> call with
<code>tokio::fs::write</code>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">let </span><span class="kw-2">mut </span>contents = String::new();
contents.push_str(<span class="string">"First line.\n"</span>);
contents.push_str(<span class="string">"Second line.\n"</span>);
contents.push_str(<span class="string">"Third line.\n"</span>);
tokio::fs::write(<span class="string">"my_file.txt"</span>, contents.as_bytes()).<span class="kw">await</span><span class="question-mark">?</span>;</code></pre></div>
<p>Use <a href="../io/struct.BufReader.html" title="struct tokio::io::BufReader"><code>BufReader</code></a> and <a href="../io/struct.BufWriter.html" title="struct tokio::io::BufWriter"><code>BufWriter</code></a> to buffer many small reads or writes
into a few large ones. This example will most likely only perform one
<code>spawn_blocking</code> call.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::fs::File;
<span class="kw">use </span>tokio::io::{AsyncWriteExt, BufWriter};
<span class="kw">let </span><span class="kw-2">mut </span>file = BufWriter::new(File::create(<span class="string">"my_file.txt"</span>).<span class="kw">await</span><span class="question-mark">?</span>);
file.write_all(<span class="string">b"First line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
file.write_all(<span class="string">b"Second line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
file.write_all(<span class="string">b"Third line.\n"</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="comment">// Due to the BufWriter, the actual write and spawn_blocking
// call happens when you flush.
</span>file.flush().<span class="kw">await</span><span class="question-mark">?</span>;</code></pre></div>
<p>Manually use <a href="https://doc.rust-lang.org/1.84.1/std/fs/index.html" title="mod std::fs"><code>std::fs</code></a> inside <a href="../task/fn.spawn_blocking.html" title="fn tokio::task::spawn_blocking"><code>spawn_blocking</code></a>.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::fs::File;
<span class="kw">use </span>std::io::{<span class="self">self</span>, Write};
<span class="kw">use </span>tokio::task::spawn_blocking;
spawn_blocking(<span class="kw">move </span>|| {
<span class="kw">let </span><span class="kw-2">mut </span>file = File::create(<span class="string">"my_file.txt"</span>)<span class="question-mark">?</span>;
file.write_all(<span class="string">b"First line.\n"</span>)<span class="question-mark">?</span>;
file.write_all(<span class="string">b"Second line.\n"</span>)<span class="question-mark">?</span>;
file.write_all(<span class="string">b"Third line.\n"</span>)<span class="question-mark">?</span>;
<span class="comment">// Unlike Tokio's file, the std::fs file does
// not need flush.
</span>io::Result::Ok(())
}).<span class="kw">await</span>.unwrap()<span class="question-mark">?</span>;</code></pre></div>
<p>Its also good to be aware of <a href="struct.File.html#method.set_max_buf_size" title="method tokio::fs::File::set_max_buf_size"><code>File::set_max_buf_size</code></a>, which controls the
maximum amount of bytes that Tokios <a href="struct.File.html" title="struct tokio::fs::File"><code>File</code></a> will read or write in a single
<a href="../task/fn.spawn_blocking.html" title="fn tokio::task::spawn_blocking"><code>spawn_blocking</code></a> call. The default is two megabytes, but this is subject
to change.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.DirBuilder.html" title="struct tokio::fs::DirBuilder">DirBuilder</a></div><div class="desc docblock-short">A builder for creating directories in various manners.</div></li><li><div class="item-name"><a class="struct" href="struct.DirEntry.html" title="struct tokio::fs::DirEntry">DirEntry</a></div><div class="desc docblock-short">Entries returned by the <a href="struct.ReadDir.html" title="struct tokio::fs::ReadDir"><code>ReadDir</code></a> stream.</div></li><li><div class="item-name"><a class="struct" href="struct.File.html" title="struct tokio::fs::File">File</a></div><div class="desc docblock-short">A reference to an open file on the filesystem.</div></li><li><div class="item-name"><a class="struct" href="struct.OpenOptions.html" title="struct tokio::fs::OpenOptions">Open<wbr>Options</a></div><div class="desc docblock-short">Options and flags which can be used to configure how a file is opened.</div></li><li><div class="item-name"><a class="struct" href="struct.ReadDir.html" title="struct tokio::fs::ReadDir">ReadDir</a></div><div class="desc docblock-short">Reads the entries in a directory.</div></li></ul><h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="fn" href="fn.canonicalize.html" title="fn tokio::fs::canonicalize">canonicalize</a></div><div class="desc docblock-short">Returns the canonical, absolute form of a path with all intermediate
components normalized and symbolic links resolved.</div></li><li><div class="item-name"><a class="fn" href="fn.copy.html" title="fn tokio::fs::copy">copy</a></div><div class="desc docblock-short">Copies the contents of one file to another. This function will also copy the permission bits
of the original file to the destination file.
This function will overwrite the contents of to.</div></li><li><div class="item-name"><a class="fn" href="fn.create_dir.html" title="fn tokio::fs::create_dir">create_<wbr>dir</a></div><div class="desc docblock-short">Creates a new, empty directory at the provided path.</div></li><li><div class="item-name"><a class="fn" href="fn.create_dir_all.html" title="fn tokio::fs::create_dir_all">create_<wbr>dir_<wbr>all</a></div><div class="desc docblock-short">Recursively creates a directory and all of its parent components if they
are missing.</div></li><li><div class="item-name"><a class="fn" href="fn.hard_link.html" title="fn tokio::fs::hard_link">hard_<wbr>link</a></div><div class="desc docblock-short">Creates a new hard link on the filesystem.</div></li><li><div class="item-name"><a class="fn" href="fn.metadata.html" title="fn tokio::fs::metadata">metadata</a></div><div class="desc docblock-short">Given a path, queries the file system to get information about a file,
directory, etc.</div></li><li><div class="item-name"><a class="fn" href="fn.read.html" title="fn tokio::fs::read">read</a></div><div class="desc docblock-short">Reads the entire contents of a file into a bytes vector.</div></li><li><div class="item-name"><a class="fn" href="fn.read_dir.html" title="fn tokio::fs::read_dir">read_<wbr>dir</a></div><div class="desc docblock-short">Returns a stream over the entries within a directory.</div></li><li><div class="item-name"><a class="fn" href="fn.read_link.html" title="fn tokio::fs::read_link">read_<wbr>link</a></div><div class="desc docblock-short">Reads a symbolic link, returning the file that the link points to.</div></li><li><div class="item-name"><a class="fn" href="fn.read_to_string.html" title="fn tokio::fs::read_to_string">read_<wbr>to_<wbr>string</a></div><div class="desc docblock-short">Creates a future which will open a file for reading and read the entire
contents into a string and return said string.</div></li><li><div class="item-name"><a class="fn" href="fn.remove_dir.html" title="fn tokio::fs::remove_dir">remove_<wbr>dir</a></div><div class="desc docblock-short">Removes an existing, empty directory.</div></li><li><div class="item-name"><a class="fn" href="fn.remove_dir_all.html" title="fn tokio::fs::remove_dir_all">remove_<wbr>dir_<wbr>all</a></div><div class="desc docblock-short">Removes a directory at this path, after removing all its contents. Use carefully!</div></li><li><div class="item-name"><a class="fn" href="fn.remove_file.html" title="fn tokio::fs::remove_file">remove_<wbr>file</a></div><div class="desc docblock-short">Removes a file from the filesystem.</div></li><li><div class="item-name"><a class="fn" href="fn.rename.html" title="fn tokio::fs::rename">rename</a></div><div class="desc docblock-short">Renames a file or directory to a new name, replacing the original file if
<code>to</code> already exists.</div></li><li><div class="item-name"><a class="fn" href="fn.set_permissions.html" title="fn tokio::fs::set_permissions">set_<wbr>permissions</a></div><div class="desc docblock-short">Changes the permissions found on a file or a directory.</div></li><li><div class="item-name"><a class="fn" href="fn.symlink.html" title="fn tokio::fs::symlink">symlink</a></div><div class="desc docblock-short">Creates a new symbolic link on the filesystem.</div></li><li><div class="item-name"><a class="fn" href="fn.symlink_metadata.html" title="fn tokio::fs::symlink_metadata">symlink_<wbr>metadata</a></div><div class="desc docblock-short">Queries the file system metadata for a path.</div></li><li><div class="item-name"><a class="fn" href="fn.try_exists.html" title="fn tokio::fs::try_exists">try_<wbr>exists</a></div><div class="desc docblock-short">Returns <code>Ok(true)</code> if the path points at an existing entity.</div></li><li><div class="item-name"><a class="fn" href="fn.write.html" title="fn tokio::fs::write">write</a></div><div class="desc docblock-short">Creates a future that will open a file for writing and write the entire
contents of <code>contents</code> to it.</div></li></ul></section></div></main></body></html>