使用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文件打开方式
写模式打开时,有几种组合:
- 打开文件,没有此文件则报错: 只选择了打开模式(O_RDONLY、O_WRONLY、O_RDWR三者之一),没选择状体模式
- 打开文件,没有此文件则创建:状态模式选择O_CREATE,但没有同时选择O_EXCL
- 打开文件,如果此文件已存在则报错:状态模式选择O_CREATE和O_EXCL
- 写文件模式下,不选择O_APPEND则默认从头写,且可以自由f.Seek移动偏移量
- 写文件模式下,选择O_APPEND则从文件尾写入,尽管f.Seek可以移动偏移量,但最终写入仍然在尾部,但如果此时有读的权限,则总seek后的偏移量开始读。
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术