Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Go Programming Cookbook

You're reading from   Go Programming Cookbook Over 85 recipes to build modular, readable, and testable Golang applications across various domains

Arrow left icon
Product type Paperback
Published in Jul 2019
Publisher Packt
ISBN-13 9781789800982
Length 434 pages
Edition 2nd Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Aaron Torres Aaron Torres
Author Profile Icon Aaron Torres
Aaron Torres
Arrow right icon
View More author details
Toc

Table of Contents (16) Chapters Close

Preface 1. I/O and Filesystems FREE CHAPTER 2. Command-Line Tools 3. Data Conversion and Composition 4. Error Handling in Go 5. Network Programming 6. All about Databases and Storage 7. Web Clients and APIs 8. Microservices for Applications in Go 9. Testing Go Code 10. Parallelism and Concurrency 11. Distributed Systems 12. Reactive Programming and Data Streams 13. Serverless Programming 14. Performance Improvements, Tips, and Tricks 15. Other Books You May Enjoy

Working with directories and files

Working with directories and files can be difficult when you switch between platforms (Windows and Linux, for example). Go provides cross-platform support to work with files and directories in the os and ioutils packages. We've already seen examples of ioutils, but now we'll explore how to use them in another way!

How to do it...

The following steps cover how to write and run your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter1/filedirs.
  2. Navigate to this directory.
  1. Run the following command:
          $ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/filedirs

You should see a file called go.mod that contains the following contents:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/filedirs
  1. Copy tests from~/projects/go-programming-cookbook-original/chapter1/filedirs or use this as an exercise to write some of your own code!
  2. Create a file called dirs.go with the following contents:
        package filedirs

import (
"errors"
"io"
"os"
)

// Operate manipulates files and directories
func Operate() error {
// this 0755 is similar to what you'd see with Chown
// on a command line this will create a director
// /tmp/example, you may also use an absolute path
// instead of a relative one
if err := os.Mkdir("example_dir", os.FileMode(0755));
err != nil {
return err
}

// go to the /tmp directory
if err := os.Chdir("example_dir"); err != nil {
return err
}

// f is a generic file object
// it also implements multiple interfaces
// and can be used as a reader or writer
// if the correct bits are set when opening
f, err := os.Create("test.txt")
if err != nil {
return err
}

// we write a known-length value to the file and
// validate that it wrote correctly
value := []byte("hellon")
count, err := f.Write(value)
if err != nil {
return err
}
if count != len(value) {
return errors.New("incorrect length returned
from write")
}

if err := f.Close(); err != nil {
return err
}

// read the file
f, err = os.Open("test.txt")
if err != nil {
return err
}

io.Copy(os.Stdout, f)

if err := f.Close(); err != nil {
return err
}

// go to the /tmp directory
if err := os.Chdir(".."); err != nil {
return err
}

// cleanup, os.RemoveAll can be dangerous if you
// point at the wrong directory, use user input,
// and especially if you run as root
if err := os.RemoveAll("example_dir"); err != nil {
return err
}

return nil
}
  1. Create a file called files.gowith the following contents:
        package filedirs

import (
"bytes"
"io"
"os"
"strings"
)

// Capitalizer opens a file, reads the contents,
// then writes those contents to a second file
func Capitalizer(f1 *os.File, f2 *os.File) error {
if _, err := f1.Seek(0, io.SeekStart); err != nil {
return err
}

var tmp = new(bytes.Buffer)

if _, err := io.Copy(tmp, f1); err != nil {
return err
}

s := strings.ToUpper(tmp.String())

if _, err := io.Copy(f2, strings.NewReader(s)); err !=
nil {
return err
}
return nil
}

// CapitalizerExample creates two files, writes to one
//then calls Capitalizer() on both
func CapitalizerExample() error {
f1, err := os.Create("file1.txt")
if err != nil {
return err
}

if _, err := f1.Write([]byte(`this file contains a
number of words and new lines`)); err != nil {
return err
}

f2, err := os.Create("file2.txt")
if err != nil {
return err
}

if err := Capitalizer(f1, f2); err != nil {
return err
}

if err := os.Remove("file1.txt"); err != nil {
return err
}

if err := os.Remove("file2.txt"); err != nil {
return err
}

return nil
}
  1. Create a new directory named example and navigate to it.
  1. Create a main.go file with the following contents:
        package main

import "github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter1/filedirs"

func main() {
if err := filedirs.Operate(); err != nil {
panic(err)
}

if err := filedirs.CapitalizerExample(); err != nil {
panic(err)
}
}
  1. Run go run ..
  2. You may also run the following:
          $ go build
$ ./example

You should see the following output:

          $ go run . 
          
hello
  1. If you copied or wrote your own tests, go up one directory and run go test, and ensure that all tests pass.

How it works...

If you're familiar with files in Unix, the Go os library should feel very familiar. You can perform basically all common operations—Stat a file to collect attributes, collect a file with different permissions, and create and modify directories and files. In this recipe, we performed a number of manipulations to directories and files and then cleaned up after ourselves.

Working with file objects is very similar to working with in-memory streams. Files also provide a number of convenience functions directly, such as Chown, Stat, and Truncate. The easiest way to get comfortable with files is to make use of them. In all the previous recipes, we have to be careful to clean up after our programs.

Working with files is a very common operation when building backend applications. Files can be used for configuration, secret keys, as temporary storage, and more. Go wraps OS system calls using the os package and allows the same functions to operate regardless of whether you're using Windows or Unix.

Once your file is opened and stored in a File structure, it can easily be passed into a number of interfaces (we discussed these interfaces earlier). All the earlier examples can use os.File structures directly instead of buffers and in-memory data streams in order to operate on data stored on the disk . This may be useful for certain techniques, such as writing all logs to stderr and the file at the same time with a single write call.

You have been reading a chapter from
Go Programming Cookbook - Second Edition
Published in: Jul 2019
Publisher: Packt
ISBN-13: 9781789800982
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at ₹800/month. Cancel anytime