<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>Now that we are using Rust on the computer, we can start working with files. You will notice that now we will start to see more and more <code>Result</code>s in our code. That is because once you start working with files and similar things, many things can go wrong. A file might not be there, or maybe the computer can't read it.</p>
<p>You might remember that if you want to use the <code>?</code> operator, it has to return a <code>Result</code> in the function it is in. If you can't remember the error type, you can just give it nothing and let the compiler tell you. Let's try that with a function that tries to make a number with <code>.parse()</code>.</p>
<p>So now we want to use <code>?</code> to just give us the value if it works, and the error if it doesn't. But how to do this in <code>fn main()</code>? If we try to use <code>?</code> in main, it won't work.</p>
<pre><codeclass="language-text">error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
<p>But actually <code>main()</code> can return a <code>Result</code>, just like any other function. If our function works, we don't want to return anything (main() isn't giving anything to anything else). And if it doesn't work, we will return the same error. So we can write it like this:</p>
<p>Don't forget the <code>Ok(())</code> at the end: this is very common in Rust. It means <code>Ok</code>, inside of which is <code>()</code>, which is our return value. Now it prints:</p>
<p>This wasn't very useful when just using <code>.parse()</code>, but it will be with files. That's because <code>?</code> also changes error types for us. Here's what <ahref="https://doc.rust-lang.org/std/macro.try.html">the page for the ? operator</a> says in simple English:</p>
<pre><codeclass="language-text">If you get an `Err`, it will get the inner error. Then `?` does a conversion using `From`. With that it can change specialized errors to more general ones. The error it gets is then returned.
</code></pre>
<p>Also, Rust has a convenient <code>Result</code> type when using <code>File</code>s and similar things. It's called <code>std::io::Result</code>, and this is what you usually see in <code>main()</code> when you are using <code>?</code> to open and do things to files. It's actually a type alias. It looks like this:</p>
<p>So it is a <code>Result<T, Error></code>, but we only need to write the <code>Result<T></code> part.</p>
<p>Now let's try working with files for the first time. <code>std::fs</code> is where the methods are for working with files, and with <code>std::io::Write</code> you can write in them. With that we can use <code>.write_all()</code> to write into the file.</p>
<p>Then if you click on the new file <code>myfilename.txt</code>, it will say <code>Let's put this in the file</code>.</p>
<p>We don't need to do this on two lines though, because we have the <code>?</code> operator. It will pass on the result we want if it works, kind of like when you use lots of methods on an iterator. This is when <code>?</code> becomes very convenient.</p>
<p>So this is saying "Please try to create a file and check if it worked. If it did, then use <code>.write_all()</code> and then check if that worked."</p>
<p>And in fact, there is also a function that does both of these things together. It's called <code>std::fs::write</code>. Inside it you give it the file name you want, and the content you want to put inside. Again, careful! It will delete any file that's already there if it has the same name. Also, it lets you write a <code>&str</code> without <code>b</code> in front, because of this:</p>
<p>So that's the file we will use. It's a conversation with a comic book character named Calvin and his dad, who is not serious about his question. With this we can create a file to use every time.</p>
<p>Opening a file is just as easy as creating one. You just use <code>open()</code> instead of <code>create()</code>. After that (if it finds your file), you can do things like <code>read_to_string()</code>. To do that you can create a mutable <code>String</code> and read the file into there. It looks like this:</p>
</span>CALVIN: DAD, HOW COME OLD PHOTOGRAPHS ARE ALWAYS BLACK AND WHITE? DIDN'T THEY HAVE COLOR FILM BACK THEN? DAD: SURE THEY DID. IN
FACT, THOSE PHOTOGRAPHS *ARE* IN COLOR. IT'S JUST THE *WORLD* WAS BLACK AND WHITE THEN. CALVIN: REALLY? DAD: YEP. THE WORLD DIDN'T TURN COLOR UNTIL SOMETIMES IN THE 1930S...
<p>Okay, what if we want to create a file but not do it if there is already another file with the same name? Maybe you don't want to delete the other file if it's already there just to make a new one. To do this, there is a struct called <code>OpenOptions</code>. Actually, we've been using <code>OpenOptions</code> all this time and didn't know it. Take a look at the source for <code>File::open</code>:</p>
<p>If you go to <ahref="https://doc.rust-lang.org/std/fs/struct.OpenOptions.html">the page for OpenOptions</a>, you can see all the methods that you can choose from. Most take a <code>bool</code>:</p>
<ul>
<li><code>append()</code>: This means "add to the content that's already there instead of deleting".</li>
<li><code>create()</code>: This lets <code>OpenOptions</code> create a file.</li>
<li><code>create_new()</code>: This means it will only create a file if it's not there already.</li>
<li><code>read()</code>: Set this to <code>true</code> if you want it to be able to read a file.</li>
<li><code>truncate()</code>: Set this to true if you want to cut the file content to 0 (delete the contents) when you open it.</li>
<li><code>write()</code>: This lets it write to a file.</li>
</ul>
<p>Then at the end you use <code>.open()</code> with the file name, and that will give you a <code>Result</code>. Let's look at one example:</p>
<p>First we made an <code>OpenOptions</code> with <code>new</code> (always start with <code>new</code>). Then we gave it the ability to <code>write</code>. After that we set <code>create_new()</code> to <code>true</code>, and tried to open the file we made. It won't work, which is what we want:</p>
<p>Let's try using <code>.append()</code> so we can write to a file. To write to the file we can use <code>.write_all()</code>, which is a method that tries to write in everything you give it.</p>
<p>Also, we will use the <code>write!</code> macro to do the same thing. You will remember this macro from when we did <code>impl Display</code> for our structs. This time we are using it on a file though instead of a buffer.</p>