使用go routine操作同一个文件进行删除固定行

func main() {
	//type Dict map[string]interface{}
	//
	//dict := Dict{"name": "zhang", "age": 10}
	MyTestType(dict)
	//
	//var aa interface{}
	//aa = dict
	//
	//fmt.Println(MySet("zhang", dict))
	//
	//
	//switch aa.(type) {
	//	case map[string]string:
	//		fmt.Println("aaaa")
	//	case Dict: // 这里
	//		fmt.Println("bbbb")
	//	default:
	//		fmt.Print("cccc")
	//}


	// 利用goroutine来删除文件的某行

	f1, err := os.OpenFile("D:/video/aa.txt", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println("Open file error: ", err)
		return
	}
	defer f1.Close()

	f2, err := os.OpenFile("D:/video/aa.txt", os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println("Open file error: ", err)
		return
	}
	defer f2.Close()


	// 阻塞chan?
	ch := make(chan interface{}, 1)

	var wg sync.WaitGroup
	wg.Add(1)
	go func(ch chan interface{}, f *os.File, wg *sync.WaitGroup){
		defer wg.Done()
		have_write := false
	LOOP:
		for {
			select {
			case line, ok := <-ch:
				if ok {
					switch v := line.(type) {
					case string:
							fmt.Printf("--receive str: %v\n", v)
							f.Write([]byte(v))
							if !have_write {
								have_write = true
							}
					case int:
						if !have_write {
							// 说明是偏移量
							fmt.Printf("--receive seek: %v\n", v)
							ret, err := f.Seek(int64(v), 0) // 文件偏移
							if err != nil {
								fmt.Printf("seek error: %v\n", err)
							}
							fmt.Printf("seek %v bytes\n", ret)
						} else {
							// 说明是截断量
							fmt.Printf("--receive trunk: %v\n", v)
							f.Truncate(int64(v))
						}

					}
				} else {
					break LOOP
				}
			}
		}
	}(ch, f2, &wg)

	// 删除文件的第四行
	line_num := 0
	byte_count := 0
	have_send_num := false
	buf := bufio.NewReader(f1)
	delete_line_byte_count := 0
	for {
		line, err := buf.ReadString('\n')
		line_num += 1
		byte_count += len(line)

		fmt.Printf("line: %s, line_num: %d, byte_count: %d\n", line, line_num, byte_count)
		if err != nil {
			if err == io.EOF {
				// 不够三行的直接退出
				if have_send_num {
					ch <- line
				}
			} else {
				fmt.Println("Read file error: ", err)
			}
			break
		}

		// 已经读了三行,发送前三行的总数字
		if line_num == 3 {
			ch <- byte_count
			have_send_num = true
		}
		if line_num == 4 { delete_line_byte_count = len(line) }

		if have_send_num && line_num >= 5{
			ch <- line
		}
	}

	fileStat, _ := f1.Stat()
	fileSize := fileStat.Size()
	if delete_line_byte_count > 0 {
		ch <- int(fileSize) -  delete_line_byte_count
	}
	close(ch)

	wg.Wait()
	fmt.Println("copy success")

}

go文件打开方式
写模式打开时,有几种组合:

  1. 打开文件,没有此文件则报错: 只选择了打开模式(O_RDONLY、O_WRONLY、O_RDWR三者之一),没选择状体模式
  2. 打开文件,没有此文件则创建:状态模式选择O_CREATE,但没有同时选择O_EXCL
  3. 打开文件,如果此文件已存在则报错:状态模式选择O_CREATE和O_EXCL
  4. 写文件模式下,不选择O_APPEND则默认从头写,且可以自由f.Seek移动偏移量
  5. 写文件模式下,选择O_APPEND则从文件尾写入,尽管f.Seek可以移动偏移量,但最终写入仍然在尾部,但如果此时有读的权限,则总seek后的偏移量开始读。
    .
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值