// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package ioutil implements some I/O utility functions. package ioutil import ( "io" "io/fs" "os" "sort" ) // ReadAll reads from r until an error or EOF and returns the data it read. // A successful call returns err == nil, not err == EOF. Because ReadAll is // defined to read from src until EOF, it does not treat an EOF from Read // as an error to be reported. // // As of Go 1.16, this function simply calls io.ReadAll. func ReadAll(r io.Reader) ([]byte, error) { return io.ReadAll(r) } // ReadFile reads the file named by filename and returns the contents. // A successful call returns err == nil, not err == EOF. Because ReadFile // reads the whole file, it does not treat an EOF from Read as an error // to be reported. func ReadFile(filename string) ([]byte, error) { f, err := os.Open(filename) if err != nil { return nil, err } defer f.Close() // It's a good but not certain bet that FileInfo will tell us exactly how much to // read, so let's try it but be prepared for the answer to be wrong. const minRead = 512 var n int64 = minRead if fi, err := f.Stat(); err == nil { // As initial capacity for readAll, use Size + a little extra in case Size // is zero, and to avoid another allocation after Read has filled the // buffer. The readAll call will read into its allocated internal buffer // cheaply. If the size was wrong, we'll either waste some space off the end // or reallocate as needed, but in the overwhelmingly common case we'll get // it just right. if size := fi.Size() + minRead; size > n { n = size } } if int64(int(n)) != n { n = minRead } b := make([]byte, 0, n) for { if len(b) == cap(b) { // Add more capacity (let append pick how much). b = append(b, 0)[:len(b)] } n, err := f.Read(b[len(b):cap(b)]) b = b[:len(b)+n] if err != nil { if err == io.EOF { err = nil } return b, err } } } // WriteFile writes data to a file named by filename. // If the file does not exist, WriteFile creates it with permissions perm // (before umask); otherwise WriteFile truncates it before writing, without changing permissions. func WriteFile(filename string, data []byte, perm fs.FileMode) error { f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err } _, err = f.Write(data) if err1 := f.Close(); err == nil { err = err1 } return err } // ReadDir reads the directory named by dirname and returns // a list of directory entries sorted by filename. func ReadDir(dirname string) ([]fs.FileInfo, error) { f, err := os.Open(dirname) if err != nil { return nil, err } list, err := f.Readdir(-1) f.Close() if err != nil { return nil, err } sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) return list, nil } // NopCloser returns a ReadCloser with a no-op Close method wrapping // the provided Reader r. // // As of Go 1.16, this function simply calls io.NopCloser. func NopCloser(r io.Reader) io.ReadCloser { return io.NopCloser(r) } // Discard is an io.Writer on which all Write calls succeed // without doing anything. // // As of Go 1.16, this value is simply io.Discard. var Discard io.Writer = io.Discard