欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

文件基本操作

程序员文章站 2022-03-03 11:02:59
读取整个文件 整个文件读取到内存是最基本的文件操作之一。这需要使用 包中的 函数。 以上使用的是运行时指定参数 来指定读取的文件,也可以使用文件的绝对路径。 分块读取文件 当文件非常大时,尤其在内存不足的情况下,把整个文件都读入内存是没有意义的。 更好的方法是分块读取文件。这可以使用 包来完成。 利 ......

读取整个文件

  • 整个文件读取到内存是最基本的文件操作之一。这需要使用ioutil包中的readfile函数。
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
)

func main() {

	fptr := flag.string("path", "test.txt", "待读取文件的路径")
	flag.parse()

	data, err := ioutil.readfile(*fptr)
	if err != nil {
		fmt.println(err)
	}
	fmt.println(string(data))
}
  • 以上使用的是运行时指定参数-path=test1.txt来指定读取的文件,也可以使用文件的绝对路径。

分块读取文件

  • 当文件非常大时,尤其在内存不足的情况下,把整个文件都读入内存是没有意义的。
  • 更好的方法是分块读取文件。这可以使用bufio包来完成。
  • 利用bufio包的'newreader()'函数实现,其中read方法可以读取文件内容到缓冲的字节数组中去。
package main

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

func main() {

	// 打开文件
	f, err := os.open("test.txt")
	if err != nil {
		fmt.println(err)
	}
	// 延迟关闭文件
	defer func() {
		if err := f.close(); err != nil {
			fmt.println(err)
		}
	}()
	// 文件读取器
	r := bufio.newreader(f)
	buf := make([]byte, 3) // 便于演示 设置的比较小
	str := ""
	for {
		_, err := r.read(buf)
		if err != nil {
			if err == io.eof {
				fmt.println("文件读取完毕!")
			} else {
				fmt.println(err)
			}
			break
		}
		fmt.println(string(buf))
		str += string(buf)
	}
	fmt.println("完整结果如下:\n", str)
}

逐行读取文件

  • 当文件比较大时还可以采用逐行读取的方式实现。
  • 利用bufio包的'newscanner()'函数实现,其中scan方法可以判断是否还有下一行,

text方法可以获取当前行,err方法可以获取错误信息。

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {

	// 打开文件
	f, err := os.open("test.txt")
	if err != nil {
		fmt.println(err)
	}
	// 延迟关闭文件
	defer func() {
		if err := f.close(); err != nil {
			fmt.println(err)
		}
	}()
	// 文件读取器
	s := bufio.newscanner(f)
	str := ""
	for s.scan() {
		fmt.println(s.text(), "\n-------分隔符--------")
		str += s.text()
	}
	if s.err() != nil {
		fmt.println(s.err().error())
	}
	fmt.println("完整结果如下:\n", str)
}

字符串写入文件

  • 使用 create 创建一个指定名字的文件。

如果这个文件已经存在,那么 create 函数将截断这个文件。该函数返回一个文件描述符。

package main

import (
	"fmt"
	"os"
)

func main() {

	f, err := os.create("123.txt")
	if err != nil {
		fmt.println(err)
	}
	defer func() {
		if err = f.close(); err != nil {
			fmt.println(err)
		}
	}()

	_, err = f.writestring("hello world!")
	if err != nil {
		fmt.println(err)
	}
	fmt.println("文件写入成功!")
}

字节写入文件

  • 使用write方法可以写入字节数组数据。一般为字符对应的utf-8的10进制编码。
package main

import (
	"fmt"
	"os"
)

func main() {

	f, err := os.create("123.txt")
	if err != nil {
		fmt.println(err)
	}

	defer func() {
		if err = f.close(); err != nil {
			fmt.println(err)
		}
	}()

	bytes := []byte{104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}
	_, err = f.write(bytes)

	if err != nil {
		fmt.println(err)
	}
	fmt.println("文件写入完成")
}

逐行写入文件

  • 使用fmt.fprintln函数实现文件的逐行写入。
package main

import (
	"fmt"
	"os"
)

func main() {

	f, err := os.create("123.txt")
	if err != nil {
		fmt.println(err)
	}

	defer func() {
		if err = f.close(); err != nil {
			fmt.println(err)
		}
	}()

	lines := []string{"hello", "golang", "world"}

	for _, v := range lines {
		_, err = fmt.fprintln(f, v)
		if err != nil {
			fmt.println(err)
		}
	}

	fmt.println("文件写入完成.")
}

追加文件内容

  • os.openfile(name string, flag int, perm filemode) (*file, error)函数可以指定文件操作方式。
package main

import (
	"fmt"
	"os"
)

func main() {

	f, err := os.openfile("123.txt", os.o_append|os.o_rdonly, 0644)
	if err != nil {
		fmt.println(err)
	}

	defer func() {
		if err = f.close(); err != nil {
			fmt.println(err)
		}
	}()

	lines := []string{"123", "abc", "!@#"}

	for _, v := range lines {
		_, err = fmt.fprintln(f, v)
		if err != nil {
			fmt.println(err)
		}
	}

	fmt.println("文件追加写入完成.")
}

并发写文件

  • 注意文件写入时的竞态条件。
package main

import (
	"fmt"
	"math/rand"
	"os"
	"sync"
)

func main() {

	chnum := make(chan int)
	chexit := make(chan bool)
	wg := sync.waitgroup{}

	// 生产者
	for i := 0; i < 100; i++ {
		wg.add(1)
		go makerandom(chnum, &wg)
	}

	// 消费者
	go writefile(chnum, chexit)

	wg.wait()
	close(chnum)

	if <-chexit {
		fmt.println("文件写入成功.")
	} else {
		fmt.println("文件写入失败.")
	}

}

func makerandom(chnum chan int, wg *sync.waitgroup) {

	chnum <- rand.intn(1000)
	wg.done()

}

func writefile(chnum chan int, chexit chan bool) {

	f, err := os.create("123.txt")
	if err != nil {
		fmt.println(err)
	}
	defer func() {
		if err = f.close(); err != nil {
			fmt.println(err)
		}
	}()

	for val := range chnum {
		_, err = fmt.fprintln(f, val)
		if err != nil {
			fmt.println(err)
		}
	}

	chexit <- true
}