storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/ioutil/read_file.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2021 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  // Forked from golang.org/pkg/os.ReadFile with NOATIME support.
    18  // Copyright 2009 The Go Authors. All rights reserved.
    19  // Use of this source code is governed by a BSD-style
    20  // license that can be found in the LICENSE file.
    21  
    22  package ioutil
    23  
    24  import (
    25  	"io"
    26  	"os"
    27  )
    28  
    29  // ReadFile reads the named file and returns the contents.
    30  // A successful call returns err == nil, not err == EOF.
    31  // Because ReadFile reads the whole file, it does not treat an EOF from Read
    32  // as an error to be reported.
    33  //
    34  // passes NOATIME flag for reads on Unix systems to avoid atime updates.
    35  func ReadFile(name string) ([]byte, error) {
    36  	f, err := os.OpenFile(name, readMode, 0)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	defer f.Close()
    41  
    42  	var size int
    43  	if info, err := f.Stat(); err == nil {
    44  		size64 := info.Size()
    45  		if int64(int(size64)) == size64 {
    46  			size = int(size64)
    47  		}
    48  	}
    49  	size++ // one byte for final read at EOF
    50  
    51  	// If a file claims a small size, read at least 512 bytes.
    52  	// In particular, files in Linux's /proc claim size 0 but
    53  	// then do not work right if read in small pieces,
    54  	// so an initial read of 1 byte would not work correctly.
    55  	if size < 512 {
    56  		size = 512
    57  	}
    58  
    59  	data := make([]byte, 0, size)
    60  	for {
    61  		if len(data) >= cap(data) {
    62  			d := append(data[:cap(data)], 0)
    63  			data = d[:len(data)]
    64  		}
    65  		n, err := f.Read(data[len(data):cap(data)])
    66  		data = data[:len(data)+n]
    67  		if err != nil {
    68  			if err == io.EOF {
    69  				err = nil
    70  			}
    71  			return data, err
    72  		}
    73  	}
    74  }