github.com/kaydxh/golang@v0.0.131/go/io/io.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package io
    23  
    24  import (
    25  	"bufio"
    26  	"bytes"
    27  	"io"
    28  	"io/ioutil"
    29  	"os"
    30  
    31  	os_ "github.com/kaydxh/golang/go/os"
    32  )
    33  
    34  // ReadFileLines read line from file divide with \n
    35  func ReadFileLines(filepath string) ([]string, error) {
    36  	file, err := os_.OpenAll(filepath, os.O_RDONLY, 0)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	defer file.Close()
    41  
    42  	var lines []string
    43  	scanner := bufio.NewScanner(file)
    44  	scanner.Split(bufio.ScanLines)
    45  	for scanner.Scan() {
    46  		lines = append(lines, scanner.Text())
    47  	}
    48  
    49  	return lines, nil
    50  }
    51  
    52  // ReadLines read line from byteArray divide with \n
    53  func ReadLines(byteArray []byte) []string {
    54  	var lines []string
    55  	index := 0
    56  	readIndex := 0
    57  	for ; readIndex < len(byteArray); index++ {
    58  		line, n := ReadLineAt(readIndex, byteArray)
    59  		readIndex = n
    60  
    61  		lines = append(lines, string(line))
    62  	}
    63  
    64  	return lines
    65  }
    66  
    67  func ReadLineAt(readIndex int, byteArray []byte) ([]byte, int) {
    68  	currentReadIndex := readIndex
    69  
    70  	// consume left spaces
    71  	for currentReadIndex < len(byteArray) {
    72  		if byteArray[currentReadIndex] == ' ' {
    73  			currentReadIndex++
    74  		} else {
    75  			break
    76  		}
    77  	}
    78  
    79  	// leftTrimIndex stores the left index of the line after the line is left-trimmed
    80  	leftTrimIndex := currentReadIndex
    81  
    82  	// rightTrimIndex stores the right index of the line after the line is right-trimmed
    83  	// it is set to -1 since the correct value has not yet been determined.
    84  	rightTrimIndex := -1
    85  
    86  	for ; currentReadIndex < len(byteArray); currentReadIndex++ {
    87  		if byteArray[currentReadIndex] == ' ' {
    88  			// set rightTrimIndex
    89  			if rightTrimIndex == -1 {
    90  				rightTrimIndex = currentReadIndex
    91  			}
    92  		} else if (byteArray[currentReadIndex] == '\n') || (currentReadIndex == (len(byteArray) - 1)) {
    93  			// end of line or byte buffer is reached
    94  			if currentReadIndex <= leftTrimIndex {
    95  				return nil, currentReadIndex + 1
    96  			}
    97  			// set the rightTrimIndex
    98  			if rightTrimIndex == -1 {
    99  				rightTrimIndex = currentReadIndex
   100  				if currentReadIndex == (len(byteArray)-1) && (byteArray[currentReadIndex] != '\n') {
   101  					// ensure that the last character is part of the returned string,
   102  					// unless the last character is '\n'
   103  					rightTrimIndex = currentReadIndex + 1
   104  				}
   105  			}
   106  			// Avoid unnecessary allocation.
   107  			return byteArray[leftTrimIndex:rightTrimIndex], currentReadIndex + 1
   108  		} else {
   109  			// unset rightTrimIndex
   110  			rightTrimIndex = -1
   111  		}
   112  	}
   113  
   114  	return nil, currentReadIndex
   115  }
   116  
   117  //ReadFile read data from file
   118  func ReadFile(filePath string) ([]byte, error) {
   119  	data, err := ioutil.ReadFile(filePath)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	return data, err
   125  }
   126  
   127  func WriteFile(filePath string, content []byte, appended bool) error {
   128  	file, err := os_.OpenFile(filePath, appended)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	defer file.Close()
   133  
   134  	buf := bufio.NewWriter(file)
   135  	_, err = buf.Write(content)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	if err := buf.Flush(); err != nil {
   141  		return err
   142  	}
   143  
   144  	return nil
   145  }
   146  
   147  // WriteLine join all line to file.
   148  func WriteFileLines(filePath string, lines []string, appended bool) (err error) {
   149  
   150  	file, err := os_.OpenFile(filePath, appended)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	defer file.Close()
   155  
   156  	buf := bufio.NewWriter(file)
   157  	for i := range lines {
   158  		if _, err = buf.WriteString(lines[i] + "\n"); err != nil {
   159  			return err
   160  		}
   161  	}
   162  
   163  	if err := buf.Flush(); err != nil {
   164  		return err
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  // WriteLine join all words with spaces, terminate with newline and
   171  // write to file.
   172  func WriteFileLine(filePath string, words []string, appended bool) (err error) {
   173  	file, err := os_.OpenFile(filePath, appended)
   174  	if err != nil {
   175  		return err
   176  	}
   177  	defer file.Close()
   178  
   179  	buf := bytes.NewBuffer(nil)
   180  	err = WriteLine(buf, words...)
   181  	if err != nil {
   182  		return err
   183  	}
   184  	_, err = file.Write(buf.Bytes())
   185  	if err != nil {
   186  		return err
   187  	}
   188  
   189  	return nil
   190  }
   191  
   192  // WriteLine join all words with spaces, terminate with newline and write to buff.
   193  func WriteLine(buf *bytes.Buffer, words ...string) error {
   194  	// We avoid strings.Join for performance reasons.
   195  	for i := range words {
   196  		_, err := buf.WriteString(words[i])
   197  		if err != nil {
   198  			return err
   199  		}
   200  		if i < len(words)-1 {
   201  			err = buf.WriteByte(' ')
   202  		} else {
   203  			err = buf.WriteByte('\n')
   204  		}
   205  		if err != nil {
   206  			return err
   207  		}
   208  
   209  	}
   210  
   211  	return nil
   212  }
   213  
   214  // WriteBytesLine write bytes to buffer, terminate with newline
   215  func WriteBytesLine(buf *bytes.Buffer, bytes []byte) error {
   216  	_, err := buf.Write(bytes)
   217  	if err != nil {
   218  		return err
   219  	}
   220  
   221  	err = buf.WriteByte('\n')
   222  	if err != nil {
   223  		return err
   224  	}
   225  
   226  	return nil
   227  }
   228  
   229  func WriteBytesAt(filepath string, bytes []byte, offset int64) error {
   230  	file, err := os_.OpenAll(filepath, os.O_CREATE|os.O_RDWR, os.ModePerm)
   231  	if err != nil {
   232  		return err
   233  	}
   234  	defer file.Close()
   235  
   236  	n, err := file.Seek(offset, io.SeekStart)
   237  	if err != nil {
   238  		return err
   239  	}
   240  	_, err = file.WriteAt(bytes, n)
   241  	if err != nil {
   242  		return err
   243  	}
   244  
   245  	return nil
   246  }
   247  
   248  func WriteReader(filepath string, r io.Reader) error {
   249  	file, err := os_.OpenAll(filepath, os.O_CREATE|os.O_RDWR, os.ModePerm)
   250  	//	file, err := os_.OpenFile(filepath, true)
   251  	if err != nil {
   252  		return err
   253  	}
   254  	defer file.Close()
   255  
   256  	_, err = io.Copy(file, r)
   257  	return err
   258  }
   259  
   260  func WriteReaderAt(filepath string, r io.Reader, offset, length int64) error {
   261  	file, err := os_.OpenAll(filepath, os.O_CREATE|os.O_RDWR, os.ModePerm)
   262  	//	file, err := os_.OpenFile(filepath, true)
   263  	if err != nil {
   264  		return err
   265  	}
   266  	defer file.Close()
   267  
   268  	buf := make([]byte, 1024)
   269  	var total int64
   270  
   271  	for total < length {
   272  		nr, err := r.Read(buf)
   273  		if err == nil || err == io.EOF {
   274  			if nr > 0 {
   275  				n, err := file.Seek(offset, io.SeekStart)
   276  				if err != nil {
   277  					return err
   278  				}
   279  				_, err = file.WriteAt(buf[:nr], n)
   280  				if err != nil {
   281  					return err
   282  				}
   283  
   284  				offset += int64(nr)
   285  				total += int64(nr)
   286  			}
   287  
   288  			if err == io.EOF {
   289  				break
   290  			}
   291  
   292  		} else {
   293  			return err
   294  		}
   295  
   296  	}
   297  
   298  	return nil
   299  }