一、概述

1、文件

文件:文件是数据源(保存数据的地方) 的一种,比如word文档,txt文件,excel文件...都是文件。文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保存视频,声音...

文件在程序中是以流的形式来操作的。

流:数据在数据源(文件)和程序(内存)之间经历的路径

  • 输入流:数据从数据源(文件)到程序(内存)的路径
  • 输出流:数据从程序(内存)到数据源(文件)的路径
import "os" 包下有File结构体,os.File封装了所有文件相关操作,File是一个结构体。
type File struct {
    // 内含隐藏或非导出字段
}
File代表一个打开的文件对象。
好多方法
func (f *File) Read(b []byte) (n int, err error)
func (f *File) Write(b []byte) (n int, err error)
...等等
对文件操作,会经常使用到os.File结构体。

1.1、打开文件和关闭文件

os.File
func Open(name string) (file *File, err error):Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。
func (f *File) Close() error:Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。
package main
import (
	"fmt"
	"os"
)

func main(){
	file,err := os.Open("D:/test.txt")//file:文件对象/文件指针/文件句柄  一个意思
	if err != nil {
		fmt.Println("open file err=",err)
	}
	fmt.Printf("file=%v",file)//file=&{0xc00010e780} //file是一个指针
	err=file.Close()
	if err != nil {
		fmt.Println("Close file err=",err)
	}
}

1.2、读文件

  1. 读取文件的内容并显示在终端(带缓冲区的方式),使用os.Open,file.Close,bufio.NewReader(),reader.ReadString函数和方法
package main
import (
	"fmt"
	"os"
	"bufio"
	"io"
)

func main(){
	file,err := os.Open("D:/test.txt")//file:文件对象/文件指针/文件句柄  一个意思
	if err != nil {
		fmt.Println("open file err=",err)
	}
	
	defer file.Close()

	reader := bufio.NewReader(file)
	for{
		str,err := reader.ReadString('\n')
		if err ==io.EOF{
			break
		}
		fmt.Print(str)
	}
	fmt.Println("文件读取结束..")
}
  1. 读取文件的内容并显示在终端(使用ioutil一次将整个文件读入到内存中),这种方式适用于文件不大的情况。相关方法和函数(ioutil.ReadFile)
import "io/ioutil"
func ReadFile(filename string) ([]byte, error):ReadFile 从filename指定的文件中读取数据并返回文件的内容。成功的调用返回的err为nil而非EOF。因为本函数定义为读取整个文件,它不会将读取返回的EOF视为应报告的错误。
===========================
package main
import (
	"fmt"
	"io/ioutil"
)
func main(){
	file := "D:/test.txt"
	content,err :=ioutil.ReadFile(file)//文件的Open和Close在ReadFile内部,不需要我们关闭文件
	if err != nil {
		fmt.Println("read file err=",err)
	}
	fmt.Printf("%v\n",content) //[]byte
	fmt.Printf("%v",string(content))
}

1.3、写文件

  1. 使用os.OpenFile(),bufio.NewWriter()
import "os"
func OpenFile(name string, flag int, perm FileMode) (file *File, err error):OpenFile是一个
更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY
等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,
错误底层类型是*PathError。
const (
    O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
    O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
    O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
    O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,文件必须不存在
    O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
)
==========================================
package main
import (
	"fmt"
	"os"
	"bufio"
)
func main(){
	filePath := "D:/ok.txt"
	file,err := os.OpenFile(filePath,os.O_WRONLY | os.O_CREATE ,0666)

	if err != nil {
		fmt.Println("open file err=",err)
		return
	}

	defer file.Close()

	str :="hello,golang\n"
	writer := bufio.NewWriter(file)
	for i:=1;i<=5;i++{
		writer.WriteString(str)  //内容写到缓存中
	}
	writer.Flush()//把缓存内容真正写入到文件中
}

已存在的文件进行清空写入:os.O_TRUNC

file,err := os.OpenFile(filePath,os.O_WRONLY | os.O_TRUNC ,0666)

已存在的文件进行追加写入:os.O_APPEND

file,err := os.OpenFile(filePath,os.O_WRONLY | os.O_APPEND ,0666)

已存在的文件进行读写模式打开:os.O_RDWR

file,err := os.OpenFile(filePath,os.O_RDWR | os.O_APPEND ,0666)
package main
import (
	"fmt"
	"os"
	"bufio"
)

func main(){
	filePath := "D:/ok.txt" //打开已经存在的文件
	file,err := os.OpenFile(filePath,os.O_WRONLY | os.O_TRUNC ,0666)

	if err != nil {
		fmt.Println("open file err=",err)
		return
	}

	defer file.Close()

	str :="hello,world!\r\n"
	writer := bufio.NewWriter(file)
	for i:=1;i<=5;i++{
		writer.WriteString(str)  //内容写到缓存中
	}
	writer.Flush()//把缓存内容真正写入到文件中
}
  1. 将一个文件的内容写入到另一个文件,这两个文件已经存在了,使用ioutil.ReadFile/ioutil.WriteFile完成写文件的任务
//文件从file1Path写到file2Path
package main
import (
	"fmt"
	"io/ioutil"
)

func main(){
	file1Path := "D:/ok.txt" 
	file2Path := "E:/kkk.txt" 
	data,err :=ioutil.ReadFile(file1Path)
	if err != nil {
		fmt.Println("read file err=",err)
		return
	}
	
	err =ioutil.WriteFile(file2Path,data,0666)
	if err != nil {
		fmt.Println("write file err=",err)
		return
	}
}

1.4、判断文件是否存在

Golang判断文件或文件夹是否存在的方法为使用os.Stat()函数返回的错误值进行判断

  1. 如果返回的错误为nil,说明文件或文件夹存在
  2. 如果返回的错误类型使用os.IsNotExist()判断为true,说明文件或文件夹不存在
  3. 如果返回的错误为其他类型,则不确定是否存在
func Stat(name string) (fi FileInfo, err error):Stat返回一个描述name指定的文件对象的FileInfo。
package main
import (
	"fmt"
	"os"
)
func PathExists(path string)(bool,error){
	_,err := os.Stat(path)
	if err == nil {//文件或者目录存在
		return true,nil
	}
	if os.IsNotExist(err){
		return false,nil
	}
	return false,err
}

func main(){
	filePath := "D:/ok.txt"
	b,err:=PathExists(filePath)
	fmt.Printf("b=%v,err=%v",b,err)
}

1.5、拷贝文件

将图片/电影/mp3拷贝到另外一个文件

import "io"
func Copy(dst Writer, src Reader) (written int64, err error):将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
====================================
package main
import (
	"fmt"
	"os"
	"bufio"
	"io"
)
//从srcFileName拷贝到destFileName
func CopyFile(destFileName string,srcFileName string)(written int64, err error){
	srcFile,err := os.Open(srcFileName)
	if err != nil {
		fmt.Println("open file err=",err)
		return
	}
	defer srcFile.Close()

	reader := bufio.NewReader(srcFile)

	destFile,err := os.OpenFile(destFileName,os.O_WRONLY | os.O_CREATE,0666)
	if err != nil {
		fmt.Println("open file err=",err)
		return
	}
	writer := bufio.NewWriter(destFile)
	defer destFile.Close()
	return io.Copy(writer,reader)
}
func main(){
	file1Path := "D:/ok.txt" 
	file2Path := "E:/ok1.txt" 
	CopyFile(file2Path,file1Path)

	file3Path := "D:/test.jpg" 
	file4Path := "E:/test1.jpg" 
	CopyFile(file4Path,file3Path)
}

干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!

04-14 01:04