Golang:File 文件操作

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

FileInfo 接口

FileInfo 接口中定义了 File 信息相关的方法。

type FileInfo interface {
    Name() string       // base name of the file 文件名.扩展名 aa.txt
    Size() int64        // 文件大小,字节数 12540
    Mode() FileMode     // 文件权限 -rw-rw-rw-
    ModTime() time.Time // 修改时间 2020-09-23 16:30:53 +0800 CST
    IsDir() bool        // 是否文件夹
    Sys() interface{}   // 基础数据源接口(can return nil)
}

权限

至于操作权限 perm,除非创建文件时才需要指定,不需要创建新文件时可以将其设定为0。虽然 Golang 语言给 perm 权限设定了很多的常量,但是习惯上也可以直接使用数字,如 0666 (具体含义和 Unix 系统的一致)。
权限控制:

linux 下有2种文件权限表示方式,即“符号表示”和“八进制表示”。

(1)符号表示方式:
-      ---         ---        ---
type   owner       group      others
文件的权限是这样子分配的 读 写 可执行 分别对应的是 r w x 如果没有那一个权限,用 - 代替
(-文件 d目录 |连接符号)
例如:-rwxr-xr-x

(2)八进制表示方式: 
r ——> 004
w ——> 002
x ——> 001
- ——> 000

0755
0777
0555
0444
0666

示例代码:

package main

import (
    "os"
    "fmt"
)

func main() {
    /*
    FileInfo:文件信息
        interface
            Name(),文件名
            Size(),文件大小,字节为单位
            IsDir(),是否是目录
            ModTime(),修改时间
            Mode(),权限

     */
    fileInfo,err :=  os.Stat("/Users/ruby/Documents/pro/a/aa.txt")
    if err != nil{
        fmt.Println("err :",err)
        return
    }
    fmt.Printf("%T\n",fileInfo)
    //文件名
    fmt.Println(fileInfo.Name())
    //文件大小
    fmt.Println(fileInfo.Size())
    //是否是目录
    fmt.Println(fileInfo.IsDir()) //IsDirectory
    //修改时间
    fmt.Println(fileInfo.ModTime())
    //权限
    fmt.Println(fileInfo.Mode()) //-rw-r--r--
}

运行结果:


文件信息示例代码运行结果

File 操作

type File
//File代表一个打开的文件对象。

func Create(name string) (file *File, err error)
//Create采用模式0666(任何人都可读写,不可执行)创建一个名为name的文件,如果文件已存在会截断它(为空文件)。如果成功,返回的文件对象可用于I/O;对应的文件描述符具有O_RDWR模式。如果出错,错误底层类型是*PathError。

func Open(name string) (file *File, err error)
//Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
//OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。

func NewFile(fd uintptr, name string) *File
//NewFile使用给出的Unix文件描述符和名称创建一个文件。

func Pipe() (r *File, w *File, err error)
//Pipe返回一对关联的文件对象。从r的读取将返回写入w的数据。本函数会返回两个文件对象和可能的错误。

func (f *File) Name() string
//Name方法返回(提供给Open/Create等方法的)文件名称。

func (f *File) Stat() (fi FileInfo, err error)
//Stat返回描述文件f的FileInfo类型值。如果出错,错误底层类型是*PathError。

func (f *File) Fd() uintptr
//Fd返回与文件f对应的整数类型的Unix文件描述符。

func (f *File) Chdir() error
//Chdir将当前工作目录修改为f,f必须是一个目录。如果出错,错误底层类型是*PathError。

func (f *File) Chmod(mode FileMode) error
//Chmod修改文件的模式。如果出错,错误底层类型是*PathError。

func (f *File) Chown(uid, gid int) error
//Chown修改文件的用户ID和组ID。如果出错,错误底层类型是*PathError。

func (f *File) Close() error
//Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。

func (f *File) Readdir(n int) (fi []FileInfo, err error)
//Readdir读取目录f的内容,返回一个有n个成员的[]FileInfo,这些FileInfo是被Lstat返回的,采用目录顺序。对本函数的下一次调用会返回上一次调用剩余未读取的内容的信息。如果n>0,Readdir函数会返回一个最多n个成员的切片。这时,如果Readdir返回一个空切片,它会返回一个非nil的错误说明原因。如果到达了目录f的结尾,返回值err会是io.EOF。如果n<=0,Readdir函数返回目录中剩余所有文件对象的FileInfo构成的切片。此时,如果Readdir调用成功(读取所有内容直到结尾),它会返回该切片和nil的错误值。如果在到达结尾前遇到错误,会返回之前成功读取的FileInfo构成的切片和该错误。

func (f *File) Readdirnames(n int) (names []string, err error)
//Readdir读取目录f的内容,返回一个有n个成员的[]string,切片成员为目录中文件对象的名字,采用目录顺序。对本函数的下一次调用会返回上一次调用剩余未读取的内容的信息。如果n>0,Readdir函数会返回一个最多n个成员的切片。这时,如果Readdir返回一个空切片,它会返回一个非nil的错误说明原因。如果到达了目录f的结尾,返回值err会是io.EOF。如果n<=0,Readdir函数返回目录中剩余所有文件对象的名字构成的切片。此时,如果Readdir调用成功(读取所有内容直到结尾),它会返回该切片和nil的错误值。如果在到达结尾前遇到错误,会返回之前成功读取的名字构成的切片和该错误。

func (f *File) Truncate(size int64) error
//Truncate改变文件的大小,它不会改变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"
    "path/filepath"
    "path"
    "os"
)

func main() {
    /*
    文件操作:
    1.路径:
        相对路径:relative
            ab.txt
            相对于当前工程
        绝对路径:absolute
            /Users/ruby/Documents/pro/a/aa.txt

        .当前目录
        ..上一层
    2.创建文件夹,如果文件夹存在,创建失败
        os.MkDir(),创建一层
        os.MkDirAll(),可以创建多层

    3.创建文件,Create采用模式0666(任何人都可读写,不可执行)创建一个名为name的文件,如果文件已存在会截断它(为空文件)
        os.Create(),创建文件

    4.打开文件:让当前的程序,和指定的文件之间建立一个连接
        os.Open(filename)
        os.OpenFile(filename,mode,perm)

    5.关闭文件:程序和文件之间的链接断开。
        file.Close()

    5.删除文件或目录:慎用,慎用,再慎用
        os.Remove(),删除文件和空目录
        os.RemoveAll(),删除所有
     */
     //1.路径
     fileName1:="/Users/ruby/Documents/pro/a/aa.txt"
     fileName2:="bb.txt"
     fmt.Println(filepath.IsAbs(fileName1)) //true
     fmt.Println(filepath.IsAbs(fileName2)) //false
     fmt.Println(filepath.Abs(fileName1))
     fmt.Println(filepath.Abs(fileName2)) // /Users/ruby/go/src/l_file/bb.txt

     fmt.Println("获取父目录:",path.Join(fileName1,".."))

     //2.创建目录
     //err := os.Mkdir("/Users/ruby/Documents/pro/a/bb",os.ModePerm)
     //if err != nil{
     // fmt.Println("err:",err)
     // return
     //}
     //fmt.Println("文件夹创建成功。。")
     //err :=os.MkdirAll("/Users/ruby/Documents/pro/a/cc/dd/ee",os.ModePerm)
     //if err != nil{
     // fmt.Println("err:",err)
     // return
     //}
     //fmt.Println("多层文件夹创建成功")

     //3.创建文件:Create采用模式0666(任何人都可读写,不可执行)创建一个名为name的文件,如果文件已存在会截断它(为空文件)
     //file1,err :=os.Create("/Users/ruby/Documents/pro/a/ab.txt")
     //if err != nil{
     // fmt.Println("err:",err)
     // return
     //}
     //fmt.Println(file1)

     //file2,err := os.Create(fileName2)//创建相对路径的文件,是以当前工程为参照的
     //if err != nil{
     // fmt.Println("err :",err)
     // return
     //}
     //fmt.Println(file2)

     //4.打开文件:
     //file3 ,err := os.Open(fileName1) //只读的
     //if err != nil{
     // fmt.Println("err:",err)
     // return
     //}
     //fmt.Println(file3)
    /*
    第一个参数:文件名称
    第二个参数:文件的打开方式
        const (
    // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
        O_RDONLY int = syscall.O_RDONLY // open the file read-only.
        O_WRONLY int = syscall.O_WRONLY // open the file write-only.
        O_RDWR   int = syscall.O_RDWR   // open the file read-write.
        // The remaining values may be or'ed in to control behavior.
        O_APPEND int = syscall.O_APPEND // append data to the file when writing.
        O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
        O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
        O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
        O_TRUNC  int = syscall.O_TRUNC  // truncate regular writable file when opened.
    )
    第三个参数:文件的权限:文件不存在创建文件,需要指定权限
     */
     //file4,err := os.OpenFile(fileName1,os.O_RDONLY|os.O_WRONLY,os.ModePerm)
     //if err != nil{
     // fmt.Println("err:",err)
     // return
     //}
     //fmt.Println(file4)

     //5关闭文件,
     //file4.Close()

     //6.删除文件或文件夹:
     //删除文件
    //err :=  os.Remove("/Users/ruby/Documents/pro/a/aa.txt")
    //if err != nil{
    //  fmt.Println("err:",err)
    //  return
    //}
    //fmt.Println("删除文件成功。。")
    //删除目录
    err :=  os.RemoveAll("/Users/ruby/Documents/pro/a/cc")
    if err != nil{
        fmt.Println("err:",err)
        return
    }
    fmt.Println("删除目录成功。。")
}

判断文件是否存在

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

  1. 如果返回的错误为 nil,说明文件或文件夹存在
  2. 如果返回的错误类型使用 os.IsNotExist() 判断为 true,说明文件或文件夹不存在

示例代码:

package main
import (
    "log"
    "os"
)

func main() {
    fileInfo,err:=os.Stat("/Users/ruby/Documents/pro/a/aa.txt")
    if err!=nil{
        if os.IsNotExist(err){
            log.Fatalln("file does not exist")
        }
    }
    log.Println("file does exist. file information:")
    log.Println(fileInfo)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268