txt: ## io-guide.md
  Input/Output the definitive guide
  
  Correctly use Raku IO
  
  # [The basics](#Input/Output_the_definitive_guide "go to top of document")[§](#The_basics "direct link")
  
  The vast majority of common IO work is done by the [`IO::Path`](/type/IO/Path) type. If you want to read from or write to a file in some form or shape, this is the class you want. It abstracts away the details of filehandles (or "file descriptors") and so you mostly don't even have to think about them.
  
  Behind the scenes, [`IO::Path`](/type/IO/Path) works with [`IO::Handle`](/type/IO/Handle), a class which you can use directly if you need a bit more control than what [`IO::Path`](/type/IO/Path) provides. When working with other processes, e.g. via [`Proc`](/type/Proc) or [`Proc::Async`](/type/Proc/Async) types, you'll also be dealing with a *subclass* of [`IO::Handle`](/type/IO/Handle): the [`IO::Pipe`](/type/IO/Pipe).
  
  Lastly, you have the [`IO::CatHandle`](/type/IO/CatHandle), as well as [`IO::Spec`](/type/IO/Spec) and its subclasses, that you'll rarely, if ever, use directly. These classes give you advanced features, such as operating on multiple files as one handle, or low-level path manipulations.
  
  Along with all these classes, Raku provides several subroutines that let you indirectly work with these classes. These come in handy if you like functional programming style or in Raku one liners.
  
  While [`IO::Socket`](/type/IO/Socket) and its subclasses also have to do with Input and Output, this guide does not cover them.
  
  # [Navigating paths](#Input/Output_the_definitive_guide "go to top of document")[§](#Navigating_paths "direct link")
  
  ## [What's an IO::Path anyway?](#Input/Output_the_definitive_guide "go to top of document")[§](#What's_an_IO::Path_anyway? "direct link")
  
  To represent paths as either files or directories, use [`IO::Path`](/type/IO/Path) type. The simplest way to obtain an object of that type is to coerce a [`Str`](/type/Str) by calling the [`.IO`](/routine/IO) method on it:
  
  ```raku
  say 'my-file.txt'.IO; # OUTPUT: «"my-file.txt".IO␤»
  ```
  
  It may seem like something is missing here—there is no volume or absolute path involved—but that information is actually present in the object. You can see it by using [`.raku`](/routine/raku) method:
  
  ```raku
  say 'my-file.txt'.IO.raku;
  # OUTPUT: «IO::Path.new("my-file.txt", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))␤»
  ```
  
  The two extra attributes—`SPEC` and `CWD`—specify what type of operating system semantics the path should use as well as the "current working directory" for the path, i.e. if it's a relative path, then it's relative to that directory.
  
  This means that regardless of how you made one, an [`IO::Path`](/type/IO/Path) object technically always refers to an absolute path. This is why its [`.absolute`](/routine/absolute) and [`.relative`](/routine/relative) methods return [`Str`](/type/Str) objects and they are the correct way to stringify a path.
  
  However, don't be in a rush to stringify anything. Pass paths around as [`IO::Path`](/type/IO/Path) objects. All the routines that operate on paths can handle them, so there's no need to convert them.
  
  ## [Path parts](#Input/Output_the_definitive_guide "go to top of document")[§](#Path_parts "direct link")
  
  Given a local file name, it's very easy to get its components. For example, we have a file, "financial.data", in some directory, "/usr/local/data". Use Raku to analyze its path:
  
  ```raku
  my $fname = "financial.data";
  # Stringify the full path name
  my $f = $fname.IO.absolute;
  say $f;
  #   OUTPUT: «/usr/local/data/financial.data␤»
  # Stringify the path's parts:
  say $f.IO.dirname;                       # OUTPUT: «/usr/local/data␤»
  say $f.IO.basename;                      # OUTPUT: «financial.data␤»
  # And the basename's parts:
  # Use a method for the extension:
  say $f.IO.extension;                     # OUTPUT: «data␤»
  # Remove the extension by redefining it:
  say ($f.IO.extension("")).IO.basename;   # OUTPUT: «financial␤»
  
  ```
  
  ## [Working with files](#Input/Output_the_definitive_guide "go to top of document")[§](#Working_with_files "direct link")
  
  ### [Writing into files](#Input/Output_the_definitive_guide "go to top of document")[§](#Writing_into_files "direct link")
  
  #### [Writing new content](#Input/Output_the_definitive_guide "go to top of document")[§](#Writing_new_content "direct link")
  
  Let's make some files and write and read data from them! The [`spurt`](/routine/spurt) and [`slurp`](/routine/slurp) routines write and read the data in one chunk respectively. Unless you're working with very large files that are difficult to store entirely in memory all at the same time, these two routines are for you.
  
  ```raku
  "my-file.txt".IO.spurt: "I ♥ Raku!";
  
  ```
  
  The code above creates a file named `my-file.txt` in the current directory and then writes text `I ♥ Raku!` into it. If Raku is your first language, celebrate your accomplishment! Try to open the file you created with a text editor to verify what you wrote with your program. If you already know some other language, you may be wondering if this guide missed anything like handling encoding or error conditions.
  
  However, that is all the code you need. The string will be encoded in `utf-8` encoding by default and the errors are handled via the [`Failure`](/type/Failure) mechanism: these are exceptions you can handle using regular conditionals. In this case, we're letting all potential [`Failure`](/type/Failure)s get sunk after the call and so any [`Exceptions`](/type/Exception) they contain will be thrown.
  
  #### [Appending content](#Input/Output_the_definitive_guide "go to top of document")[§](#Appending_content "direct link")
  
  If you wanted to add more content to the file we created in the previous section, you could note the [`spurt` documentation](/routine/spurt) mentions `:append` as one of its argument options. However, for finer control, let's get ourselves an [`IO::Handle`](/type/IO/Handle) to work with:
  
  ```raku
  my $fh = 'my-file.txt'.IO.open: :a;
  $fh.print: "I count: ";
  $fh.print: "$_ " for ^10;
  $fh.close;
  
  ```
  
  The [`.open`](/routine/open) method call opens our [`IO::Path`](/type/IO/Path) and returns an [`IO::Handle`](/type/IO/Handle). We passed `:a` as argument, to indicate we want to open the file for writing in append mode.
  
  In the next two lines of code, we use the usual [`.print`](/routine/print) method on that [`IO::Handle`](/type/IO/Handle) to print a line with 11 pieces of text (the `'I count: '` string and 10 numbers). Note that, once again, [`Failure`](/type/Failure) mechanism takes care of all the error checking for us. If the [`.open`](/routine/open) fails, it returns a [`Failure`](/type/Failure), which will throw when we attempt to call method the [`.print`](/routine/print) on it.
  
  Finally, we close the [`IO::Handle`](/type/IO/Handle) by calling the [`.close`](/routine/close) method on it. It is *important that you do it*, especially in large programs or ones that deal with a lot of files, as many systems have limits to how many files a program can have open at the same time. If you don't close your handles, eventually you'll reach that limit and the [`.open`](/routine/open) call will fail. Note that unlike some other languages, Raku does not use reference counting, so the filehandles **are NOT closed** when the scope they're defined in is left. They will be closed only when they're garbage collected and failing to close the handles may cause your program to reach the file limit *before* the open handles get a chance to get garbage collected.
  
  ### [Reading from files](#Input/Output_the_definitive_guide "go to top of document")[§](#Reading_from_files "direct link")
  
  #### [Using IO::Path](#Input/Output_the_definitive_guide "go to top of document")[§](#Using_IO::Path "direct link")
  
  We've seen in previous sections that writing stuff to files is a single-line of code in Raku. Reading from them, is similarly easy:
  
  ```raku
  say 'my-file.txt'.IO.slurp;        # OUTPUT: «I ♥ Raku!␤»
  say 'my-file.txt'.IO.slurp: :bin;  # OUTPUT: «Buf[uint8]:0x<49 20 E2 99 A5 20 52 61 6B 75 21>␤»
  
  ```
  
  The [`.slurp`](/routine/slurp) method reads entire contents of the file and returns them as a single [`Str`](/type/Str) object, or as a [`Buf`](/type/Buf) object, if binary mode was requested, by specifying `:bin` named argument.
  
  Since [slurping](/routine/slurp) loads the entire file into memory, it's not ideal for working with huge files.
  
  The [`IO::Path`](/type/IO/Path) type offers two other handy methods: [`.words`](/type/IO/Path#method_words) and [`.lines`](/type/IO/Path#method_lines) that lazily read the file in smaller chunks and return [`Seq`](/type/Seq) objects that (by default) don't keep already-consumed values around.
  
  Here's an example that finds lines in a text file that mention Raku and prints them out. Despite the file itself being too large to fit into available [RAM](https://en.wikipedia.org/wiki/Random-access_memory), the program will not have any issues running, as the contents are processed in small chunks:
  
  ```raku
  .say for '500-PetaByte-File.txt'.IO.lines.grep: *.contains: 'Raku';
  
  ```
  
  Here's another example that prints the first 100 words from a file, without loading it entirely:
  
  ```raku
  .say for '500-PetaByte-File.txt'.IO.words: 100
  
  ```
  
  Note that we did this by passing a limit argument to [`.words`](/type/IO/Path#method_words) instead of, say, using [a list indexing operation](/language/operators#index-entry-array_indexing_operator-array_subscript_operator-array_indexing_operator). The reason for that is there's still a filehandle in use under the hood, and until you fully consume the returned [`Seq`](/type/Seq), the handle will remain open. If nothing references the [`Seq`](/type/Seq), eventually the handle will get closed, during a garbage collection run, but in large programs that work with a lot of files, it's best to ensure all the handles get closed right away. So, you should always ensure the [`Seq`](/type/Seq) from [`IO::Path`](/type/IO/Path)'s [`.words`](/type/IO/Path#method_words) and [`.lines`](/type/IO/Path#method_lines) methods is [fully reified](/language/glossary#Reify); and the limit argument is there to help you with that.
  
  #### [Using IO::Handle](#Input/Output_the_definitive_guide "go to top of document")[§](#Using_IO::Handle "direct link")
  
  You can read from files using the [`IO::Handle`](/type/IO/Handle) type; this gives you a finer control over the process.
  
  ```raku
  given 'some-file.txt'.IO.open {
      say .readchars: 8;  # OUTPUT: «I ♥ Raku␤»
      .seek: 1, SeekFromCurrent;
      say .readchars: 15;  # OUTPUT: «I ♥ Programming␤»
      .close
  }
  
  ```
  
  The [`IO::Handle`](/type/IO/Handle) gives you [.read](/type/IO/Handle#method_read), [.readchars](/type/IO/Handle#method_readchars), [.get](/type/IO/Handle#routine_get), [.getc](/type/IO/Handle#routine_getc), [.words](/type/IO/Handle#routine_words), [.lines](/type/IO/Handle#routine_lines), [.slurp](/type/IO/Handle#method_slurp), [.comb](/type/IO/Handle#method_comb), [.split](/type/IO/Handle#method_split), and [.Supply](/type/IO/Handle#method_Supply) methods to read data from it. Plenty of options; and the catch is you need to close the handle when you're done with it.
  
  Unlike some languages, the handle won't get automatically closed when the scope it's defined in is left. Instead, it'll remain open until it's garbage collected. To make the closing business easier, some of the methods let you specify a `:close` argument, you can also use the [`will leave` trait](/language/phasers#index-entry-will_trait), or the `does auto-close` trait provided by the [`Trait::IO`](https://raku.land/zef:raku-community-modules/Trait::IO) module.
  
  # [The wrong way to do things](#Input/Output_the_definitive_guide "go to top of document")[§](#The_wrong_way_to_do_things "direct link")
  
  This section describes how NOT to do Raku IO.
  
  ## [Leave $\*SPEC alone](#Input/Output_the_definitive_guide "go to top of document")[§](#Leave_$*SPEC_alone "direct link")
  
  You may have heard of [`$*SPEC`](/language/variables#Dynamic_variables) and seen some code or books show its usage for splitting and joining path fragments. Some of the routine names it provides may even look familiar to what you've used in other languages.
  
  However, unless you're writing your own IO framework, you almost never need to use [`$*SPEC`](/language/variables#Dynamic_variables) directly. [`$*SPEC`](/language/variables#Dynamic_variables) provides low-level stuff and its use will not only make your code tough to read, you'll likely introduce security issues (e.g. null characters)!
  
  The [`IO::Path`](/type/IO/Path) type is the workhorse of Raku world. It caters to all the path manipulation needs as well as provides shortcut routines that let you avoid dealing with filehandles. Use that instead of the [`$*SPEC`](/language/variables#Dynamic_variables) stuff.
  
  Tip: you can join path parts with `/` and feed them to [`IO::Path`](/type/IO/Path)'s routines; they'll still do The Right Thing™ with them, regardless of the operating system.
  
  ```raku
  # WRONG!! TOO MUCH WORK!
  my $fh = open $*SPEC.catpath: '', 'foo/bar', $file;
  my $data = $fh.slurp;
  $fh.close;
  
  ```
  
  ```raku
  # RIGHT! Use IO::Path to do all the dirty work
  my $data = 'foo/bar'.IO.add($file).slurp;
  
  ```
  
  However, it's fine to use it for things not otherwise provided by [`IO::Path`](/type/IO/Path). For example, the [`.devnull` method](/routine/devnull):
  
  ```raku
  {
      temp $*OUT = open :w, $*SPEC.devnull;
      say "In space no one can hear you scream!";
  }
  say "Hello";
  
  ```
  
  ## [Stringifying IO::Path](#Input/Output_the_definitive_guide "go to top of document")[§](#Stringifying_IO::Path "direct link")
  
  Don't use the `.Str` method to stringify [`IO::Path`](/type/IO/Path) objects, unless you just want to display them somewhere for information purposes or something. The `.Str` method returns whatever basic path string the [`IO::Path`](/type/IO/Path) was instantiated with. It doesn't consider the value of the [`$.CWD` attribute](/type/IO/Path#attribute_CWD). For example, this code is broken:
  
  ```raku
  my $path = 'foo'.IO;
  chdir 'bar';
  # WRONG!! .Str DOES NOT USE $.CWD!
  run <tar -cvvf archive.tar>, $path.Str;
  
  ```
  
  The [`chdir`](/routine/chdir) call changed the value of the current directory, but the `$path` we created is relative to the directory before that change.
  
  However, the [`IO::Path`](/type/IO/Path) object *does* know what directory it's relative to. We just need to use [`.absolute`](/routine/absolute) or [`.relative`](/routine/relative) to stringify the object. Both routines return a [`Str`](/type/Str) object; they only differ in whether the result is an absolute or relative path. So, we can fix our code like this:
  
  ```raku
  my $path = 'foo'.IO;
  chdir 'bar';
  # RIGHT!! .absolute does consider the value of $.CWD!
  run <tar -cvvf archive.tar>, $path.absolute;
  # Also good:
  run <tar -cvvf archive.tar>, $path.relative;
  
  ```
  
  ## [Be mindful of $\*CWD](#Input/Output_the_definitive_guide "go to top of document")[§](#Be_mindful_of_$*CWD "direct link")
  
  While usually out of view, every [`IO::Path`](/type/IO/Path) object, by default, uses the current value of [`$*CWD`](/language/variables#Dynamic_variables) to set its [`$.CWD` attribute](/type/IO/Path#attribute_CWD). This means there are two things to pay attention to.
  
  ### [temp the $\*CWD](#Input/Output_the_definitive_guide "go to top of document")[§](#temp_the_$*CWD "direct link")
  
  This code is a mistake:
  
  ```raku
  # WRONG!!
  my $*CWD = "foo".IO;
  
  ```
  
  The `my $*CWD` made [`$*CWD`](/language/variables#Dynamic_variables) undefined. The [`.IO`](/routine/IO) coercer then goes ahead and sets the [`$.CWD` attribute](/type/IO/Path#attribute_CWD) of the path it's creating to the stringified version of the undefined `$*CWD`; an empty string.
  
  The correct way to perform this operation is use [`temp`](/routine/temp) instead of `my`. It'll localize the effect of changes to [`$*CWD`](/language/variables#Dynamic_variables), just like `my` would, but it won't make it undefined, so the [`.IO`](/routine/IO) coercer will still get the correct old value:
  
  ```raku
  temp $*CWD = "foo".IO;
  
  ```
  
  Better yet, if you want to perform some code in a localized [`$*CWD`](/language/variables#Dynamic_variables), use the [`indir` routine](/routine/indir) for that purpose.
  