go语言中的读写操作以及文件的复制

目录

一、文件读写

1.读取文件中的数据:

 2.写出数据到本地文件:

二、文件复制

1、方法一:io包下的Read()和Write()方法实现

2、方法二:io包下的Copy()方法实现

3、方法三:ioutil包


一、文件读写

file类是在os包中的,封装了底层的文件描述符和相关信息,同时封装了Read和Write的实现。

func (f *File) Read(b []byte) (n int, err error)
//Read方法从f中读取最多len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取0个字节且返回值err为io.EOF。

func (f *File) ReadAt(b []byte, off int64) (n int, err error)
//ReadAt从指定的位置(相对于文件开始位置)读取len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。当n

1.读取文件中的数据:

读取数据:
   Reader接口:
      Read(p []byte)(n int, error)

示例代码:

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
	 //读取本地aa.txt文件中的数据
	 //step1:打开文件
	 fileName := "abcd.txt"
	 file,err := os.Open(fileName)
	 if err != nil{
	 	fmt.Println("err:",err)
	 	return
	 }
	 //step3:关闭文件
	 defer file.Close()

	 //step2:读取数据
	 bs := make([]byte,4,4)
	 /*
	 //第一次读取
	 n,err :=file.Read(bs)
	 fmt.Println(err) //
	 fmt.Println(n) //4
	 fmt.Println(bs) //[97 98 99 100]
	fmt.Println(string(bs)) //abcd

	//第二次读取
	n,err = file.Read(bs)
	fmt.Println(err)//
	fmt.Println(n)//4
	fmt.Println(bs) //[101 102 103 104]
	fmt.Println(string(bs)) //efgh

	//第三次读取
	n,err = file.Read(bs)
	fmt.Println(err) //
	fmt.Println(n) //2
	fmt.Println(bs) //[105 106 103 104]
	fmt.Println(string(bs)) //ijgh

	//第四次读取
	n,err = file.Read(bs)
	fmt.Println(err) //EOF
	fmt.Println(n) //0
	 */
	 n := -1
	 for{
	 	n,err = file.Read(bs)
	 	if n == 0 || err == io.EOF{
	 		fmt.Println("读取到了文件的末尾,结束读取操作。。")
	 		break
		}
	 	fmt.Println(string(bs[:n]))
	 }
}

 2.写出数据到本地文件:

package main

import (
	"os"
	"fmt"
	"log"
)

func main() {
	/*
	写出数据:
	 */

	 fileName := "/Users/ruby/Documents/pro/a/ab.txt"
	//step1:打开文件
	//step2:写出数据
	//step3:关闭文件
	//file,err := os.Open(fileName)
	file,err := os.OpenFile(fileName,os.O_CREATE|os.O_WRONLY|os.O_APPEND,os.ModePerm)
	if err != nil{
		fmt.Println(err)
		return
	}
	defer file.Close()

	//写出数据
	//bs :=[]byte{65,66,67,68,69,70}//A,B,C,D,E,F
	bs :=[] byte{97,98,99,100} //a,b,c,d
	//n,err := file.Write(bs)
	n,err := file.Write(bs[:2])
	fmt.Println(n)
	HandleErr(err)
	file.WriteString("\n")

	//直接写出字符串
	n,err = file.WriteString("HelloWorld")
	fmt.Println(n)
	HandleErr(err)

	file.WriteString("\n")
	n,err =file.Write([]byte("today"))
	fmt.Println(n)
	HandleErr(err)

}

func HandleErr(err error){
	if err != nil{
		log.Fatal(err)
	}
}

二、文件复制

在io包中主要是操作流的一些方法,今天主要学习一下copy。就是把一个文件复制到另一个目录下。它的原理就是通过程序,从源文件读取文件中的数据,在写出到目标文件里。

1、方法一:io包下的Read()和Write()方法实现

我们可以通过io包下的Read()和Write()方法,边读边写,就能够实现文件的复制。这个方法是按块读取文件,块的大小也会影响到程序的性能。

/*
该函数的功能:实现文件的拷贝,返回值是拷贝的总数量(字节),错误
 */
func copyFile1(srcFile,destFile string)(int,error){
	file1,err:=os.Open(srcFile)
	if err != nil{
		return 0,err
	}
	file2,err:=os.OpenFile(destFile,os.O_WRONLY|os.O_CREATE,os.ModePerm)
	if err !=nil{
		return 0,err
	}
	defer file1.Close()
	defer file2.Close()
	//拷贝数据
	bs := make([]byte,1024,1024)
	n :=-1//读取的数据量
	total := 0
	for {
		n,err = file1.Read(bs)
		if err == io.EOF || n == 0{
			fmt.Println("拷贝完毕。。")
			break
		}else if err !=nil{
			fmt.Println("报错了。。。")
			return total,err
		}
		total += n
		file2.Write(bs[:n])
	}
	return total,nil

}

2、方法二:io包下的Copy()方法实现

我们也可以直接使用io包下的Copy()方法。

示例代码如下:

func copyFile2(srcFile, destFile string)(int64,error){
	file1,err:=os.Open(srcFile)
	if err != nil{
		return 0,err
	}
	file2,err:=os.OpenFile(destFile,os.O_WRONLY|os.O_CREATE,os.ModePerm)
	if err !=nil{
		return 0,err
	}
	defer file1.Close()
	defer file2.Close()

	return io.Copy(file2,file1)
}

3、方法三:ioutil包

使用ioutil包中的 ioutil.WriteFile()和 ioutil.ReadFile(),但由于使用一次性读取文件,再一次性写入文件的方式,所以该方法不适用于大文件,容易内存溢出。

示例代码:

func copyFile3(srcFile, destFile string)(int,error){
	input, err := ioutil.ReadFile(srcFile)
	if err != nil {
		fmt.Println(err)
		return 0,err
	}

	err = ioutil.WriteFile(destFile, input, 0644)
	if err != nil {
		fmt.Println("操作失败:", destFile)
		fmt.Println(err)
		return 0,err
	}

	return len(input),nil
}

这3种方式,在性能上,不管是还是io.Copy()还是ioutil包,性能都是还不错的。

你可能感兴趣的:(go的学习,go,golang,开发语言)