go语言文件操作,这期资料比较详细

欢迎加入go语言群: go语言深圳群 golang深圳 218160862

点击加入

文件操作

func Open(name string) (file *File, err error),*File 是实现了 io.Reader这个接口
byte[] 转化为 bytes.Buffer:bytes.NewBuffer([]byte).

一、建立与打开

建立文件函数:
func Create(name string) (file *File, err Error)
func NewFile(fd int, name string) *File

打开文件函数:
func Open(name string) (file *File, err Error)
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

判断文件是否存在:
// it returns false when it's a directory or does not exist.
func IsFile(file string) bool {
    f, e := os.Stat(file)
    if e != nil {
        return false
    }
    return !f.IsDir()
}

// IsExist returns whether a file or directory exists.
func IsExist(path string) bool {
    _, err := os.Stat(path)
    return err == nil || os.IsExist(err)
}

// 追加写入文件日志
func myLog( str string ){
    // 这行使用追加模式写入文件,如果文件不存在则创建
    fp, err := os.OpenFile( LOGFILE, os.O_CREATE|os.O_APPEND|os.O_RDWR,0660 )
    defer fp.Close()
    
    if err != nil{
        walk.MsgBox(nil, "写入日志结果:", "失败", walk.MsgBoxIconError)
    }
    
    timeStr := time.Now().Format("2006-01-02 15:04:05") // 这是个奇葩,必须是这个时间点, 据说是go诞生之日, 记忆方法:6-1-2-3-4-5
    fp.WriteString( timeStr + " 日志信息: " + str + " \n" )    
}

二、写文件

写文件函数:
func (file *File) Write(b []byte) (n int, err Error)
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
func (file *File) WriteString(s string) (ret int, err Error)

写文件示例代码:

package main
import (
        "os"
        "fmt"
)
func main() {
        userFile := "test.txt"
        fout,err := os.Create(userFile)
        defer fout.Close()
        if err != nil {
                fmt.Println(userFile,err)
                return
        }
        for i:= 0;i<10;i++ {
                fout.WriteString("Just a test!\r\n")
                fout.Write([]byte("Just a test!\r\n"))
        }
}

三、读文件

读文件函数:
func (file *File) Read(b []byte) (n int, err Error)
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

具体见官网:http://golang.org/pkg/os/#File.Read
 
读文件示例代码:

package main
import (
        "os"
        "fmt"
)
func main() {
        userFile := "test.txt"
        fin,err := os.Open(userFile)
        defer fin.Close()
        if err != nil {
                fmt.Println(userFile,err)
                return
        }
        buf := make([]byte, 1024)
        for{
                n, _ := fin.Read(buf)
                if 0 == n { break }
                os.Stdout.Write(buf[:n])
        }
}

四、删除文件

函数:
func Remove(name string) Error

------------------------------------------------------------------------------------------------
使用os库os.Open os.Create。

package main
import (
    "io"
    "os"
)
 
func main() {
    fi, err := os.Open("input.txt")
    if err != nil { panic(err) }
    defer fi.Close()
 
    fo, err := os.Create("output.txt")
    if err != nil { panic(err) }
    defer fo.Close()
 
    buf := make([]byte, 1024)
    for {
        n, err := fi.Read(buf)
        if err != nil && err != io.EOF { panic(err) }
        if n == 0 { break }
 
        if n2, err := fo.Write(buf[:n]); err != nil {
            panic(err)
        } else if n2 != n {
            panic("error in writing")
        }
    }
}

使用bufio库
package main
import (
    "bufio"
    "io"
    "os"
)
 
func main() {
    fi, err := os.Open("input.txt")
    if err != nil { panic(err) }
    defer fi.Close()
    r := bufio.NewReader(fi)
 
    fo, err := os.Create("output.txt")
    if err != nil { panic(err) }
    defer fo.Close()
    w := bufio.NewWriter(fo)
 
    buf := make([]byte, 1024)
    for {
        n, err := r.Read(buf)
        if err != nil && err != io.EOF { panic(err) }
        if n == 0 { break }
 
        if n2, err := w.Write(buf[:n]); err != nil {
            panic(err)
        } else if n2 != n {
            panic("error in writing")
        }
    }
 
    if err = w.Flush(); err != nil { panic(err) }
}

使用ioutil库
package main
import (
    "io/ioutil"
)
 
func main() {
    b, err := ioutil.ReadFile("input.txt")
    if err != nil { panic(err) }
 
    err = ioutil.WriteFile("output.txt", b, 0644)
    if err != nil { panic(err) }
}

五、遍历文件夹
package main
import (
    "path/filepath"
    "os"
    "fmt"
    "flag"
)

func getFilelist(path string) {
        err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
                if ( f == nil ) {return err}
                if f.IsDir() {return nil}
                println(path)
                return nil
        })
        if err != nil {
                fmt.Printf("filepath.Walk() returned %v\n", err)
        }
}

func main(){
        flag.Parse()
        root := flag.Arg(0)
        getFilelist(root)
}

golang编程之文件操作 2013-11-17 16:11:07

分类: LINUX

操作文件是任何编程语言都绕不过,要掌握一门语言,知道如何操作文件是必不可少的,今天学习了下golang对文件操作的支持。
    golang对文件的支持是在os package里。我无意将本文写成官方文档的模样,我只是想讨论如何利用这些接口操作文件。
    OPEN
     熟悉文件系统的人都知道,open是整个文件系统中最复杂的接口之一。熟悉C语言的都知道,C语言中有open和creat,接口如下:

#include <sys/types.h>
           #include <sys/stat.h>
           #include <fcntl.h>

int open(const char *pathname, int flags);
           int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode)

对C的open而言,如果flag里面有了O_CREAT,那么必须带上mode参数,制定创建文件时的perm,如果文件已经存在了,这个O_CREAT标志就无效了(除非O_EXCL标志被指定。 除了O_CREAT,还有很多的标志

O_RDONLY
    O_WRONLY
    O_RDWR
    O_DIRECT
    O_APPEND
    O_TRUNC
    。。。。
    这些标志位基本是顾名思义,对于open这种很复杂很综合的文件操作,golang中对应的是OpenFile

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

我们看到了也有flag,也有FileMode.比如说我要读写打开一个文件,如果不存在就创建,如果存在,就追加写,如何写go 代码?

f,err := os.OpenFile("test.txt",os.O_CREATE|os.O_APPEND|os.O_RDWR,0660)
        if(err != nil){
            panic(err)
        }

我们看到了,golang中也有这些标志(注意O_CREATE,在C语言中,是O_CREAT),我在上面代码片段中用了几个标志

const (
            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.
            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 // if possible, truncate file when opened.
          )

C语言中有creat,没有则创建,有则截断写,本质等于O_WRONLY | O_CREAT | O_TRUNC

#include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int creat (const char *name, mode_t mode)

Ken Thompson大神曾经戏言,漏掉creat系统调用中的e字母是他设计Unix最后悔的事情,呵呵看起来老爷子接收了教训,没有犯同样的拼写错误,golang中对应的接口是Create(大神这一次没有拼写错)

func Create(name string) (file *File, err error)

和C的creat系统调用相比,少了mode入参,默认是0x666(before umask),同时标志不再是O_WRONLY,而是O_RDWR,仍然带创建标志位,仍然带截断标志。
    golang中的Open和C中的open就不能相比了(和C中的open PK那是OpenFile的事儿)接口如下:

func Open(name string) (file *File, err error)

直白说,就是带O_RDONLY的open,太菜了。

CLOSE
    这个接口无甚好说。接口如下

func (f *File) Close() error

但说接口没啥说的,但是golang提供了defer,这是一个我认为很赞的特点,就是将不得不做的cleanup放到defer去做。
    我们写C的人,经常遇到了这种代码

fd = open(...)
    if(fd < 0 )
    {
        ...
    }

if (failed_1)
    {
       ...
       close(fd);
       ....
    }

if(faile_2)
    {
        ...
        close(fd);
        ...
    }
    ....

只要打开了文件,每次异常处理都要想着close,否则句柄泄漏,太烦。所以C语言是一门你要小心伺候的语言。
    go提供了defer解决这种困境,后面不用时刻惦记close,函数退出前,会执行close。

f,err := os.OpenFile("test.txt",os.O_CREATE|os.O_APPEND|os.O_RDWR,0660)
        if(err != nil){
            panic("open file failed")
        }
        defer f.Close()
        ...

READ和WRITE
    read和write是比较重要的文件操作了,这是C的接口。

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
      ssize_t read(int fd, void *buf, size_t count)

对于golang,接口如下:

func (f *File) Read(b []byte) (n int, err error)
    func (f *File) ReadAt(b []byte, off int64) (n int, err error)

func (f *File) Write(b []byte) (n int, err error)
    func (f *File) WriteAt(b []byte, off int64) (n int, err error)
    func (f *File) WriteString(s string) (ret int, err error)

看到代码片段,学习使用读写接口:

read_buf := make([]byte,32)
        var pos int64 = 0
        for{

n,err := f.ReadAt(read_buf,pos)
            if err != nil && err != io.EOF{
                panic(err)
            }
            if n == 0{
                fmt.Printf("\nfinish read\n")
                break
            }
            fmt.Printf("%s",string(read_buf[:n]))
            pos = pos +(int64)(n)
        }

在看一个代码片段:

var buff = make([]byte,1024)
        for{
            n,err := fi.Read(buff)
            if err != nil && err != io.EOF{
                panic(err)
            }
            
            if n == 0{
                break
            }

if _,err := fo.Write(buff[:n]); err != nil{
                panic(err)
            }

}

最后,我写了一个完整的代码,完成简单cp功能,就叫mycp

manu@manu-hacks:~/code/go/self$ cat mycp.go
    package main
    import "fmt"
    import "os"
    import "io"

func usage(){
        fmt.Printf("%s %s %s\n",os.Args[0],"filename" , "newfile")
    }

func main(){
        
        if len(os.Args) != 3{
            usage()
            return
        }

filename_in := os.Args[1]
        fi,err := os.Open(filename_in)
        if err != nil{
            panic(err)
        }
        defer fi.Close()

filename_out := os.Args[2]
        fo,err := os.Create(filename_out)
        if err != nil{
            panic(err)
        }
        defer fo.Close()

var buff = make([]byte,1024)
        for{
            n,err := fi.Read(buff)
            if err != nil && err != io.EOF{
                panic(err)
            }
            
            if n == 0{
                break
            }

if _,err := fo.Write(buff[:n]); err != nil{
                panic(err)
            }

}
    }

执行结果:

manu@manu-hacks:~/code/go/self$ ./mycp test.txt test.bak
    manu@manu-hacks:~/code/go/self$ diff test.txt test.bak
    manu@manu-hacks:~/code/go/self$ cat test.txt
    this is test file created by go
    if not existed ,please create this file
    if existed, Please write append
    hello world,hello go
    this is test file created by go
    if not existed ,please create this file
    if existed, Please write append
    hello world,hello go

参考文献
1 Linux system program
2 golang os package
3 StackOverflow How to read/write from/to file?

go语言文件操作,这期资料比较详细( 欢迎加入go语言群: 218160862 )的更多相关文章

  1. C语言文件操作

    C语言文件操作,以下以基本的例子和说明来展开怎么通过C语言来进行文件操作. 操作文件,我们得需要知道什么?当然是路径和文件名. 首先我需要知道我操作的文件在哪里,叫什么名字.在C语言中还存在一个打开方 ...

  2. C 语言文件操作

    C 语言文件操作 1. 数据流:     程序与数据的交互以流的形式进行.fopen 即打开数据流,fclose 即刷新数据流.     所谓数据流,是一种抽象,表示这段数据像流一样,需要逐步接收,不 ...

  3. C语言文件操作函数

    C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * str ...

  4. C语言文件操作解析(五)之EOF解析(转载)

      C语言文件操作解析(五)之EOF解析 在C语言中,有个符号大家都应该很熟悉,那就是EOF(End of File),即文件结束符.但是很多时候对这个理解并不是很清楚,导致在写代码的时候经常出错,特 ...

  5. 【转】C语言文件操作解析(三)

    原文网址:http://www.cnblogs.com/dolphin0520/archive/2011/10/07/2200454.html C语言文件操作解析(三) 在前面已经讨论了文件打开操作, ...

  6. C语言文件操作函数大全(超详细)

    C语言文件操作函数大全(超详细) 作者: 字体:[增加 减小] 类型:转载 本篇文章是对C语言中的文件操作函数进行了详细的总结分析,需要的朋友参考下   fopen(打开文件)相关函数 open,fc ...

  7. C语言文件操作 FILE结构体

    内存中的数据都是暂时的,当程序结束时,它们都将丢失.为了永久性的保存大量的数据,C语言提供了对文件的操作. 1.文件和流 C将每个文件简单地作为顺序字节流(如下图).每个文件用文件结束符结束,或者在特 ...

  8. C语言文件操作相关函数

    在实际应用中,我们往往需要对文件进行操作,下面我将介绍C语言的一些关于操作文件的函数. 一.计算机文件 计算机文件是以计算机硬盘为载体存储在计算机上的信息集合,是存储在某种长期储存设备上的一段数据流. ...

  9. 关于C语言文件操作

    关于C语言的文件操作之前我也写过一篇博客来介绍,但是当时写的很不全面,只是简单的使用了一下 ,今天再从新学习一下. 1.文件的写 首先还是先看一个简单的例子: include<stdio.h&g ...

随机推荐

  1. opencv 小任务1 图片的缩放

    #include <opencv2/opencv.hpp> using namespace std; int main() { double fScale = 0.2; //缩放倍数 Cv ...

  2. 超酷震撼 HTML5/CSS3动画应用及源码

    HTML5可以制作非常华丽的动画效果,这点通过之前的分享学习我们已经有深刻的了解了,今天我们主要来分享一些HTML5结合CSS3形成的超炫震撼的动画应用以及它们的源代码,真的非常不错. 1.纯CSS3 ...

  3. 小游戏Talk表

    [Config]1|0|2|久远的记忆影子|你也是误入宠物王国的妹子吧,我在这里等你很久了,或许我们应该一起逃出这里,跟着我.[Config] [Config]2|3|2|久远的记忆影子|这里原本是一 ...

  4. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  5. 将Jquery序列化后的表单值转换成Json

    From: https://segmentfault.com/a/1190000000473625 小朋友有一个表单,他想以Json的方式获取到表单的内容.小朋友尝试了以下方式. 通过$(" ...

  6. AtCoder Grand Contest 6

    A - Prefix and Suffix 题意:输入一个整形变量n和两个字符串s,t,使用一些规则求满足条件的最短字符串的长度:规则如下:这个最短字符串的长度不能小于n:它的前n个字符必须与s相同: ...

  7. 关于SQL安装问题及安装前的准备

    转载自:IceWee  原文连接:http://www.cnblogs.com/icewee/articles/2019783.html 由于工作需要,今天要在电脑上安装SQL Server 2005 ...

  8. web开发流程(传智播客-方立勋老师)

    1.搭建开发环境 1.1 导入项目所需的开发包 dom4j-1.6.1.jar jaxen-1.1-beta-6.jar commons-beanutils-1.8.0.jar commons-log ...

  9. ruby环境的配置

    安装 Ruby 解析器 一些Linux发行版本,MacOSX操作系统都自带Ruby解析器,但是我仍然建议自行下载ruby源代码编译安装.因为一方面可以自己定制ruby安装的路径,另一方面可以在编译过程 ...

  10. java语言程序设计(一)-1

    java 语言的特点是: 强类型,制定了比较多的语言规范,尽可能在编译阶段检测出更多的错误及警告. 编译和解释,首先将源代码编译成codebyte,运行时,java的运行系统装载和链接需要执行的类,并 ...