1
go 官方库的文件操作分散在多个包中,感觉有点乱,比如os,ioutil包,基于别人总结的基础上简单总结一下

1.文件基本操作

1.1创建空文件

  package main

import (
    "os"
    "log"

)

var (
    newFile *os.File
    err error
)
func main(){
      //创建文件
      newFile,err=os.Create("text.txt")
      checkErr(err)
      log.Println(newFile)
      newFile.Close()
}
/**
 检查错误
 */
func checkErr(err error){
      if err!=nil{
          log.Fatal(err)
      }
}

1.2 truncate 文件

     package main
    
    import (
        "log"
        "os"
    )

    func main(){
        // 裁剪一个文件到100个字节。
        // 如果文件本来就少于100个字节,则文件中原始内容得以保留,剩余的字节以null字节填充。
        // 如果文件本来超过100个字节,则超过的字节会被抛弃。
        // 这样我们总是得到精确的100个字节的文件。
        // 传入0则会清空文件。
        err:=os.Truncate("text.txt",100)
        checkErr(err)
    }
    
    func checkErr(err error){
        if err!=nil{
            log.Panic(err)
        }
    }

1.3 得到文件信息

    package main

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

var (
    fileInfo os.FileInfo
    err      error
)

func main() {
    fileInfo, err = os.Stat("text.txt")
    checkErr(err)
    fmt.Println("FIle name:", fileInfo.Name())
    fmt.Println("Size in bytes:", fileInfo.Size())
    fmt.Println("Permissions:", fileInfo.Mode())
    fmt.Println("Last modified:", fileInfo.ModTime())
    fmt.Println("Is directory:", fileInfo.IsDir())
    fmt.Printf("System interface type:%T\n", fileInfo.Sys())
    fmt.Printf("System info:%+v\n\n", fileInfo.Sys())

}

func checkErr(err error) {
    if err != nil {
        log.Panic(err)
    }
}

运行结果

clipboard.png

1.4 重命名和移动

renamemove原理一样
package main

import (
    "log"
    "os"
)

func main() {
    oldPath, newPath := "text.txt", "test.txt"
    err := os.Rename(oldPath, newPath)
    checkErr(err)

}

func checkErr(err error) {
    if err != nil {
        log.Panic(err)
    }
}

1.5 删除文件

    package main

import (
    "log"
    "os"
)

func main() {
    err := os.Remove("text.txt")
    checkErr(err)

}

func checkErr(err error) {
    if err != nil {
        log.Panic(err)
    }
}

1.6 打开文件

    package main

import (
    "log"
    "os"
)

func main() {
    // 简单地以只读的方式打开。下面的例子会介绍读写的例子。
    file,err:=os.Open("test.txt")
    checkErr(err)
    file.Close()

    // OpenFile提供更多的选项。
    // 最后一个参数是权限模式permission mode
    // 第二个是打开时的属性
    file1,err:=os.OpenFile("hello.txt",os.O_CREATE|os.O_APPEND,0666)
    checkErr(err)
    file1.Close()
    //下面的属性可以单独使用,也可以组合使用。
    // 组合使用时可以使用 OR 操作设置 OpenFile的第二个参数,例如:
    // os.O_CREATE|os.O_APPEND
    // 或者 os.O_CREATE|os.O_TRUNC|os.O_WRONLY
    // os.O_RDONLY // 只读
    // os.O_WRONLY // 只写
    // os.O_RDWR // 读写
    // os.O_APPEND // 往文件中添建(Append)
    // os.O_CREATE // 如果文件不存在则先创建
    // os.O_TRUNC // 文件打开时裁剪文件
    // os.O_EXCL // 和O_CREATE一起使用,文件不能存在
    // os.O_SYNC // 以同步I/O的方式打开

}

func checkErr(err error) {
    if err != nil {
        log.Panic(err)
    }
}

1.7检查文件是否存在

    package main

import (
    "log"
    "os"
)

func main() {
    fileInfo,err:=os.Stat("hello.txt")
      if err!=nil{
          if os.IsNotExist(err){
              log.Fatalln("file does not exist")
        }
      }
      log.Println("file does exist. file information:")
      log.Println(fileInfo)


}

1.8 检查读写权限

    package main

import (
    "os"
    "log"
)

func main() {
    // 这个例子测试写权限,如果没有写权限则返回error。
    // 注意文件不存在也会返回error,需要检查error的信息来获取到底是哪个错误导致。
    file, err := os.OpenFile("1.txt", os.O_WRONLY, 0666)
    if err != nil {
        if os.IsPermission(err) {
            log.Println("Error write permission denied")
        }
        if os.IsNotExist(err) {
            log.Println("file does not exist")
        }
    }
    file.Close()
    // 测试读权限
    file, err = os.OpenFile("test.txt", os.O_RDONLY, 0666)
    if err != nil {
        if os.IsPermission(err) {
            log.Println("Error:Read permission denied")
        }
    }

    file.Close()
}

1.9改变权限、拥有者、时间戳

package main

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

func main(){
    // 使用Linux风格改变文件权限
    err:=os.Chmod("test.txt",0777)
    checkErr(err)
    // 改变文件所有者
    err=os.Chown("test.txt",os.Geteuid(),os.Getgid())
    checkErr(err)
    twoDaysFromNow:=time.Now().Add(48*time.Hour)
    lastAccessTime:=twoDaysFromNow
    lastModifyTime:=twoDaysFromNow
    err=os.Chtimes("test.txt",lastAccessTime,lastModifyTime)
    checkErr(err)
    fileInfo,err:=os.Stat("test.txt")

    fmt.Println("file modified time:",fileInfo.ModTime())
    
}

func checkErr(err error){
    if err!=nil{
        log.Println(err)
    }
}

1.10 硬链接和软链接

一个普通的文件是一个指向硬盘的inode的地方。
硬链接创建一个新的指针指向同一个地方。只有所有的链接被删除后文件才会被删除。硬链接只在相同的文件系统中才工作。你可以认为一个硬链接是一个正常的链接。

symbolic link,又叫软连接,和硬链接有点不一样,它不直接指向硬盘中的相同的地方,而是通过名字引用其它文件。他们可以指向不同的文件系统中的不同文件。并不是所有的操作系统都支持软链接。

package main
import (
    "os"
    "log"
    "fmt"
)
func main() {
    // 创建一个硬链接。
    // 创建后同一个文件内容会有两个文件名,改变一个文件的内容会影响另一个。
    // 删除和重命名不会影响另一个。
    err := os.Link("original.txt", "original_also.txt")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("creating sym")
    // Create a symlink
    err = os.Symlink("original.txt", "original_sym.txt")
    if err != nil {
        log.Fatal(err)
    }
    // Lstat返回一个文件的信息,但是当文件是一个软链接时,它返回软链接的信息,而不是引用的文件的信息。
    // Symlink在Windows中不工作。
    fileInfo, err := os.Lstat("original_sym.txt")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Link info: %+v", fileInfo)
    //改变软链接的拥有者不会影响原始文件。
    err = os.Lchown("original_sym.txt", os.Getuid(), os.Getgid())
    if err != nil {
        log.Fatal(err)
    }
}

文章来源:http://colobu.com/2016/10/12/...


soledad
888 声望35 粉丝

我们努力的付出想换来的是什么,我只想让自己过得快乐点