github.com/gogf/gf@v1.16.9/os/gfile/gfile_contents.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gfile
     8  
     9  import (
    10  	"bufio"
    11  	"io"
    12  	"io/ioutil"
    13  	"os"
    14  )
    15  
    16  var (
    17  	// DefaultReadBuffer is the buffer size for reading file content.
    18  	DefaultReadBuffer = 1024
    19  )
    20  
    21  // GetContents returns the file content of <path> as string.
    22  // It returns en empty string if it fails reading.
    23  func GetContents(path string) string {
    24  	return string(GetBytes(path))
    25  }
    26  
    27  // GetBytes returns the file content of <path> as []byte.
    28  // It returns nil if it fails reading.
    29  func GetBytes(path string) []byte {
    30  	data, err := ioutil.ReadFile(path)
    31  	if err != nil {
    32  		return nil
    33  	}
    34  	return data
    35  }
    36  
    37  // putContents puts binary content to file of <path>.
    38  func putContents(path string, data []byte, flag int, perm os.FileMode) error {
    39  	// It supports creating file of <path> recursively.
    40  	dir := Dir(path)
    41  	if !Exists(dir) {
    42  		if err := Mkdir(dir); err != nil {
    43  			return err
    44  		}
    45  	}
    46  	// Opening file with given <flag> and <perm>.
    47  	f, err := OpenWithFlagPerm(path, flag, perm)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	defer f.Close()
    52  	if n, err := f.Write(data); err != nil {
    53  		return err
    54  	} else if n < len(data) {
    55  		return io.ErrShortWrite
    56  	}
    57  	return nil
    58  }
    59  
    60  // Truncate truncates file of <path> to given size by <size>.
    61  func Truncate(path string, size int) error {
    62  	return os.Truncate(path, int64(size))
    63  }
    64  
    65  // PutContents puts string <content> to file of <path>.
    66  // It creates file of <path> recursively if it does not exist.
    67  func PutContents(path string, content string) error {
    68  	return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, DefaultPermOpen)
    69  }
    70  
    71  // PutContentsAppend appends string <content> to file of <path>.
    72  // It creates file of <path> recursively if it does not exist.
    73  func PutContentsAppend(path string, content string) error {
    74  	return putContents(path, []byte(content), os.O_WRONLY|os.O_CREATE|os.O_APPEND, DefaultPermOpen)
    75  }
    76  
    77  // PutBytes puts binary <content> to file of <path>.
    78  // It creates file of <path> recursively if it does not exist.
    79  func PutBytes(path string, content []byte) error {
    80  	return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, DefaultPermOpen)
    81  }
    82  
    83  // PutBytesAppend appends binary <content> to file of <path>.
    84  // It creates file of <path> recursively if it does not exist.
    85  func PutBytesAppend(path string, content []byte) error {
    86  	return putContents(path, content, os.O_WRONLY|os.O_CREATE|os.O_APPEND, DefaultPermOpen)
    87  }
    88  
    89  // GetNextCharOffset returns the file offset for given <char> starting from <start>.
    90  func GetNextCharOffset(reader io.ReaderAt, char byte, start int64) int64 {
    91  	buffer := make([]byte, DefaultReadBuffer)
    92  	offset := start
    93  	for {
    94  		if n, err := reader.ReadAt(buffer, offset); n > 0 {
    95  			for i := 0; i < n; i++ {
    96  				if buffer[i] == char {
    97  					return int64(i) + offset
    98  				}
    99  			}
   100  			offset += int64(n)
   101  		} else if err != nil {
   102  			break
   103  		}
   104  	}
   105  	return -1
   106  }
   107  
   108  // GetNextCharOffsetByPath returns the file offset for given <char> starting from <start>.
   109  // It opens file of <path> for reading with os.O_RDONLY flag and default perm.
   110  func GetNextCharOffsetByPath(path string, char byte, start int64) int64 {
   111  	if f, err := OpenWithFlagPerm(path, os.O_RDONLY, DefaultPermOpen); err == nil {
   112  		defer f.Close()
   113  		return GetNextCharOffset(f, char, start)
   114  	}
   115  	return -1
   116  }
   117  
   118  // GetBytesTilChar returns the contents of the file as []byte
   119  // until the next specified byte <char> position.
   120  //
   121  // Note: Returned value contains the character of the last position.
   122  func GetBytesTilChar(reader io.ReaderAt, char byte, start int64) ([]byte, int64) {
   123  	if offset := GetNextCharOffset(reader, char, start); offset != -1 {
   124  		return GetBytesByTwoOffsets(reader, start, offset+1), offset
   125  	}
   126  	return nil, -1
   127  }
   128  
   129  // GetBytesTilCharByPath returns the contents of the file given by <path> as []byte
   130  // until the next specified byte <char> position.
   131  // It opens file of <path> for reading with os.O_RDONLY flag and default perm.
   132  //
   133  // Note: Returned value contains the character of the last position.
   134  func GetBytesTilCharByPath(path string, char byte, start int64) ([]byte, int64) {
   135  	if f, err := OpenWithFlagPerm(path, os.O_RDONLY, DefaultPermOpen); err == nil {
   136  		defer f.Close()
   137  		return GetBytesTilChar(f, char, start)
   138  	}
   139  	return nil, -1
   140  }
   141  
   142  // GetBytesByTwoOffsets returns the binary content as []byte from <start> to <end>.
   143  // Note: Returned value does not contain the character of the last position, which means
   144  // it returns content range as [start, end).
   145  func GetBytesByTwoOffsets(reader io.ReaderAt, start int64, end int64) []byte {
   146  	buffer := make([]byte, end-start)
   147  	if _, err := reader.ReadAt(buffer, start); err != nil {
   148  		return nil
   149  	}
   150  	return buffer
   151  }
   152  
   153  // GetBytesByTwoOffsetsByPath returns the binary content as []byte from <start> to <end>.
   154  // Note: Returned value does not contain the character of the last position, which means
   155  // it returns content range as [start, end).
   156  // It opens file of <path> for reading with os.O_RDONLY flag and default perm.
   157  func GetBytesByTwoOffsetsByPath(path string, start int64, end int64) []byte {
   158  	if f, err := OpenWithFlagPerm(path, os.O_RDONLY, DefaultPermOpen); err == nil {
   159  		defer f.Close()
   160  		return GetBytesByTwoOffsets(f, start, end)
   161  	}
   162  	return nil
   163  }
   164  
   165  // ReadLines reads file content line by line, which is passed to the callback function <callback> as string.
   166  // It matches each line of text, separated by chars '\r' or '\n', stripped any trailing end-of-line marker.
   167  //
   168  // Note that the parameter passed to callback function might be an empty value, and the last non-empty line
   169  // will be passed to callback function <callback> even if it has no newline marker.
   170  func ReadLines(file string, callback func(text string) error) error {
   171  	f, err := os.Open(file)
   172  	if err != nil {
   173  		return err
   174  	}
   175  	defer f.Close()
   176  
   177  	scanner := bufio.NewScanner(f)
   178  	for scanner.Scan() {
   179  		if err = callback(scanner.Text()); err != nil {
   180  			return err
   181  		}
   182  	}
   183  	return nil
   184  }
   185  
   186  // ReadByteLines reads file content line by line, which is passed to the callback function <callback> as []byte.
   187  // It matches each line of text, separated by chars '\r' or '\n', stripped any trailing end-of-line marker.
   188  //
   189  // Note that the parameter passed to callback function might be an empty value, and the last non-empty line
   190  // will be passed to callback function <callback> even if it has no newline marker.
   191  //
   192  // Deprecated, use ReadLinesBytes instead.
   193  func ReadByteLines(file string, callback func(bytes []byte) error) error {
   194  	return ReadLinesBytes(file, callback)
   195  }
   196  
   197  // ReadLinesBytes reads file content line by line, which is passed to the callback function <callback> as []byte.
   198  // It matches each line of text, separated by chars '\r' or '\n', stripped any trailing end-of-line marker.
   199  //
   200  // Note that the parameter passed to callback function might be an empty value, and the last non-empty line
   201  // will be passed to callback function <callback> even if it has no newline marker.
   202  func ReadLinesBytes(file string, callback func(bytes []byte) error) error {
   203  	f, err := os.Open(file)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	defer f.Close()
   208  
   209  	scanner := bufio.NewScanner(f)
   210  	for scanner.Scan() {
   211  		if err = callback(scanner.Bytes()); err != nil {
   212  			return err
   213  		}
   214  	}
   215  	return nil
   216  }