go初识
- FileInfo接口
type FileInfo interface{
Name() string
Size() int64
Mode() FileMode//文件权限
ModTime() time.Time//修改时间
IsDir() bool//是否文件夹
Sys() interface{}//基础数据原接口
}
- 断点续传
package main
import (
"fmt"
"io"
"log"
"os"
"strconv"
)
func HandleErr(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
srcFile := "C:/Users/asus/go/src/不会/hello/test1.txt"
destFile := "C:/Users/asus/go/src/不会/hello/test2.txt"
tempFile := "C:/Users/asus/go/src/不会/hello/temp.txt"
file1, err := os.OpenFile(srcFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
HandleErr(err)
file2, err := os.OpenFile(destFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
HandleErr(err)
file3, err := os.OpenFile(tempFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
HandleErr(err)
defer file1.Close()
defer file2.Close()
//step1:先读取临时文件中的数据,再seek
file3.Seek(0, io.SeekStart)
bs := make([]byte, 100)
fmt.Println(bs)
n1, err := file3.Read(bs)
//HandleErr(err)
countStr := string(bs[:n1])
count, err := strconv.ParseInt(countStr, 10, 64)
//HandleErr(err)
fmt.Println(count)
//step2:设置读写的位置
file1.Seek(count, io.SeekStart)
file2.Seek(count, io.SeekStart)
data := make([]byte, 1024)
n2 := -1 //读取数据量
n3 := -1 //写入数据量
total := int(count) //读取的总量
//step3:复制文件
for {
n2, err = file1.Read(data)
if err == io.EOF || n2 == 0 {
fmt.Println("文件复制完毕。。。")
file3.Close()
os.Remove(tempFile)
break
}
n3, err = file2.Write(data[:n2])
HandleErr(err)
total = n3 + total
//将复制的总量,存储到临时文件中
file3.Seek(0, io.SeekStart)
file3.WriteString(strconv.Itoa(total))
fmt.Printf("total:%d\n", total)
}
}
-
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0 total:7 文件复制完毕。。。
- goroutine
封装main函数的goroutine称为主goroutine
同步等待组WaitGroup:
wg.Add(),设置等待组中要执行的子goroutine的数量
wg.wait(),让主goroutine处于等待直到WaitGroup为0
wg.done(),等待组减一
- channel
var a chan int
类型是chan int,指向nil
channel是nil,不能使用,需要先创建通道
a=make(chan int)
通道是goroutine之间的连接,所以通道的发送和接收必须在不同goroutine中
- 通道发送和接收
data:=<-a
a<-data
v,ok:=<-a
package main
import (
"fmt"
)
func main() {
//通过range访问通道
ch1 := make(chan int)
go sendData(ch1)
for v := range ch1 {
fmt.Println("读取数据:", v)
}
fmt.Println("main over...")
}
func sendData(ch1 chan int) {
for i := 0; i < 10; i++ {
ch1 <- i
}
close(ch1)
}
读取数据: 0
读取数据: 1
读取数据: 2
读取数据: 3
读取数据: 4
读取数据: 5
读取数据: 6
读取数据: 7
读取数据: 8
读取数据: 9
main over...
- 缓冲通道
ch:=make(chan type,capacity)
定向通道:chan <- int 单向,只能写,不能读
<- chan int 单向,只能读,不能写
- select
select{
case ...:
...
case ...:
....
default:
...
}
类似switch语句,但是select语句会随机执行一个可执行的case,如果没有case可以执行,要看是否有default,如果有就执行defualt,否则久进入阻塞,直到有case可以执行
每个case必须是一个通信
- 反射
通过反射,可以获取一个接口类型变量的类型和数值