├── io_pro ├── aa1.txt ├── main │ ├── BaseConversion.go │ ├── ListenIpudp.go │ ├── ListenTcp.go │ ├── ListenTcp1.go │ ├── ListenUdp.go │ ├── ListenUnix.go │ ├── aa.txt │ ├── archive_tar.go │ ├── archive_tar_01.go │ ├── archive_tar_02.go │ ├── archive_zip_01.go │ ├── archive_zip_02.go │ ├── archive_zip_03.go │ ├── bufio_Reader.go │ ├── bufio_Scanner_01.go │ ├── bufio_Scanner_02.go │ ├── bufio_Scanner_03.go │ ├── bufio_Writer.go │ ├── bytes+strings_01.go │ ├── bytes_Buffer_01.go │ ├── bytes_Reader_01.go │ ├── bzip2 │ │ ├── aa.txt │ │ ├── aa.txt.bz2 │ │ ├── bzip2.txt │ │ └── e.txt.bz2 │ ├── compress_bzip2.go │ ├── compress_flate.go │ ├── compress_gzip.go │ ├── compress_gzip_01.go │ ├── compress_lzw.go │ ├── compress_zlib.go │ ├── dialDNSUdp.go │ ├── dst_tar │ │ └── text.tar │ ├── encoding.md │ ├── encoding_ascii85.go │ ├── encoding_asn1.go │ ├── encoding_asn1_01.go │ ├── encoding_base32.go │ ├── encoding_base64.go │ ├── encoding_binary.go │ ├── encoding_csv.go │ ├── encoding_gob.go │ ├── encoding_gob_01.go │ ├── encoding_hex.go │ ├── encoding_json_01.go │ ├── encoding_json_02.go │ ├── encoding_pem.go │ ├── encoding_xml.go │ ├── encoding_xml_01.go │ ├── encoding_xml_02.go │ ├── flag_01.go │ ├── flag_02.go │ ├── flag_03.go │ ├── flate │ │ ├── flate.txt │ │ └── flate_dst.txt │ ├── fmt.go │ ├── github.com.axgle.mahonia.go │ ├── go_scanner.go │ ├── golang.org.x.text.go │ ├── gzip │ │ ├── dst.gz │ │ ├── dst2.gz │ │ ├── gzip.txt │ │ └── gzip02.txt │ ├── html.go │ ├── html_template.go │ ├── index2.go │ ├── io_01.go │ ├── io_ioutil_01.go │ ├── io_ioutil_02.go │ ├── log.go │ ├── log │ │ ├── log.txt │ │ └── output.txt │ ├── log_syslog.md │ ├── lzw │ │ ├── .idea │ │ │ ├── lzw.iml │ │ │ ├── misc.xml │ │ │ ├── modules.xml │ │ │ └── workspace.xml │ │ ├── lzw.txt │ │ ├── lzw_dst.pdf │ │ ├── lzw_dst.txt │ │ └── lzw_src.pdf │ ├── math_01.go │ ├── math_big.go │ ├── math_cmplx.md │ ├── math_rand.go │ ├── mytemp │ │ ├── templ1.txt │ │ └── templ2.txt │ ├── net.go │ ├── os_02.go │ ├── os_03.go │ ├── os_04.go │ ├── os_05.go │ ├── os_exec_03.go │ ├── os_signal_01.go │ ├── os_signal_02.go │ ├── os_signal_03.go │ ├── os_user_01.go │ ├── path_01.go │ ├── path_filepath.go │ ├── pic │ │ ├── image-20191201182115354.png │ │ ├── image-20191201182548667.png │ │ ├── image-20191201182557772.png │ │ ├── image-20191201182734459.png │ │ ├── image-20191201183128167.png │ │ ├── image-20191201183232729.png │ │ ├── image-20191201183452657.png │ │ ├── image-20191201183742563.png │ │ ├── image-20191201183918097.png │ │ ├── image-20191201185235815.png │ │ ├── image-20191201192742193.png │ │ ├── image-20191201192834669.png │ │ └── image-20191201192855541.png │ ├── reflect_01.go │ ├── reflect_02.go │ ├── reflect_03.go │ ├── regexp.go │ ├── regexp_syntax.go │ ├── sort_01.go │ ├── sql.go │ ├── sql_01.go │ ├── sql_driver.go │ ├── sql_regester().go │ ├── strconv_01.go │ ├── tar_data │ │ ├── text1.txt │ │ └── text2.txt │ ├── test.txt │ ├── test111.txt │ ├── test222.txt │ ├── test3.txt │ ├── text_scanner_01.go │ ├── text_scanner_02.go │ ├── text_tabwriter_01.go │ ├── text_tabwriter_02.go │ ├── text_template_01.go │ ├── text_template_parse.md │ ├── time_01.go │ ├── time_02.go │ ├── unicode_01.go │ ├── unicode_utf16.md │ ├── unicode_utf8_01.go │ ├── zip │ │ ├── aa.zip │ │ ├── text1.txt │ │ ├── zip_01.zip │ │ └── zip_02.zip │ └── zlib │ │ ├── zlib01.txt │ │ └── zlib01_compress.txt ├── main2 │ ├── encoding_asn1_02.go │ └── 包说明.md ├── main3 │ ├── compress_zlib.go │ ├── log │ │ ├── log.txt │ │ └── output.txt │ ├── mytemp │ │ ├── templ1.txt │ │ └── templ2.txt │ ├── text_template_parse.assets │ │ ├── image-20191201182115354.png │ │ ├── image-20191201182548667.png │ │ ├── image-20191201182557772.png │ │ ├── image-20191201182734459.png │ │ ├── image-20191201183128167.png │ │ ├── image-20191201183232729.png │ │ ├── image-20191201183452657.png │ │ ├── image-20191201183742563.png │ │ ├── image-20191201183918097.png │ │ ├── image-20191201185235815.png │ │ ├── image-20191201192742193.png │ │ ├── image-20191201192834669.png │ │ └── image-20191201192855541.png │ ├── text_template_parse.md │ └── 包说明.md ├── test │ ├── config.xml │ ├── test01.go │ ├── test02.go │ ├── test03.go │ ├── test04.go │ ├── test05.go │ ├── test06.go │ ├── test07.go │ ├── test08.go │ ├── test09.go │ ├── test10.go │ ├── test11.go │ ├── test12.go │ ├── test13.go │ ├── test14.go │ ├── test15.go │ ├── test16.go │ ├── test17.go │ ├── test18.go │ ├── test19.go │ ├── test20.go │ ├── test21.go │ ├── test22.go │ ├── test23.go │ ├── test24.go │ ├── test25.go │ ├── test26.go │ ├── test27.go │ ├── test28.go │ ├── test29.go │ ├── test30.go │ ├── test31.go │ ├── test32.go │ ├── test33.go │ ├── test34.go │ ├── test35.go │ ├── test36.go │ ├── test37.go │ ├── test38.go │ ├── test39.go │ ├── test40.go │ ├── test41.go │ ├── test42.go │ ├── test43.go │ ├── test44.go │ ├── test45.go │ ├── test46.go │ ├── test47.go │ ├── test48.go │ ├── test49.go │ ├── test50.go │ ├── testdir │ │ ├── 1.txt │ │ ├── 2.txt │ │ ├── sum.go │ │ └── test16.go │ └── 包说明.md ├── test1.txt ├── test2.txt ├── test3.txt └── test4.txt └── readme.md /io_pro/aa1.txt: -------------------------------------------------------------------------------- 1 | nihao a a -------------------------------------------------------------------------------- /io_pro/main/BaseConversion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | "fmt" 7 | "log" 8 | "math" 9 | "strconv" 10 | "strings" 11 | "unicode/utf8" 12 | ) 13 | 14 | func main() { 15 | r := "世" 16 | fmt.Println(bytes.NewBufferString(r).Bytes()) 17 | 18 | b1:='世' 19 | fmt.Println("----",strconv.QuoteRune(b1)) 20 | buf := make([]byte, 3) 21 | n := utf8.EncodeRune(buf, b1) 22 | fmt.Println(buf) 23 | fmt.Println(n) 24 | 25 | 26 | //b := []byte{0x00, 0x00, 0x03, 0xe8} 27 | //b := []byte{ 0x96, 0xb8,0xe4 } 28 | //bytesBuffer := bytes.NewBuffer(b) 29 | ////var x int32 30 | //var x rune//两种都可以 31 | //binary.Read(bytesBuffer, binary.BigEndian, &x) 32 | //fmt.Println(x) 33 | 34 | //int8类型的rune转[]byte类型 35 | var x int32 36 | //x = 97两种都可以 37 | x = 'a' 38 | bytesBuffer := bytes.NewBuffer([]byte{}) 39 | binary.Write(bytesBuffer, binary.BigEndian, x) 40 | fmt.Println(bytesBuffer.Bytes()) 41 | fmt.Println(rune(bytesBuffer.Bytes()[3])) 42 | 43 | 44 | //var x int32 45 | //x = '世' 46 | //bytesBuffer := bytes.NewBuffer([]byte{}) 47 | //binary.Write(bytesBuffer, binary.BigEndian, x) 48 | //fmt.Println(bytesBuffer.Bytes()) 49 | //by:=bytesBuffer.Bytes() 50 | //fmt.Println(by[2],by[3]) 51 | //fmt.Printf("%T---%T\n",Dec2Bin(int64(by[2])),Dec2Bin(int64(by[3]))) 52 | //fmt.Println(Dec2Bin(int64(by[2])),Dec2Bin(int64(by[3]))) 53 | //str111:=Dec2Bin(int64(by[2])) + Dec2Bin(int64(by[3])) 54 | //fmt.Println(str111) 55 | ////strconv.Atoi(str111) 56 | //str222:=Bin2Dec(str111) 57 | //fmt.Println(str222) 58 | //fmt.Printf("%T",str222) 59 | //fmt.Printf("%q\n",str222) 60 | //fmt.Println(string(str222))//string值得是编码int类型,但是不是将int字面值原样转成字符串 61 | 62 | } 63 | 64 | 65 | 66 | 67 | //256以下的十进制转二进制,并且在绝对保证8位形式的二进制格式 68 | func Dec2Bin(n int64) string { 69 | if n < 0 { 70 | log.Println("Decimal to binary error: the argument must be greater than zero.") 71 | return "" 72 | } 73 | if n == 0 { 74 | return "0" 75 | } 76 | s := "" 77 | for q := n; q > 0; q = q / 2 { 78 | m := q % 2 79 | s = fmt.Sprintf("%v%v", m, s) 80 | } 81 | //------------------------------------------------ 82 | //这里是我自己添加的。因此限制了能转换的十进制只能是256的最大值 83 | fmt.Println(s,len(s)) 84 | if len(s)<8{ 85 | length:=8-len(s) 86 | //编程误区,因为在for的里面修改了s的长度,同时我们每次循环都会去判断s的长度,导致循环的次数不对 87 | //所以我们要先获取到对象的长度然后再遍历 88 | for i:=0 ;i 0}} 105 | // Addr: 127.0.0.1:9996 106 | // Addr.String(): 127.0.0.1:9996 107 | // Addr.Network(): tcp 108 | // 正在等待客户端请求。。。 109 | // tcpConn.LocalAddr() 127.0.0.1:9996 110 | // tcpConn.RemoteAddr() 127.0.0.1:9994 111 | // tcp服务器读取来自客户端的字节数为: 42 112 | // tcp服务器读取来自客户端的字节数据为: [232 191 153 230 152 175 229 174 162 230 136 183 231 171 175 229 143 145 233 128 129 231 154 132 116 99 112 230 149 176 230 141 174 227 128 130 227 128 130 227 128 130 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] 113 | // tcp服务器读取来自客户端的字节转字符串数据为: 这是客户端发送的tcp数据。。。 114 | // 服务器接收到了客户端的数据完毕!! 115 | // 116 | // tcp服务器响应给客户端的字节数为: 49 117 | // tcp服务器响应给客户端的字节转字符串数据为: 这是tcp服务器响应给客户端的内容2222 118 | // 服务器响应完毕!! 119 | } 120 | func check_err_net(err error) { 121 | if err != nil { 122 | //fmt.Fprintln(os.Stderr,err) 123 | //上面的这种方式会导致输出顺序不确定,虽然他可以输出红色的字体,但是由于顺序不确定,我们不采用他! 124 | fmt.Println("出错了,错误信息为:", err) 125 | panic(err) 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /io_pro/main/ListenUdp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | //这个文件作为udp的服务器端来使用 9 | func main() { 10 | la, err := net.ResolveUDPAddr("udp4", "127.0.0.1:8888") //这个端口千万年不要和上部分测试的tcp使用的端口9999相同,否则会报错 11 | check_err_net(err) 12 | //net.ListenTCP()返回值是一个tcp监听器*TCPListener对象,但是为什么下面的net.ListenUDP()确实返回一个*UDPConn呢? 13 | //因为tcp才需要建立连接,而udp是不需要建立连接的额!所以不存在监听器,直接创建一个*UDPConn对象直接读取和写入即可! 14 | //*UDPConn对象的更多方法将会在客户端中进行探索而不是在这里的服务端进行探索!请到客户端在去查看! 15 | udpListener, err := net.ListenUDP("udp4", la) //监听9999端口,从这个端口接收发送端发送过来的数据! 16 | check_err_net(err) 17 | fmt.Println("tcpListener:", udpListener) 18 | 19 | defer udpListener.Close() 20 | 21 | //直接进行读取即可,不存在监听的过程!这就是udp有别于tcp的地方!这里会阻塞到一直接收到数据为止! 22 | read_by := make([]byte, 100) 23 | i, err := udpListener.Read(read_by) 24 | check_err_net(err) 25 | 26 | fmt.Println("udp服务器接收到客户端的字节数为:", i) 27 | fmt.Println("udp服务器接收到客户端的字节数据为:", read_by) 28 | fmt.Println("udp服务器接收到客户端的字节转字符串数据为:", string(read_by)) 29 | fmt.Println("udp服务器接收完毕!!") 30 | 31 | fmt.Println() 32 | //write_i, err := udpListener.Write([]byte("这是udp服务器发送给客户端的数据2222")) 33 | //注意在tcp是长连接所以不会指定对方的地址都是可以直接发送数据的,只要客户端请求进来,那么服务器发送数据时候是不用再指定 34 | //对方的地址的了,但是udp是短连接,他虽然也是全双工通信,但是还是需要指定对方的地址才可以进行发送数据回头的! 35 | //事实上这个write()方法是UDPConn组合下的conn对象上面的方法,这是go库 api设计需要改进的地方,既然有这个方法,但是却不能被调用, 36 | //这是非常不人道的行为!切记我们在设计api时候不要这样做,如果他们的行为不完全一样,那么就不要生搬硬套,而是因为抽象出共同的行为来新建 37 | // 一个接口或者结构体,最后组合这个结构体或者接口即可! 38 | //假如采用上面的方式的话则会抛出这个错误: 39 | // 出错了,错误信息为: write udp4 127.0.0.1:8888: wsasend: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. 40 | // panic: write udp4 127.0.0.1:8888: wsasend: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. 41 | // 42 | // goroutine 1 [running]: 43 | // main.check_err_net(0x524880, 0xc0000a4000) 44 | // C:/Users/Administrator/Desktop/go_pro/src/io_pro/main3/ListenUdp.go:56 +0xdd 45 | // main.main() 46 | // C:/Users/Administrator/Desktop/go_pro/src/io_pro/main3/ListenUdp.go:33 +0x53c 47 | //错误信息的意思是: 48 | // 不允许发送或接收数据的请求,因为未连接套接字,并且(当使用sendto调用在数据报套接字上发送时)未提供地址。 49 | 50 | //这里我们不能写回这个8888端口,这个端口一定要是客户端中监听的7777端口!一个端口在udp中不能享有读和写功能,但是在tcp中是可以的! 51 | //然而udp中要分开来! 52 | // 53 | ra, err := net.ResolveUDPAddr("udp4", "127.0.0.1:7777") 54 | check_err_net(err) 55 | 56 | write_i, err := udpListener.WriteTo([]byte("这是udp服务器发送给客户端的数据2222"), ra) 57 | check_err_net(err) 58 | fmt.Println("udp服务器响应给客户端的字节个数为:", write_i) 59 | if write_i == 0 { 60 | fmt.Println("未发送任何数据给客户端,发生了错误!请检查!") 61 | } 62 | fmt.Println("udp服务器响应给客户端的字节数据为:", "这是udp服务器发送给客户端的数据2222") 63 | fmt.Println("udp服务器响应完毕!!") 64 | 65 | //此服务器端中的输出为:(注意先要运行服务器代码,然后才能运行客户端的代码) 66 | // tcpListener: &{{0xc00007ca00}} 67 | // udp服务器接收到客户端的字节数为: 60 68 | // udp服务器接收到客户端的字节数据为: [232 191 153 230 152 175 229 174 162 230 136 183 231 171 175 229 143 145 233 128 129 231 187 153 230 69 | // 156 141 229 138 161 229 153 168 231 171 175 231 154 132 228 191 161 230 129 175 49 49 49 117 100 112 67 111 110 110 32 116 101 115 116 70 | // 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] 71 | // udp服务器接收到客户端的字节转字符串数据为: 这是客户端发送给服务器端的信息111udpConn test 72 | // udp服务器接收完毕!! 73 | // 74 | // udp服务器响应给客户端的字节个数为: 49 75 | // udp服务器响应给客户端的字节数据为: 这是udp服务器发送给客户端的数据2222 76 | // udp服务器响应完毕!! 77 | 78 | } 79 | func check_err_net(err error) { 80 | if err != nil { 81 | //fmt.Fprintln(os.Stderr,err) 82 | //上面的这种方式会导致输出顺序不确定,虽然他可以输出红色的字体,但是由于顺序不确定,我们不采用他! 83 | fmt.Println("出错了,错误信息为:", err) 84 | panic(err) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /io_pro/main/aa.txt: -------------------------------------------------------------------------------- 1 | readme.txt0000000000000000000000000000004600000000000011165 0ustar0000000000000000This archive contains some text files.gopher.txt0000000000000000000000000000004300000000000011211 0ustar0000000000000000Gopher names: 2 | George 3 | Geoffrey 4 | Gonzotodo.txt0000000000000000000000000000003400000000000010672 0ustar0000000000000000Get animal handling licence. -------------------------------------------------------------------------------- /io_pro/main/archive_tar_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/tar" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | 11 | fmt.Println("-----------快速获取一个文化的元数据------------") 12 | //创建软连接文件,如果已经存在的话则会报错 13 | //symlink_err := os.Symlink("main/tar_data/text1.txt", "main/tar_02/text1_Symlink.lnk") 14 | //checkErr_tar(symlink_err) 15 | //time.Sleep(2e9) 16 | file, e := os.Open("main/tar_data/text1.txt") 17 | checkErr_tar(e) 18 | info, e := file.Stat() 19 | checkErr_tar(e) 20 | //wt := tar.NewWriter(file) 21 | // FileInfoHeader从fi创建一个部分填充的Header。 22 | //如果fi描述了符号链接,则FileInfoHeader会将链接记录为链接目标。 23 | //如果fi描述目录,则在名称后添加斜杠。 24 | //由于os.FileInfo的Name方法仅返回其描述的文件的基本名称,因此可能有必要修改Header.Name以提供文件的完整路径名。 25 | //说白了就是快速获取一个文化的元数据 26 | h, e := tar.FileInfoHeader(info, "") 27 | //h, e := tar.FileInfoHeader(info, "main/tar_data/text1.txt")//似乎第二个参数写跟没写都一样不起作用的!暂时不知道怎么用! 28 | checkErr_tar(e) 29 | printHeaderinfo(h) 30 | //输出: 31 | // -----------快速获取一个文化的元数据------------ 32 | // ----下面是获取当前tar文件的header对象的一些信息---- 33 | // FileInfo().Sys()总信息: &{48 text1.txt 727 438 0 0 2019-10-16 14:58:40.9768512 +0800 CST 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC 0 0 map[] map[] } 34 | // Typeflag是标题条目的类型: 48 35 | // 文件入口名称: text1.txt 36 | // 链接的目标名称: 37 | // 逻辑文件大小: 727 38 | // 权限和模式位(二进制表示):110110110 39 | // 所有者的用户标识: 0 40 | // 所有者的组ID: 0 41 | // 所有者的用户名: 42 | // 所有者的组名: 43 | // 修改时间: 2019-10-16 14:58:40.9768512 +0800 CST 44 | // 访问时间: 0001-01-01 00:00:00 +0000 UTC 45 | // 更改时间: 0001-01-01 00:00:00 +0000 UTC 46 | // 主设备号: 0 47 | // 次设备号: 0 48 | // PAX扩展头记录的映射: map[] 49 | // tar标头的格式: 50 | // ----------------------------- 51 | //关于header的更多信息请参考https://blog.csdn.net/lichangrui2009/article/details/85995620 52 | 53 | 54 | 55 | } 56 | func checkErr_tar(err error) { 57 | if err != nil{ 58 | fmt.Println(err) 59 | } 60 | } 61 | 62 | func printHeaderinfo(h *tar.Header) {//这样表示的是*Header而不是*tar 63 | fmt.Println("----下面是获取当前tar文件的header对象的一些信息----") 64 | fmt.Println("FileInfo().Sys()总信息:", h.FileInfo().Sys()) 65 | fmt.Println("Typeflag是标题条目的类型:", h.Typeflag) // Typeflag是标题条目的类型。根据Name中是否存在尾部斜杠,零值会自动提升为TypeReg或TypeDir。 66 | fmt.Println("文件入口名称:", h.Name) //文件入口名称 67 | fmt.Println("链接的目标名称:", h.Linkname) //链接的目标名称(对TypeLink或TypeSymlink有效) 68 | fmt.Println("逻辑文件大小:", h.Size) //逻辑文件大小(以字节为单位) 69 | fmt.Printf("权限和模式位(二进制表示):%b\n", h.Mode) //权限和模式位 70 | fmt.Println("所有者的用户标识:", h.Uid) //所有者的用户标识 71 | fmt.Println("所有者的组ID:", h.Gid) //所有者的组ID 72 | fmt.Println("所有者的用户名:", h.Uname) //所有者的用户名 73 | fmt.Println("所有者的组名:", h.Gname) //所有者的组名 74 | fmt.Println("修改时间:", h.ModTime) //修改时间 75 | fmt.Println("访问时间:", h.AccessTime) //访问时间(需要PAX或GNU支持) 76 | fmt.Println("更改时间:", h.ChangeTime) //更改时间(需要PAX或GNU支持) 77 | fmt.Println("主设备号:", h.Devmajor) //主设备号(对TypeChar或TypeBlock有效) 78 | fmt.Println("次设备号:", h.Devminor) //次设备号(对TypeChar或TypeBlock有效) 79 | fmt.Println("PAX扩展头记录的映射:", h.PAXRecords) // PAXRecords是PAX扩展头记录的映射。 80 | fmt.Println("tar标头的格式:", h.Format) // Format指定tar标头的格式。 81 | fmt.Println("-----------------------------") 82 | 83 | } -------------------------------------------------------------------------------- /io_pro/main/archive_zip_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/zip" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | type MynopCloser struct { 10 | io.Writer 11 | } 12 | 13 | func (w MynopCloser) Close() error { 14 | return nil 15 | } 16 | 17 | func main() { 18 | // Compressor返回一个新的压缩编写器,写入w。 19 | //必须使用WriteCloser的Close方法将待处理数据刷新到w。 20 | // Compressor本身必须可以安全地同时从多个goroutine调用,但是每个返回的writer一次只能由一个goroutine使用。 21 | 22 | 23 | //首先创建一个文件 24 | _, e := os.OpenFile("main/zip/zip1.zip", os.O_CREATE, 777)//打开新建的压缩zip文件准备读写 25 | checkErr_zip(e) 26 | 27 | 28 | file_dst, e := os.OpenFile("main/zip/zip1.zip", os.O_RDWR, 777)//打开新建的压缩zip文件准备读写 29 | checkErr_zip(e) 30 | var zipCom zip.Compressor//zipCom是一个接收装载器的压缩写入器函数 31 | zipCom=func(w io.Writer) (io.WriteCloser, error) { return &MynopCloser{w}, nil } 32 | wtCloser, e := zipCom(file_dst) 33 | checkErr_zip(e) 34 | 35 | checkErr_zip(e) 36 | //打开要压缩的文件 37 | file_src, e := os.OpenFile("main/tar_data/text1.txt", os.O_RDWR, 777)//打开文件准备读写 38 | checkErr_zip(e) 39 | info_src, e := file_src.Stat() 40 | checkErr_zip(e) 41 | byte_src:=make([]byte,info_src.Size()) 42 | n, e := file_src.Read(byte_src) 43 | checkErr_zip(e) 44 | fmt.Println("要压缩的文件的字符串是:",string(byte_src)) 45 | fmt.Println("要压缩的文件的字节数是:",n) 46 | //开始将text1中的字节写入压缩文件中去 47 | i, e := wtCloser.Write(byte_src) 48 | checkErr_zip(e) 49 | 50 | fmt.Println("成功写入压缩文件的字节数是(只有这个值等于上面的要压缩的文件的字节数的话才是成功写入了):",i) 51 | 52 | defer func() { 53 | e2 := wtCloser.Close() 54 | checkErr_zip(e2) 55 | e2 = file_src.Close() 56 | checkErr_zip(e2) 57 | e2 = file_dst.Close() 58 | checkErr_zip(e2) 59 | }() 60 | 61 | } 62 | func checkErr_zip(err error) { 63 | if err != nil{ 64 | fmt.Println(err) 65 | } 66 | } -------------------------------------------------------------------------------- /io_pro/main/archive_zip_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/zip" 5 | "fmt" 6 | "io" 7 | "log" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | //Reader结构体说明 13 | //type Reader struct { 14 | // r io.ReaderAt //表示从哪里开始读 15 | // File []*File //看下面,相当于压缩文件中的1个源数据(或者键一个文件),这个相当于File的管理器 16 | // Comment string //压缩包的注释 17 | // decompressors map[uint16]Decompressor //解压器对象的map 18 | //} 19 | 20 | //File结构体说明 21 | //type File struct { 22 | // FileHeader //这个是FileHeader结构体,所以他相当于FileHeader的读取管理器 23 | // zip *Reader //读取器接口 24 | // zipr io.ReaderAt //读取接口 25 | // zipsize int64 //压缩包的大小 26 | // headerOffset int64 //读取文件的指针 27 | //} 28 | 29 | //-------------------------第一种声明读取器的方式------------------------------- 30 | //打开一个zip存档以供阅读。 31 | // OpenReader将打开按名称指定的Zip文件,并返回ReadCloser。 32 | //底层是通过os.open以及os.stat和init()3个方法来进行实现的(init方法才是真正的OpenReader,不过跟函数名字不大搭配) 33 | //r, err := zip.OpenReader("main/zip/zip_02.zip") 34 | //-----------------------------第2种声明读取器的方式--------------------------- 35 | //上面的方法是下面的方法的封装,多数情况下采用上面的方法会更便捷 36 | f, err := os.Open("main/zip/zip_02.zip") 37 | check_err_zip(err) 38 | fi, err := f.Stat() 39 | if err != nil { 40 | fmt.Println(err) 41 | f.Close()//如果出错直接关闭并且停止main函数 42 | return 43 | } 44 | // NewReader从r返回一个新的Reader读数,假定具有给定的字节大小(zip的字节大小)。 45 | r, err := zip.NewReader(f, fi.Size())//os.File对象实现了io.ReaderAt()方法 46 | if err != nil { 47 | log.Fatal(err) 48 | } 49 | //-------------------------------------------------------- 50 | //因为上面提供了2中方式的创建压缩读取器,所以下面的关闭也展示了2中不同的关闭方式,除此之外无他区别了! 51 | //close关闭Zip文件,使其无法用于I/O。 52 | //底层是调用了File.close()方法,下面是这个方法的说明。说明这个方法会关闭处于打开状态的的压缩文件和压缩文件里面的文件。 53 | // Close关闭文件,使其无法用于I / O。 54 | //在支持SetDeadline的文件上,所有挂起的I / O操作都将被取消并立即返回错误。 55 | //如果已调用Close,则将返回错误。 56 | //defer r.Close()//这是ReadCloser对象才需要写这句代码,如果是Reader的话是不需要写的 57 | 58 | defer f.Close()//这句话就相当于上面的底层的主要实现,这句代码是Reader才需要写的 59 | 60 | //遍历档案中的文件,打印其中的一些内容。 61 | for _, f := range r.File { 62 | fmt.Printf("Contents of %s:\n", f.Name) 63 | // DataOffset返回文件的可能经过压缩的数据(压缩包里面的文件不是绝对会压缩数据的)相对于zip文件开头的偏移量。 64 | //大多数调用者应该改用Open,它透明地解压缩数据并验证校验和。 65 | //主要是通过findBodyOffset()方法实现的 66 | fmt.Println(f.DataOffset()) 67 | 68 | // Open返回一个ReadCloser,它提供对文件内容的访问。 69 | //可以同时读取多个文件。 70 | //底层实现主要方法是io.NewSectionReader,findBodyOffset(),zip.decompressor方法, 71 | // open根本不是通过DataOffset()方法来实现的,取而代之的是findBodyOffset()方法(DataOffset()的底层就是通过这个方法实现的) 72 | rc, err := f.Open() 73 | if err != nil { 74 | log.Fatal(err) 75 | } 76 | // CopyN将n个字节(或直到出错)从src复制到dst。 77 | //返回复制的字节数以及复制时遇到的最早错误。 78 | //返回时,当且仅当err == nil时才writter== n。 79 | //如果dst实现了ReaderFrom接口,则使用该接口实现副本。 80 | //底层是通过Copy(dst, LimitReader(src, n))来实现的 81 | _, err = io.CopyN(os.Stdout, rc, f.FileInfo().Size())//基本在Fileheader里面的方法都是可以在File中调用的 82 | if err != nil { 83 | log.Fatal(err) 84 | } 85 | rc.Close()//关闭io的读取关闭器,注意不是关不压缩文件读取关闭器 86 | fmt.Println() 87 | //输出: 88 | // Contents of text1.txt: 89 | // 39 ,说明从第39个字节开始是text1.txt的数据 90 | // a1111111adsdsdsd李克强在致辞中代表中国政府和人民祝贺本届世园会成功举办,并对支持和参与北京世园会的各国朋友致以谢意。他表示,本届世园会以“绿色生活,美丽家园”为主题,精彩纷呈、成果丰硕。 91 | // 在开幕式上,中国国家主席习近平倡导共同建设美丽地球家sdsdsdsd园、构建人类命运共同体。这是一场文明互鉴的绿色盛会,促进了各国文明交流、民心相通和绿色合作。这是一场创新荟萃的科技盛会,展现了绿色科技应用的美好前景。 92 | // 这是一场走进自然的体验盛会,中外访客用心感受环保与发展相互促进、人与自然和谐共处的美好。sdsdsds 93 | // Contents of text2.txt: 94 | // 586 ,说明从第586个字节开始是text2.txt的数据 95 | // 2222222222“保持中美关aaabbbb系健康稳定发展,对两国对世界都有利。双方要坚持协abc调、合作、稳定的基调,在相互尊重基础上管控分歧,在互惠互利基础上拓展合作,推动两国关系沿着正确轨道向前发展。” 96 | // 习近平主席在致特朗普总统的口信中强调了中方主张,特朗普总统请刘鹤副总理转达对习近平主席的感谢,并明确表示“美中经贸磋商取得了实质性的第一阶段成果,这对美中两国和世界都是重大利好”。abc 97 | 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /io_pro/main/bufio_Scanner_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("===================================") 12 | //Scanner类型提供了方便的读取数据的接口,如从换行符分隔的文本里读取每一行。 13 | // 14 | //成功调用的Scan方法会逐步提供文件的token令牌字节切片,跳过token令牌字节切片之间的字节。token令牌字节切片由SplitFunc类型的分割函数指定; 15 | //默认的分割函数会将输入分割为多个行,并去掉行尾的换行标志。本包预定义的分割函数可以将文件分割为行、字节、 16 | //unicode码值、空白分隔的word。调用者可以定制自己的分割函数。 17 | // 18 | //scan扫描会在抵达输入流结尾、遇到的第一个I/O错误、token过大不能保存进缓冲时,不可恢复的停止。当扫描停止后, 19 | //当前读取位置可能会远在最后一个获得的token后面。需要更多对错误管理的控制或token很大,或必须从reader连续扫描的程序, 20 | //应使用bufio.Reader代替。 21 | 22 | //下面几句是错误的示范 23 | //sReader := strings.NewReader("wvzz") 24 | //scanner := bufio.NewScanner(sReader) 25 | //fmt.Println(scanner.Bytes()) 26 | //fmt.Println(scanner.Text()) 27 | 28 | // An artificial input source. 29 | const input = "1234 5678 123456789" 30 | // NewScanner返回一个新的Scanner以从r中读取。 31 | //拆分功能默认为ScanLines。 32 | scanner := bufio.NewScanner(strings.NewReader(input)) 33 | // SplitFunc是用于对输入进行标记化的split函数的签名。 34 | // 参数data是剩余的未处理数据的初始子字符串(不是token令牌字节切片) 35 | // 参数atEOF标志, 该标志报告Reader是否没有更多数据可提供。 36 | // 返回值advance是推进输入的字节数,以及返回给用户的下一个tokon(如果有)以及err(如果有)。 37 | //如果函数返回错误,扫描将停止,在这种情况下,某些输入可能会被丢弃。 38 | //否则,扫描仪将前进输入(advance+1)。如果token令牌字节切片不是nil(说明遇到空格了),则扫描程序会将其返回给用户。如果token令牌字节切片为nil,则扫描程序将读取更多数据并继续扫描; 39 | //检查参数atEOF,如果没有更多数据-如果atEOF为true(说明没有更多数据了)-扫描程序将返回。如果数据还没有完整的令牌,例如,如果在扫描行时没有换行符, 40 | // 则SplitFunc可以返回(0,nil,nil),以指示扫描程序将更多数据读取到切片中,并尝试使用更长的时间切片从输入中的同一点开始。 41 | //除非atEOF为true,否则永远不要使用空数据片调用该函数。但是,如果atEOF为true,则数据可能为非空,并且一如既往地保留未处理的文本。 42 | 43 | //通过包装现有的ScanWords函数来创建自定义拆分函数。 44 | split := func(data []byte, atEOF bool) (advance int, token []byte, err error) { 45 | // ScanWords是扫描程序的拆分功能,它返回每个空格分隔的文本单词,并删除周围的空格。 46 | // 它永远不会返回空字符串。 空间的定义由unicode.IsSpace设置。 47 | advance, token, err = bufio.ScanWords(data, atEOF) 48 | if err == nil && token != nil { 49 | //最多能转化10位数字(二进制是31位),如果参数改为64的话最多可以容纳19位数字 50 | _, err = strconv.ParseInt(string(token), 10, 64) 51 | } 52 | return 53 | } 54 | //Split()设置扫描仪的分割功能。 55 | //默认的拆分功能是ScanLines。 56 | //如果在扫描开始后调用了panic,则将其拆分。 57 | 58 | // 指定分割函数 59 | scanner.Split(split) 60 | 61 | //Scan()会将扫描程序前进到下一个令牌,然后可以通过Bytes或Text方法使用它。 当扫描停止(到达输入结尾或错误)时,它将返回false。 62 | //在Scan返回false之后,Err方法将返回扫描期间发生的任何错误,但如果是io.EOF,Err将返回nil。 63 | //如果split函数在不提前输入的情况下返回了太多的空令牌,请扫描恐慌。 这是扫描仪的常见错误模式。 64 | //下面是验证输入 65 | for scanner.Scan() { 66 | //Bytes方法返回最近一次Scan调用生成的token。底层数组指向的数据可能会被下一次Scan的调用重写。 67 | fmt.Println(scanner.Bytes()) 68 | //Text()返回通过调用Scan生成的最新令牌,作为保留其字节的新分配字符串。 69 | fmt.Printf("%s\n", scanner.Text()) 70 | } 71 | //Bytes方法返回最近一次Scan调用生成的token。底层数组指向的数据可能会被下一次Scan的调用重写。 72 | fmt.Println(scanner.Bytes())//[],读完了,所以空 73 | if err := scanner.Err(); err != nil { 74 | fmt.Printf("Invalid input: %s", err)//Invalid input: strconv.ParseInt: parsing "1234567901234567890": value out of range 75 | } 76 | 77 | //附录Scanner结构体字段参数: 78 | // r io.Reader //客户端提供的读取器。 79 | // split SplitFunc //拆分令牌字节切片的函数。 80 | // maxTokenSize int //令牌字节切片的最大大小; 通过测试修改。 81 | // token []byte //拆分返回的最后一个token令牌字节切片。 82 | // buf []byte //缓冲区用作拆分参数。 83 | // start int // buf中的第一个未处理字节索引。这个参数会跟随读取器不停的变化。 84 | // end int // buf中的数据结束索引。 85 | // err err //粘性错误。 86 | // empties int //连续空令牌字节切片的计数。 87 | // scanCalled bool //扫描已被调用; 缓冲区正在使用中。 88 | // done bool //扫描已完成。 89 | 90 | 91 | //Bytes方法返回最近一次Scan调用生成的token。底层数组指向的数据可能会被下一次Scan的调用重写。 92 | fmt.Println(scanner.Bytes())//[],读完了,所以空 93 | 94 | //对于分割函数go内置了4个常用的分割函数,当然你也可以自定义,下面的4个函数分别是按照字节,字符rune,空白空格 95 | //和换行符进行分割 96 | // 97 | //func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) 98 | // ScanBytes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个字节作为一个token返回。 99 | // 100 | // 101 | //func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) 102 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个utf-8编码的unicode码值作 103 | // 为一个token返回。本函数返回的rune序列和range一个字符串的输出rune序列相同。错误的utf-8编码会翻译为 104 | // U+FFFD = "\xef\xbf\xbd",但只会消耗一个字节。调用者无法区分正确编码的rune和错误编码的rune。 105 | // 106 | // 107 | //func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) 108 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将空白(参见unicode.IsSpace) 109 | // 分隔的片段(去掉前后空白后)作为一个token返回。本函数永远不会返回空字符串。 110 | // 111 | // 112 | //func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) 113 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每一行文本去掉末尾的换行标记作 114 | // 为一个token返回。返回的行可以是空字符串。换行标记为一个可选的回车后跟一个必选的换行符。最后一行即 115 | // 使没有换行符也会作为一个token返回。 116 | } 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /io_pro/main/bufio_Scanner_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("===================================") 12 | 13 | //对于分割函数go内置了4个常用的分割函数,当然你也可以自定义,下面的4个函数分别是按照字节,字符rune,空白空格 14 | //和换行符进行分割 15 | // 16 | //func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) 17 | // ScanBytes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个字节作为一个token返回。 18 | // 19 | // 20 | //func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) 21 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个utf-8编码的unicode码值作 22 | // 为一个token返回。本函数返回的rune序列和range一个字符串的输出rune序列相同。错误的utf-8编码会翻译为 23 | // U+FFFD = "\xef\xbf\xbd",但只会消耗一个字节。调用者无法区分正确编码的rune和错误编码的rune。 24 | // 25 | // 26 | //func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) 27 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将空白(参见unicode.IsSpace) 28 | // 分隔的片段(去掉前后空白后)作为一个token返回。本函数永远不会返回空字符串。 29 | // 30 | // 31 | //func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) 32 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每一行文本去掉末尾的换行标记作 33 | // 为一个token返回。返回的行可以是空字符串。换行标记为一个可选的回车后跟一个必选的换行符。最后一行即 34 | // 使没有换行符也会作为一个token返回。 35 | 36 | 37 | // An artificial input source. 38 | const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n" 39 | scanner := bufio.NewScanner(strings.NewReader(input)) 40 | // Set the split function for the scanning operation. 41 | scanner.Split(bufio.ScanWords) 42 | // Count the words. 43 | count := 0 44 | for scanner.Scan() { 45 | fmt.Printf("%s\n", scanner.Text()) 46 | count++//对每个scanner.Text()字符串进行计数 47 | } 48 | if err := scanner.Err(); err != nil { 49 | // Fprintln格式使用其操作数的默认格式并写入w。 50 | //始终在操作数之间添加空格,并添加换行符。 51 | //返回写入的字节数以及遇到的任何写入错误。 52 | fmt.Fprintln(os.Stderr, "reading input:", err) 53 | } 54 | fmt.Printf("%d\n", count) 55 | // ScanWords是扫描程序的拆分功能,它返回每个空格分隔的文本单词, 56 | // 并删除周围的空格。 它永远不会返回空字符串。 空间的定义由unicode.IsSpace设置。 57 | //因为不同的编码有不同的空格unicode值,所以这里所说的空格是unicode值表示的空格,他包括: 58 | // 第一:' ', '\t', '\n', '\v', '\f', '\r', 59 | // 第二:'\u0085', '\u00A0' 60 | // 第三:'\u2000' <= r && r <= '\u200a' 61 | // 第四:'\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000' 62 | 63 | //输出如下: 64 | //=================================== 65 | //Now 66 | //is 67 | //the 68 | //winter 69 | //of 70 | //our 71 | //discontent, 72 | // Made 73 | //glorious 74 | //summer 75 | //by 76 | //this 77 | //sun 78 | //of 79 | //York. 80 | //15 81 | } 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /io_pro/main/bufio_Scanner_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("===================================") 11 | 12 | //对于分割函数go内置了4个常用的分割函数,当然你也可以自定义,下面的4个函数分别是按照字节,字符rune,空白空格 13 | //和换行符进行分割 14 | // 15 | //func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) 16 | // ScanBytes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个字节作为一个token返回。 17 | // 18 | // 19 | //func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) 20 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个utf-8编码的unicode码值作 21 | // 为一个token返回。本函数返回的rune序列和range一个字符串的输出rune序列相同。错误的utf-8编码会翻译为 22 | // U+FFFD = "\xef\xbf\xbd",但只会消耗一个字节。调用者无法区分正确编码的rune和错误编码的rune。 23 | // 24 | // 25 | //func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) 26 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将空白(参见unicode.IsSpace) 27 | // 分隔的片段(去掉前后空白后)作为一个token返回。本函数永远不会返回空字符串。 28 | // // ScanWords是扫描程序的拆分功能,它返回每个空格分隔的文本单词, 29 | // // 并删除周围的空格。 它永远不会返回空字符串。 空间的定义由unicode.IsSpace设置。 30 | // //因为不同的编码有不同的空格unicode值,所以这里所说的空格是unicode值表示的空格,他包括: 31 | // // 第一:' ', '\t', '\n', '\v', '\f', '\r', 32 | // // 第二:'\u0085', '\u00A0' 33 | // // 第三:'\u2000' <= r && r <= '\u200a' 34 | // // 第四:'\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000' 35 | // 36 | //func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) 37 | // ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每一行文本去掉末尾的换行标记作 38 | // 为一个token返回。返回的行可以是空字符串。换行标记为一个可选的回车后跟一个必选的换行符。最后一行即 39 | // 使没有换行符也会作为一个token返回。 40 | 41 | 42 | scanner := bufio.NewScanner(os.Stdin) 43 | for scanner.Scan() { 44 | fmt.Println(scanner.Text()) // Println will add back the final '\n',默认是这种按行分割模式 45 | } 46 | if err := scanner.Err(); err != nil { 47 | fmt.Fprintln(os.Stderr, "reading standard input:", err) 48 | } 49 | //第一次输出: 50 | // 你好啊(单数行都是我自己输入的字符串) 51 | // 你好啊(双数行都是程序自己打印的字符串) 52 | // nnn 53 | // nnn 54 | // sdsd 55 | // sdsd 56 | //第二次输出: 57 | // 你好 迭代 sdsd \n(单数行都是我自己输入的字符串) 58 | // 你好 迭代 sdsd \n(双数行都是程序自己打印的字符串) 59 | // sdsd \n sdsds \n sdsdsd 60 | // sdsd \n sdsds \n sdsdsd 61 | } 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /io_pro/main/bytes_Buffer_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | byte_slice := []byte{97, 98, 99, 100, 101, 102, 126, 127} 10 | Bf:=bytes.NewBuffer(byte_slice) 11 | fmt.Println(Bf)//会在控制台打印出字面值,最大126可显示出字面值,超过的就会显示乱码了 12 | //fmt.Println(Bf[0])//buffer不支持索引 13 | 14 | //ls:=make([]byte,5) 15 | //fmt.Println(Bf.Read(ls)) 16 | //fmt.Println(Bf)//索引会接着上面的读取指针进行读取到结尾 17 | //fmt.Println(ls)//[97 98 99 100 101] 18 | 19 | fmt.Println("-----------------") 20 | 21 | 22 | fmt.Println(Bf.ReadByte())//读取下一个索引的值 23 | fmt.Println(Bf)//bcdef~(每次读取一个字节,Bf就会pop一个字节出来) 24 | 25 | fmt.Println(Bf.UnreadByte())//不但指针回退,pop出去的索引值被重新push进来 26 | fmt.Println(Bf)//abcdef~(每次读取一个字节,Bf就会pop一个字节出来) 27 | //因为上面的UnreadByte将读取指针调前一位了,所以这里还是读取到和上面的ReadByte读取一样的值 28 | fmt.Println(Bf.ReadByte()) 29 | fmt.Println(Bf)//bcdef~(每次读取一个字节,Bf就会pop一个字节出来) 30 | 31 | 32 | //索引会接着上面的读取指针进行读取下一个并且返回下一个索引值并且pop出一个索引值,如果是从最开始读取的话,那么就是最开始的索引值 33 | fmt.Println(Bf.ReadRune()) 34 | fmt.Println(Bf)//cdef~ 35 | 36 | fmt.Println(Bf.UnreadRune())//跟上面的函数作用相反 37 | fmt.Println(Bf)//bcdef~ 38 | 39 | fmt.Println(Bf.ReadRune())//跟UnreadByte同理 40 | fmt.Println(Bf)//cdef~ 41 | 42 | fmt.Println("-----------------") 43 | ls:=[]byte{65,66,67,68,69} 44 | reader := bytes.NewReader(ls) 45 | fmt.Println("******",reader)//&{[65 66 67 68 69] 0 -1} 46 | n, _ := Bf.ReadFrom(reader)///从io.Reader中append到Buffer中去原地扩充元素,Buffer的容量跟随需要扩大 47 | fmt.Println(n)//5,表示append到Buffer多少个值 48 | fmt.Println(Bf)//cdef~ABCDE 49 | fmt.Println("******",reader)// &{[65 66 67 68 69] 5 -1} 50 | 51 | fmt.Println("-----------------") 52 | b:=byte('e') 53 | line, _ := Bf.ReadString(b)//读取到元素的相应值为b的值的话就返回从开始到这个元素的这段相应的字符串 54 | fmt.Println(line)//cde 55 | fmt.Println("-----------------") 56 | fmt.Println(Bf)//f~ABCDE 57 | 58 | fmt.Println("-----------------") 59 | b111:=byte('C') 60 | lines, _ := Bf.ReadBytes(b111)//注意这里返回的是字节切片的类型,而上面那个函数返回的是字符串的类型 61 | fmt.Println(lines) 62 | fmt.Println(Bf) 63 | 64 | fmt.Println("-----------------") 65 | fmt.Printf("%p--%v\n",Bf,Bf) 66 | Bf.Reset() //通过原地重置切片的索引值和长度值重置了Bf 67 | fmt.Printf("%p--%v\n",Bf,Bf)//空的Buffer会返回空的什么都不显示 68 | 69 | fmt.Println("-----------------") 70 | ls111:=[]byte{65,66,67,68,69} 71 | reader111 := bytes.NewReader(ls111) 72 | fmt.Println(Bf.ReadFrom(reader111)) 73 | //fmt.Println(reader)//&{[65 66 67 68 69] 5 -1} 74 | //fmt.Println(Bf.ReadFrom(reader))//0 ,重复的reader不能被读取2次进buffer,因为reader里面的索引值为最尾端的值了,比如上面的值5 75 | fmt.Println(Bf) 76 | 77 | fmt.Println("-----------------") 78 | fmt.Println(Bf.Write([]byte{77,78,79,80})) 79 | fmt.Println(Bf) 80 | 81 | fmt.Println("-----------------") 82 | fmt.Println(Bf.Len())//9 83 | fmt.Println(Bf.String())//ABCDEMNOP 84 | fmt.Println(Bf.Bytes())//[65 66 67 68 69 77 78 79 80] 85 | fmt.Println(Bf.Cap())//528 86 | 87 | fmt.Println("-----------------") 88 | fmt.Println(Bf.WriteString("xyz")) 89 | fmt.Println(Bf) 90 | fmt.Println(Bf.Bytes())//[65 66 67 68 69 77 78 79 80 120 121 122] 91 | //一个中文占3个字节,而且这2个中文字是按照utf8编码后的字节存进去的, 92 | // 非原本的unicode字符的字节数组 93 | fmt.Println(Bf.WriteString("你好")) 94 | fmt.Println(Bf) 95 | fmt.Println(Bf.Bytes())//[65 66 67 68 69 77 78 79 80 120 121 122 228 189 160 229 165 189] 96 | 97 | fmt.Println("-----------------") 98 | r, size, _ := Bf.ReadRune() 99 | fmt.Println(r, size)//65 1 100 | Bf.Reset() 101 | Bf.WriteString("你好") 102 | fmt.Println(Bf) 103 | fmt.Println(Bf.Bytes()) 104 | r111, size111, _ := Bf.ReadRune()//rune会将前3个字节一起编码为uft8的单个字符串类型,具体编码格式如下: 105 | fmt.Println(r111, size111)//20320 3(20320是) 106 | fmt.Println(string(r111))//对二进制(十进制为20320)的值进行解析转义。输出:你 107 | //假设前3个字节:228 189 160 108 | //字节值:二进制值 109 | //228:11100100 110 | //189:10111101 111 | //160:10100000 112 | //去掉每个字节的前2位,然后分别为: 113 | //228:100100 114 | //189:111101 115 | //160:100000 116 | //然后连接这3个二进制为:100100111101100000 117 | //最后将二进制存进去内存中 118 | //其实我们发现100100111101100000十进制是20320,也就是对应utf8字典中的你这个中文单字符 119 | //我们输出到屏幕上面就是需要解码的过程,这里说的解码并不是由utf8类型的二进制转成单字节的二进制, 120 | //而是翻译二进制为字符串在屏幕上显示出来成为人眼能够识别的字符串的过程,我们也成为解码,其实解码的概念很大的! 121 | 122 | // string是所有8位字节的字符串的集合,按常规,但不是 123 | //必须代表UTF-8编码的文本。 字符串可以为空,但不能为nil。 字符串类型的值是不可变的。 124 | 125 | fmt.Println("-----------------") 126 | //新建立一个Buffer好了。 127 | byte_slice111 := []byte{97, 98, 99, 100, 101, 102, 103,104} 128 | Bf111:=bytes.NewBuffer(byte_slice111) 129 | fmt.Println(Bf111) 130 | //截断会丢弃缓冲区中除前n个未读取字节以外的所有字节,但会继续使用相同的已分配存储。 131 | //如果n为负数或大于缓冲区的长度,则会发生恐慌。 132 | Bf111.Truncate(3)//保留前3个字节,其他去除 133 | fmt.Println(Bf111) 134 | 135 | 136 | //如有必要,Grow会增加缓冲区的容量,以保证另外n个字节的空间。 在Grow(n)之后,至少可以将n个字节写入缓冲区,而无需进行其他分配。 137 | //如果n为负数,Grow会惊慌。 138 | //如果缓冲区无法增长,则会因ErrTooLarge感到恐慌。 139 | fmt.Println(Bf111.Cap(),"--",Bf111.Len())//8 -- 3 140 | Bf111.Grow(20)//计算方法是当前的cap长度*2+n,也就是8*2+20=36 141 | fmt.Println(Bf111.Cap(),"--",Bf111.Len())//36 -- 3 142 | 143 | 144 | // Next返回一个切片,其中包含缓冲区中的下n个字节, 145 | //前进缓冲区,就好像字节已由Read返回。 146 | //如果缓冲区中的字节数少于n个,则Next返回整个缓冲区。 147 | //切片仅在下一次调用read或write方法之前才有效。 148 | fmt.Println("-----------------") 149 | fmt.Println(Bf111)//abc 150 | fmt.Println(Bf111.Next(2))//返回字节切片[97 98],读取接下来的2个,同时读取指针前进2,源缓存会改变 151 | fmt.Println(Bf111)//c 152 | fmt.Println(Bf111)//c 153 | Bf111.WriteString("defg")//加点东西 154 | fmt.Println(Bf111)//cdefg 155 | fmt.Println(Bf111.Next(6))//[99 100 101 102 103],很明显只有5个,但是我们却要取6个,于是全部返回 156 | fmt.Println(Bf111)//这里输出空 157 | 158 | fmt.Println("-----------------") 159 | // WriteString将s的内容附加到缓冲区,根据需要增大缓冲区。 160 | // 返回值n是s的长度; 错误始终为零。 如果缓冲区太大,WriteString将对ErrTooLarge感到恐慌。 161 | //Bf111.WriteString("abcdef世")//写入中文也可以 162 | Bf111.WriteString("abcdefg")//内部是通过copy()实现的,copy()的用法如下: 163 | //复制内置函数将元素从源切片复制到目标切片。 164 | // (在特殊情况下,它还会将字节从字符串复制到字节切片。) 165 | // 源和目标可能会重叠。 复制返回复制的元素数量,该数量将是len(src)和len(dst)的最小值。 166 | fmt.Println(Bf111)//abcdefg 167 | 168 | 169 | // WriteRune将Unicode代码点r的UTF-8编码附加到缓冲区,返回其长度和错误, 170 | // 该错误始终为nil,但包含在其中以匹配bufio.Writer的WriteRune。 缓冲区根据需要增长; 171 | //如果太大,WriteRune会因ErrTooLarge感到恐慌。 172 | fmt.Println("-----------------") 173 | var a rune=104//abcdefgh 174 | //var a rune=19990//abcdefg世 175 | fmt.Println(Bf111.WriteRune(a))//往切片里面写入utf8编码的rune 176 | fmt.Println(Bf111)//abcdefgh 177 | 178 | 179 | } 180 | -------------------------------------------------------------------------------- /io_pro/main/bytes_Reader_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | func main() { 8 | byte_slice:=[]byte{99,98,99,99,101,102,103,107} 9 | //byte_slice:=[]byte{00,24,00,35,00,56,00,34} 10 | //byte_slice:=[]byte{99,98,99,99,100,100,100,107} 11 | ls:=make([]byte,6) 12 | reader := bytes.NewReader(byte_slice) 13 | fmt.Println(reader) 14 | fmt.Println(reader.Read(ls)) 15 | fmt.Println(reader) 16 | fmt.Println(ls) 17 | ls111:=make([]byte,6) 18 | fmt.Println(reader.ReadAt(ls111,2)) 19 | fmt.Println(ls111) 20 | //ReadRune读取并返回Reader中的下一个utf-8码值。如果没有数据可用, 21 | // 返回值err为io.EOF。如果缓冲中的数据是错误的utf-8编码,本方法会吃掉一字节并返回(U+FFFD, 1, nil)。 22 | ch, size, _ := reader.ReadRune()//ch是读取结束时候的指针值,size是单前的字节宽度,这表明里面没有任何一个rune类型的字节 23 | //如果读取成功的话各个参数的意义就不一样了 24 | fmt.Println("----",ch) 25 | fmt.Printf("%T\n",ch) 26 | fmt.Println(size) 27 | fmt.Printf("%T---%v\n",byte_slice[0],byte_slice[0]) 28 | 29 | fmt.Println("--------------------") 30 | // Size返回基础字节片的原始长度。 31 | // Size是可通过ReadAt读取的字节数。 32 | //返回的值始终相同,并且不受任何其他方法的调用影响。 33 | fmt.Println(reader.Size()) 34 | fmt.Println(reader.Len())//Len返回r包含的切片中还没有被读取的部分。 35 | fmt.Println("--------------------") 36 | 37 | //fmt.Println(reader) 38 | //fmt.Println(reader.Seek(4,0))//read的指针移动到索引4再读 39 | //ls222:=make([]byte,3) 40 | //fmt.Println(reader) 41 | //fmt.Println(reader.Read(ls222)) 42 | ////因为上面的读取,导致这里开始读取的索引为左后一个了,所以直接读取最后一个单个字节,注意他只读取单个字节 43 | //fmt.Println(reader.ReadByte()) 44 | 45 | //ls333:=[]byte{1,2,3,4,5} 46 | //ls333:=[]byte{} 47 | //fmt.Printf("%p---%v\n",reader,reader)//0xc00005a330---&{[99 98 99 99 100 100 100 107] 8 -1} 48 | //reader.Reset(ls333)//0xc00005a330---&{[] 0 -1} 49 | ////reader.Reset(ls333) 50 | ////地址没变,相当于原来切片的切片 51 | //fmt.Printf("%p---%v\n",reader,reader)//0xc00005a330---&{[1 2 3 4 5] 0 -1} 52 | 53 | fmt.Println(reader.UnreadByte()) 54 | fmt.Println(reader) 55 | 56 | fmt.Println("--------------------") 57 | fmt.Println(reader.ReadRune())//也受读取指针的影响,如果指针在最后了,那就返回最后一个索引值 58 | fmt.Println(reader.UnreadRune())//似乎是ReadRune()的反向。调用这个之前必须要调用ReadRune()才可以 59 | 60 | //UnreadRune吐出最近一次调用ReadRune方法读取的unicode码值。 61 | // 如果最近一次读写操作不是ReadRune,本方法会返回错误。 62 | // (这里就能看出来UnreadRune比UnreadByte严格多了) 63 | fmt.Println("--------------------") 64 | fmt.Println(reader)//&{[99 98 99 99 101 102 103 107] 6 -1} 65 | fmt.Println(reader.UnreadByte())//读取指针发生变化 66 | fmt.Println(reader)//&{[99 98 99 99 101 102 103 107] 5 -1} 67 | } 68 | 69 | -------------------------------------------------------------------------------- /io_pro/main/bzip2/aa.txt: -------------------------------------------------------------------------------- 1 | bc2019年10月15日,北京。 鸽子从董先生的鸽笼中飞出,董先生是大兴信鸽协会成员,这次为国庆活动提供了一百多个鸽子。10月1日的新中国成立70周年庆典上放飞了7万羽和平鸽,场面蔚为壮观。 2 | 据了解,这些和平鸽都是北京信鸽协会从鸽友处征集而来。在广场集体放飞后,这些信鸽绝大部分都回到了家中,而这些信鸽平时在家中是如何训练和生活的呢?北京青年报记者采访了部分鸽友,揭秘信鸽的日常生活和训练。供图:视觉中国abc 3 | -------------------------------------------------------------------------------- /io_pro/main/bzip2/aa.txt.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/bzip2/aa.txt.bz2 -------------------------------------------------------------------------------- /io_pro/main/bzip2/bzip2.txt: -------------------------------------------------------------------------------- 1 | abc2019年10月15日,北京。 鸽子从董先生的鸽笼中飞出,董先生是大兴信鸽协会成员,这次为国庆活动提供了一百多个鸽子。10月1日的新中国成立70周年庆典上放飞了7万羽和平鸽,场面蔚为壮观。 2 | 据了解,这些和平鸽都是北京信鸽协会从鸽友处征集而来。在广场集体放飞后,这些信鸽绝大部分都回到了家中,而这些信鸽平时在家中是如何训练和生活的呢?北京青年报记者采访了部分鸽友,揭秘信鸽的日常生活和训练。供图:视觉中国abc -------------------------------------------------------------------------------- /io_pro/main/bzip2/e.txt.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/bzip2/e.txt.bz2 -------------------------------------------------------------------------------- /io_pro/main/compress_bzip2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "compress/bzip2" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | //file, e := os.Open("main/bzip2/e.txt.bz2") 11 | file, e := os.Open("main/bzip2/aa.txt.bz2") 12 | check_err_bzip2(e) 13 | // NewReader返回一个io.Reader,它将io中的bzip2数据解压缩。 14 | //如果r还没有实现io.ByteReader,则解压缩器可能会从r读取比所需更多的数据。 15 | r_bz2 := bzip2.NewReader(file) 16 | 17 | //info, e := file.Stat() 18 | check_err_bzip2(e) 19 | //dst_byte:=make([]byte,info.Size())//这里获取的是压缩后的字节的大小,但是容纳的却是解压后的字节的大小,是不一样的额! 20 | //dst_byte:=make([]byte,102400)//给一个很大的数就行,事实上他的真实字节数是100003,对于这种有没有更好的解决办法呢? 21 | dst_byte:=make([]byte,600)//这个大小主要是为了解压aa.txt.bz2用的,如果是e.txt.bz2请用上面的大小 22 | // 目前还不知道,一般[]byte大小对于这种格式给源bzip2文件的大小的2.2倍即可 23 | n, e := r_bz2.Read(dst_byte) 24 | check_err_bzip2(e) 25 | fmt.Println("解压了的字节数是:",n) 26 | fmt.Println("解压了的字节是:",dst_byte) 27 | fmt.Println("解压了的字符串是:",string(dst_byte)) 28 | //e.txt.bz2输出: 29 | // 解压了的字节数是: 43149 30 | // 解压了的字节是: [50 46 55 49 56 50 56 49 56 50 56 52 53 57 48 52 53 50 51 53 ...](这里我省略了,因为太长了) 31 | // 解压了的字符串是: 2.718281828459045235360287471352662497757247093699959574966967...(这里我省略了,因为太长了) 32 | //aa.txt.bz2输出: 33 | // 解压了的字节数是: 577 34 | // 解压了的字节是: [98 99 50 48 49 57 229 185 180 49 48 230 156 136 49 53 230 151 165 239 188 140 229 140 151 228 186 172 227 128 130 32 35 | // 233 184 189 229 173 144 228 187 142 232 145 163 229 133 136 231 148 159 231 154 132 233 184 189 231 172 188 228 184 173 233 163 158 36 | // 229 135 186 239 188 140 232 145 163 229 133 136 231 148 159 230 152 175 229 164 167 229 133 180 228 191 161 233 184 189 229 141 143 37 | // 228 188 154 230 136 144 229 145 152 239 188 140 232 191 153 230 172 161 228 184 186 229 155 189 229 186 134 230 180 187 229 138 168 38 | // 230 143 144 228 190 155 228 186 134 228 184 128 231 153 190 229 164 154 228 184 170 233 184 189 229 173 144 227 128 130 49 48 230 156 39 | // 136 49 230 151 165 231 154 132 230 150 176 228 184 173 229 155 189 230 136 144 231 171 139 55 48 229 145 168 229 185 180 229 186 134 40 | // 229 133 184 228 184 138 230 148 190 233 163 158 228 186 134 55 228 184 135 231 190 189 229 146 140 229 185 179 233 184 189 239 188 140 41 | // 229 156 186 233 157 162 232 148 154 228 184 186 229 163 174 232 167 130 227 128 130 10 230 141 174 228 186 134 232 167 163 239 188 140 42 | // 232 191 153 228 186 155 229 146 140 229 185 179 233 184 189 233 131 189 230 152 175 229 140 151 228 186 172 228 191 161 233 184 189 229 43 | // 141 143 228 188 154 228 187 142 233 184 189 229 143 139 229 164 132 229 190 129 233 155 134 232 128 140 230 157 165 227 128 130 229 156 44 | // 168 229 185 191 229 156 186 233 155 134 228 189 147 230 148 190 233 163 158 229 144 142 239 188 140 232 191 153 228 186 155 228 191 161 45 | // 233 184 189 231 187 157 229 164 167 233 131 168 229 136 134 233 131 189 229 155 158 229 136 176 228 186 134 229 174 182 228 184 173 239 46 | // 188 140 232 128 140 232 191 153 228 186 155 228 191 161 233 184 189 229 185 179 230 151 182 229 156 168 229 174 182 228 184 173 230 152 47 | // 175 229 166 130 228 189 149 232 174 173 231 187 131 229 146 140 231 148 159 230 180 187 231 154 132 229 145 162 239 188 159 229 140 151 48 | // 228 186 172 233 157 146 229 185 180 230 138 165 232 174 176 232 128 133 233 135 135 232 174 191 228 186 134 233 131 168 229 136 134 233 49 | // 184 189 229 143 139 239 188 140 230 143 173 231 167 152 228 191 161 233 184 189 231 154 132 230 151 165 229 184 184 231 148 159 230 180 50 | // 187 229 146 140 232 174 173 231 187 131 227 128 130 228 190 155 229 155 190 239 188 154 232 167 134 232 167 137 228 184 173 229 155 189 51 | // 97 98 99 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 52 | // 解压了的字符串是: bc2019年10月15日,北京。 鸽子从董先生的鸽笼中飞出,董先生是大兴信鸽协会成员,这次为国庆活动提供了一百多个鸽子。10月1日的新中国成立70周年庆典上放飞了7万羽和平鸽,场面蔚为壮观。 53 | // 据了解,这些和平鸽都是北京信鸽协会从鸽友处征集而来。在广场集体放飞后,这些信鸽绝大部分都回到了家中,而这些信鸽平时在家中是如何训练和生活的呢?北京青年报记者采访了部分鸽友,揭秘信鸽的日常生活和训练。供图:视觉中国abc 54 | 55 | //目前go没提供压缩成这种格式的api,只能解压! 56 | //如果你希望得到自己的这种格式的压缩文件进行测试,请到linux虚拟机中: 57 | // 1.命令“yum -y install bzip2”安装bzip2包(前提要有yum包) 58 | // 2.创建你需要压缩的文件 59 | // 3.命令“bzip2 -k 你要压缩的完整文件名”,这样的话就可以得到对应的bzip2压缩文件了 60 | 61 | } 62 | func check_err_bzip2(err2 error) { 63 | if err !=nil{ 64 | fmt.Println(err) 65 | } 66 | } -------------------------------------------------------------------------------- /io_pro/main/compress_gzip_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "compress/gzip" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | fmt.Println("-----下面的代码都是为了验证是否可以压缩多个文件------") 13 | dst_file, err := os.Create("main/gzip/dst2.gz") 14 | check_err_gzip2(err) 15 | wt1 := gzip.NewWriter(dst_file) 16 | wt2:= gzip.NewWriter(dst_file) 17 | ii:=0 18 | 19 | err=filepath.Walk("main/gzip", func(path string, info os.FileInfo, err error) error { 20 | // Ext返回路径使用的文件扩展名。 21 | //扩展名是从path的最后一个元素中的最后一个点开始的后缀; 如果没有点,则为空。 22 | //info.Name()返回文件名,不包含路径,如下: 23 | //dst.gz 24 | //gzip.txt 25 | //gzip02.txt 26 | if !info.IsDir() && filepath.Ext(info.Name())==".txt" { 27 | fmt.Println("当前操作的文件名是:",info.Name()) 28 | 29 | //path是相对文件路径 30 | file, err := os.Open(path) 31 | check_err_gzip2(err) 32 | //这个方法比read()好用很多倍,而且不用我们手动创建[]byte来存储读取到的字节数据 33 | src_byte, err := ioutil.ReadAll(file) 34 | check_err_gzip2(err) 35 | 36 | if ii != 0{ 37 | i, err := wt2.Write(src_byte) 38 | check_err_gzip2(err) 39 | 40 | //写不写都没什么所谓,因为后面调用了close()(包含flush()方法) 41 | //err = wt.Flush() 42 | //check_err_gzip2(err) 43 | fmt.Println("写入压缩文件中得到字节数是222:",i) 44 | err = wt2.Close() 45 | check_err_gzip2(err) 46 | }else { 47 | i, err := wt1.Write(src_byte) 48 | check_err_gzip2(err) 49 | 50 | //写不写都没什么所谓,因为后面调用了close()(包含flush()方法) 51 | //err = wt.Flush() 52 | //check_err_gzip2(err) 53 | fmt.Println("写入压缩文件中得到字节数是111:",i) 54 | ii++ 55 | err = wt1.Close() 56 | check_err_gzip2(err) 57 | } 58 | 59 | 60 | 61 | } 62 | return nil 63 | }) 64 | check_err_gzip2(err) 65 | 66 | err = dst_file.Close() 67 | check_err_gzip2(err) 68 | 69 | //验证结果显示,但凡是使用了flate算法的压缩(gzip和zlib压缩就是)都是无法压缩多个文件的,除非将多个文件写入到单个文件中然后再进行压缩,上面的方式就是这样! 70 | 71 | 72 | //下面的api个人认为不怎么常用 73 | 74 | //多流控制阅读器是否支持多流文件。 75 | //如果已启用(默认设置),则Reader希望输入是一系列单独压缩的数据流,每个数据流都有自己的标题和结尾,以EOF结尾。 效果是,压缩文件序列的串联被视为等同于该序列串联的gzip。 这是gzip阅读器的标准行为。 76 | //调用Multistream(false)将禁用此行为; 当读取区分单个gzip数据流或将gzip数据流与其他数据流区分开的文件格式时,禁用该行为可能很有用。 77 | //在此模式下,当Reader到达数据流的末尾时,Read返回io.EOF。 基础阅读器必须实现io.ByteReader才能将其定位在gzip流之后。 78 | //要开始下一个流,请调用z.Reset(r),然后调用z.Multistream(false)。 79 | //如果没有下一个流,则z.Reset(r)将返回io.EOF。 80 | //reader.Multistream(true) 81 | 82 | // Reset丢弃Reader z的状态,使其等效于从NewReader读取其原始状态的结果,但改为从r读取。 83 | //这允许重用Reader,而不是分配新的Reader。 84 | //reader.Reset() 85 | 86 | } 87 | 88 | func check_err_gzip2(err error) { 89 | if err != nil{ 90 | fmt.Println(err) 91 | } 92 | } -------------------------------------------------------------------------------- /io_pro/main/compress_lzw.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "compress/lzw" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | //对于这种算法建议阅读https://baike.baidu.com/reference/7293853/524dhTCm7Hnt8jSdM7ycM4Gd81AvPcI0GG_T94Jzzkd1qM_Mm05Z_I7EhSedUJYIspbGWi1segdqT65xzSUHAUvns38us4pu2XGFFw 13 | //或者https://segmentfault.com/a/1190000011425787?utm_source=tag-newest 14 | //这种算法多用于重复性比较大的数据,如压缩GIF文件、图象、文本文件是最理想的,对于像我下面的读取少字的pdf反而因压缩会变大! 15 | 16 | fmt.Println("---------压缩文件------------") 17 | dst_file, e := os.Create("main/lzw/lzw_dst.txt") 18 | check_err_lzw(e) 19 | 20 | ////顺序指定LZW数据流中的位顺序。 21 | //type Order int 22 | //const ( 23 | // // LSB表示GIF文件格式中使用的最低有效位优先。 24 | // LSB Order = iota 25 | // // MSB首先表示最高有效位,如TIFF和PDF文件格式所用。 26 | // MSB 27 | //) 28 | 29 | // NewWriter创建一个新的io.WriteCloser。 30 | //写入返回的io.WriteCloser被压缩并写入w。 31 | //完成写入后,调用者有责任在WriteCloser上调用Close。 32 | //用于文字代码的位数litWidth必须在[2,8]范围内,通常为8。输入字节必须小于1 << litWidth。 33 | wt := lzw.NewWriter(dst_file, lzw.MSB, 8)//如果是中文的pdf只能是8, 34 | 35 | src_bytes, e := ioutil.ReadFile("main/lzw/lzw_src.pdf") 36 | check_err_lzw(e) 37 | n, e := wt.Write(src_bytes) 38 | check_err_lzw(e) 39 | 40 | fmt.Println("写入压缩文件的字节数是:",n) 41 | e = wt.Close() 42 | check_err_lzw(e) 43 | 44 | fmt.Println("---------读取压缩文件------------") 45 | 46 | ret, e := dst_file.Seek(0, 0) 47 | check_err_lzw(e) 48 | 49 | 50 | fmt.Println("将压缩文件的读写指针重置:",ret) 51 | 52 | dst_bytes, e := ioutil.ReadAll(dst_file) 53 | 54 | fmt.Println("读取到的压缩文件的字节数是:",len(dst_bytes)) 55 | fmt.Println("读取到的压缩文件的字节是:",dst_bytes) 56 | fmt.Println("读取到的压缩文件的字符串是:",string(dst_bytes)) 57 | 58 | 59 | 60 | fmt.Println("---------解压压缩文件并且读取解压后的数据------------") 61 | i, e := dst_file.Seek(0, 0) 62 | check_err_lzw(e) 63 | 64 | fmt.Println("重置压缩文件的读写指针到:",i) 65 | 66 | dst_bytes111:=make([]byte,0,512*91)//不给长度,记得,这样的话append才会从切片的开头开始追加 67 | fmt.Printf("总装载器的地址是:%p ",dst_bytes111) 68 | // 返回的rd实际上是bufio.NewReader(r),而bufio.NewReader(r)就是限制了4096个字节的。 69 | rd := lzw.NewReader(dst_file, lzw.MSB, 8) 70 | aready_rd_num :=0 71 | for { 72 | //每次都重新申请内存,我们在这里模仿缓存,如果你想要节省空间的话可以使用真正的缓存buf 73 | //buffer := make([]byte,4096) 74 | buffer := make([]byte,512)//为了不让解压后的数据生成的文件过大,我们不用4096,因为如果一开始给太大, 75 | // 在最后那里几次性申请的内存会非常的大,具体表现需要你自己打印输出看看,如果你希望不产生多余的字节,那么可以通过buf来实现的 76 | 77 | 78 | m, e := rd.Read(buffer)//这里千万不要read大于4096字节的切片,否则会出错(数据不会真的全部解压) 79 | if m < 0 { 80 | panic("errNegativeRead") 81 | } 82 | aready_rd_num += m 83 | fmt.Println("已读到的压缩文件的字节数为",aready_rd_num) 84 | fmt.Println("buf的长度是:",len(buffer)) 85 | 86 | dst_bytes111=append(dst_bytes111,buffer...) 87 | fmt.Printf("总装载器的地址是:%p\t",dst_bytes111) 88 | //n=copy(dst_bytes111,buffer)//千万不要用copy,因为长度容量什么的都会被复制过去了,这并不是我们想要的结果 89 | fmt.Println("总容量为:",len(dst_bytes111)) 90 | 91 | if e == io.EOF { 92 | break 93 | } 94 | if e != nil { 95 | fmt.Println("读取解压发生了错误。。。") 96 | } 97 | } 98 | 99 | //下面的注释掉的一大段是之前的失败尝试,之所以失败是因为我们 rd.Read(dst_bytes111)时候dst_bytes111大于4096个字节了 100 | //-------------------------------------11111111111111-------------------------------------------- 101 | //dst_bytes111:=make([]byte,45358,45358) 102 | //n2, e1 := rd.Read(dst_bytes111) 103 | //fmt.Println("遍历读取,每次读取的字节数为:",n2) 104 | //// rd实际上是bufio.NewReader(r),而bufio.NewReader(r)就是限制了4096个字节的。 105 | //// 因为文件大于4096,所以不可以使用这个方法进行单次读取完全部,必须使用buf缓存来进行读取,因为缓存会自动扩展容量的, 106 | //// 经典的有缓存读取的api是ioutil.ReadAll(),一般我们都会优先使用这个api,但是这个缓存大小初始化仅为512个字节,因此 107 | //// 如果你不希望多次申请内存的话,那么就采用下面的循环遍历读取来提升性能,而不是用便捷的ioutil.ReadAll()方法!但是不知道 108 | //// 为什么读取出来的数据像是没解压的,因为我打开pdf是没正确显示中文的! 109 | // 110 | //var num int=n2 111 | //fmt.Println("num第一次的值为:",num) 112 | //for e1 != io.EOF{ 113 | // //defer里面的recoverb并不会捕获文件读取到结尾抛出来的信息,因此不会执行recover下面的东西 114 | // //defer func() { 115 | // // if err := recover(); err != nil { 116 | // // fmt.Println(err) // 这里的err其实就是panic传入的内容, 117 | // // } 118 | // //}() 119 | // 120 | // n2, e1 = rd.Read(dst_bytes111[n2:])//每次只能读取4096个字节。读取到最后时候读取不到字节因此n2最后值为0 121 | // // 下面的ReadAll的内部实现就是通过缓存进行读取的!我们可以看到这个Read方法有一定的缺陷。 122 | // if e1 !=nil{ 123 | // fmt.Println("读取到了文件结尾,抛出读取到文件结尾信息为:",e1) 124 | // break 125 | // } 126 | // num+=n2 127 | // fmt.Println("num当前值为:",num) 128 | //} 129 | ////事实上这个Close并没做任何事情,只是设置了标志位为close而已 130 | //e = rd.Close() 131 | // 132 | //check_err_lzw(e) 133 | //-------------------------------------111111111111111------------------------------------------ 134 | 135 | //-------------------------------------222222222222-------------------------------------------- 136 | // readAll从r读取直到出现错误或EOF,并从分配给指定容量的内部缓冲区中返回读取的数据。 137 | //dst_bytes111, e := ioutil.ReadAll(rd) 138 | //check_err_lzw(e) 139 | //-------------------------------------222222222222-------------------------------------------- 140 | //fmt.Println("压缩文件解压之后的字节数是:",num)//循环读取需要放开这行注释同时注释下一行的代码 141 | fmt.Println("压缩文件解压之后的字节数是:",len(dst_bytes111)) 142 | fmt.Println("压缩文件解压之后的字节是:",dst_bytes111) 143 | fmt.Printf("压缩文件解压之后的字符串是:\n%v\n",string(dst_bytes111)) 144 | 145 | //不知道上面的中文为什么输出乱码 146 | 147 | fmt.Println("---------将解压后的数据写入到文件中去------------") 148 | dst_file111, e := os.Create("main/lzw/lzw_dst.pdf") 149 | check_err_lzw(e) 150 | 151 | n3, e := dst_file111.Write(dst_bytes111) 152 | check_err_lzw(e) 153 | 154 | fmt.Println("解压后的数据写入到新文件中的字节数是:",n3) 155 | 156 | //输出如下:自己执行,因为输出太多了!此处略! 157 | 158 | 159 | } 160 | 161 | func check_err_lzw(err error) { 162 | if err != nil { 163 | fmt.Println(err) 164 | } 165 | } 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /io_pro/main/dialDNSUdp.go: -------------------------------------------------------------------------------- 1 | //转载请注明出处:http://blog.csdn.net/gophers/article/details/22942457 2 | 3 | package main 4 | 5 | import ( 6 | "bytes" 7 | "encoding/binary" 8 | "fmt" 9 | "net" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | type DNSHeader struct { 15 | ID uint16 16 | Flag uint16 17 | QuestionCount uint16 18 | AnswerRRs uint16 //RRs is Resource Records 19 | AuthorityRRs uint16 20 | AdditionalRRs uint16 21 | } 22 | 23 | func (header *DNSHeader) SetFlag(QR uint16, OperationCode uint16, AuthoritativeAnswer uint16, Truncation uint16, RecursionDesired uint16, RecursionAvailable uint16, ResponseCode uint16) { 24 | header.Flag = QR<<15 + OperationCode<<11 + AuthoritativeAnswer<<10 + Truncation<<9 + RecursionDesired<<8 + RecursionAvailable<<7 + ResponseCode 25 | } 26 | 27 | type DNSQuery struct { 28 | QuestionType uint16 29 | QuestionClass uint16 30 | } 31 | 32 | func ParseDomainName(domain string) []byte { 33 | //要将域名解析成相应的格式,例如: 34 | //"www.google.com"会被解析成"0x03www0x06google0x03com0x00" 35 | //就是长度+内容,长度+内容……最后以0x00结尾 36 | var ( 37 | buffer bytes.Buffer 38 | segments []string = strings.Split(domain, ".") 39 | ) 40 | for _, seg := range segments { 41 | binary.Write(&buffer, binary.BigEndian, byte(len(seg))) 42 | binary.Write(&buffer, binary.BigEndian, []byte(seg)) 43 | } 44 | binary.Write(&buffer, binary.BigEndian, byte(0x00)) 45 | 46 | return buffer.Bytes() 47 | } 48 | 49 | func DialDnsUdp() { 50 | var ( 51 | dns_header DNSHeader 52 | dns_question DNSQuery 53 | ) 54 | 55 | //填充dns首部 56 | dns_header.ID = 0xFFFF 57 | dns_header.SetFlag(0, 0, 0, 0, 1, 0, 0) 58 | dns_header.QuestionCount = 1 59 | dns_header.AnswerRRs = 0 60 | dns_header.AuthorityRRs = 0 61 | dns_header.AdditionalRRs = 0 62 | 63 | //填充dns查询首部 64 | dns_question.QuestionType = 1 //IPv4 65 | dns_question.QuestionClass = 1 66 | go func() { 67 | //同样不知道为什么不可以读取 68 | udpConn, e := net.ListenUDP("udp", nil) 69 | if e != nil { 70 | fmt.Println(e) 71 | return 72 | } 73 | by := make([]byte, 512) 74 | i, e := udpConn.Read(by) 75 | if e != nil { 76 | fmt.Println(e) 77 | return 78 | } 79 | fmt.Println("接收到的字节数为:", i) 80 | fmt.Println("接收到的字节数据为:", by) 81 | fmt.Println("接收到的字节数据为:", string(by)) 82 | }() 83 | var ( 84 | conn net.Conn 85 | err error 86 | 87 | buffer bytes.Buffer 88 | ) 89 | 90 | //DNS服务器的端口一般是53,dns的服务器ip地址你自己ipconfig查一下 91 | //别忘了DNS是基于UDP协议的 92 | if conn, err = net.Dial("udp", "120.196.165.24:53"); err != nil { 93 | fmt.Println(err.Error()) 94 | return 95 | } 96 | defer conn.Close() 97 | 98 | //buffer中是我们要发送的数据,里面的内容是DNS首部+查询内容+DNS查询首部 99 | binary.Write(&buffer, binary.BigEndian, dns_header) 100 | binary.Write(&buffer, binary.BigEndian, ParseDomainName("www.baidu.com")) 101 | binary.Write(&buffer, binary.BigEndian, dns_question) 102 | fmt.Println(buffer.Bytes()) 103 | fmt.Println(buffer.String()) 104 | 105 | if _, err := conn.Write(buffer.Bytes()); err != nil { 106 | fmt.Println(err.Error()) 107 | return 108 | } 109 | fmt.Println("send success.") 110 | //请自己抓包查看效果,这里查询的是baidu.com的dns地址 111 | time.Sleep(2e9) 112 | } 113 | -------------------------------------------------------------------------------- /io_pro/main/dst_tar/text.tar: -------------------------------------------------------------------------------- 1 | text1.txt0000666000001200000000000000132713562150517011071 0ustar00000000000000001111111adsdsdsd李克强在致辞中代表中国政府和人民祝贺本届世园会成功举办,并对支持和参与北京世园会的各国朋友致以谢意。他表示,本届世园会以“绿色生活,美丽家园”为主题,精彩纷呈、成果丰硕。 2 | 在开幕式上,中国国家主席习近平倡导共同建设美丽地球家sdsdsdsd园、构建人类命运共同体。这是一场文明互鉴的绿色盛会,促进了各国文明交流、民心相通和绿色合作。这是一场创新荟萃的科技盛会,展现了绿色科技应用的美好前景。 3 | 这是一场走进自然的体验盛会,中外访客用心感受环保与发展相互促进、人与自然和谐共处的美好。sdsdsdstext2.txt0000666000001200000000000000104613562150517011070 0ustar00000000000000002222222222“保持中美关aaabbbb系健康稳定发展,对两国对世界都有利。双方要坚持协abc调、合作、稳定的基调,在相互尊重基础上管控分歧,在互惠互利基础上拓展合作,推动两国关系沿着正确轨道向前发展。” 4 | 习近平主席在致特朗普总统的口信中强调了中方主张,特朗普总统请刘鹤副总理转达对习近平主席的感谢,并明确表示“美中经贸磋商取得了实质性的第一阶段成果,这对美中两国和世界都是重大利好”。abc -------------------------------------------------------------------------------- /io_pro/main/encoding.md: -------------------------------------------------------------------------------- 1 | encoding包定义了供其它包使用的可以将数据在字节水平和文本表示之间转换的接口。encoding/gob、encoding/json、encoding/xml三个包都会检查使用这些接口。因此,只要实现了这些接口一次,就可以在多个包里使用。标准包内建类型time.Time和net.IP都实现了这些接口。接口是成对的,分别产生和还原编码后的数据。 2 | 3 | 主要有下面的结果方法: 4 | 5 | [type BinaryMarshaler] 6 | 7 | [type BinaryUnmarshaler] 8 | 9 | [type TextMarshaler] 10 | 11 | [type TextUnmarshaler] 12 | 13 | #### 这个包一般不被用到,他会被其他包继承!所以不写!事实上在其他encoding包中已经被写到了,请去了解其他包中的实现类! 14 | 15 | -------------------------------------------------------------------------------- /io_pro/main/encoding_ascii85.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/ascii85" 6 | "fmt" 7 | ) 8 | 9 | func main() { 10 | 11 | fmt.Println("------------编码---------------") 12 | dst_ls:=make([]byte,15) 13 | src_ls:=[]byte{97,98,99,100,101,102} 14 | 15 | //将src编码成最多MaxEncodedLen(len(src))数据写入dst,返回实际写入的字节数。编码每4字节一段进行一次, 16 | //最后一个片段采用特殊的处理方式,因此不应将本函数用于处理大数据流的某一独立数据块。 17 | //一般来说ascii85编码数据会被'<~'和'~>'包括起来,函数并未添加上它们。 18 | n:=ascii85.Encode(dst_ls,src_ls)//每次取4个字节为一段来进行转码,不够4个就取光来转码,不过无论去多少个,最后一定生成5个字节输出 19 | fmt.Println(n) 20 | fmt.Println("源切片",src_ls,"字符串显示为:",string(src_ls)) 21 | fmt.Println("转换后的目的切片",dst_ls,"字符串显示为:",string(dst_ls)) 22 | 23 | //输出: 24 | // 8,这个8=(len(src_ls)/4)*5+(len(src_ls)%4)+1,具体表示什么真的不好说 25 | // 源切片 [97 98 99 100 101 102] 字符串显示为: abcdef 26 | // 转换后的目的切片 [64 58 69 95 87 65 83 40 111 66 0 0 0 0 0] 字符串显示为: @:E_WAS(oB,编码后的 27 | // 字节序列的长度为(len(src_ls) + 3) / 4 * 5,当然可以通过ascii85.MaxEncodedLen()获取,转码后的字节序列的长度一定会是5的倍数 28 | 29 | fmt.Println("-------------解码--------------") 30 | 31 | //将src解码后写入dst,返回写入dst的字节数、从src解码的字节数。如果src含有非法数据,函数将返回成功执行的数据(两个数字) 32 | //和CorruptInputError。如果flush为真,则函数会认为src代表输入流的结尾,完全处理src,而不会等待另一个32字节的数据块。 33 | // 34 | //函数会忽略src中的空格和控制字符,一般来说ascii85编码数据会被'<~'和'~>'包括起来,但是调用者应自行去掉它们。 35 | dst_ls111:=make([]byte,15) 36 | src_ls111:=[]byte{64 ,58, 69, 95, 87, 65, 83, 40}//这个数据就是上面转码后的数据,这种ascii85.Decode的第三个参数必须设置为true才可以正确的解码 37 | //src_ls111:=[]byte{64 ,58, 69, 95, 87, 65, 83, 40, 111, 66}//这个数据就是上面转码后的数据 38 | ndst, nsrc, err := ascii85.Decode(dst_ls111, src_ls111, true) 39 | if err!=nil{ 40 | fmt.Println(err) 41 | } 42 | fmt.Println(ndst) 43 | fmt.Println("解码的源序列字节数为:",nsrc,"要解码数据为:",src_ls111) 44 | fmt.Println("解码后的序列的字节数为:",ndst,"解码后的数据为:",dst_ls111) 45 | //输出: 46 | // 解码的源序列字节数为: 10 要解码数据为: [64 58 69 95 87 65 83 40 111 66] 47 | // 解码后的序列的字节数为: 8 解码后的数据为: [97 98 99 100 101 102 0 0 0 0 0 0 0 0 0] 48 | 49 | fmt.Println("--------------ascii85.Encode()封装函数ascii85.NewEncoder()-----------------") 50 | 51 | // MaxEncodedLen返回n个源字节的编码的最大长度。 52 | 53 | // 编码后的字节序列的长度为(len(src_ls) + 3) / 4 * 5,当然可以通过ascii85.MaxEncodedLen()获取,转码后的字节序列的长度一定会是5的倍数 54 | fmt.Println(ascii85.MaxEncodedLen(8))//10 55 | fmt.Println(ascii85.MaxEncodedLen(9))//15 56 | 57 | fmt.Println("-------------------------------") 58 | // NewEncoder返回一个新的ascii85流编码器。 写入返回的写入器的数据将被编码,然后写入w。 59 | // Ascii85编码以32位块运行; 完成写入后,调用者必须关闭返回的编码器以刷新任何尾随的部分块。 60 | // 底层也是通过ascii85.Encode()实现的,不过放在2个函数里面实现,一个是ascii85.NewEncoder,另外一个是writeCloser.Close() 61 | ls_bf:=make([]byte,0,15) 62 | buffer := bytes.NewBuffer(ls_bf) 63 | writeCloser := ascii85.NewEncoder(buffer) 64 | 65 | ls_src222:=[]byte{97,98,99,100,101,102} 66 | i, err111 := writeCloser.Write(ls_src222)//写入什么 67 | if err111 !=nil{ 68 | fmt.Println(err111) 69 | } 70 | // Close刷新编码器的所有未决输出。必须调用 71 | //调用Close之后调用Write会出错。 72 | err222:=writeCloser.Close()//不够4个字节的尾字节都会在这里编码,也就是说,如果不写这句话的话, 73 | // 那么编码将只有5个字节而不会有后面的3个字节,因为后面的3个字节是由最尾的2个源切片的字节编码后生成的。 74 | if err222 !=nil{ 75 | fmt.Println(err222) 76 | } 77 | 78 | fmt.Println(i) 79 | fmt.Println("源切片:",ls_src222,"字符串显示为:",string(ls_src222),"源切片长度:",len(ls_src222)) 80 | fmt.Println("转换后的目的切片:",buffer.Bytes(),"字符串显示为:",buffer.String(),"转换后的目的切片长度:",buffer.Len()) 81 | //输出: 82 | // 6 83 | // 源切片: [97 98 99 100 101 102] 字符串显示为: abcdef 源切片长度: 6 84 | // 转换后的目的切片: [64 58 69 95 87 65 83 40] 字符串显示为: @:E_WAS( 转换后的目的切片长度: 8 85 | 86 | //从输出可以看出比ascii85.Encode()的编码少了2个字节,至于为什么不大清楚,不过可以肯定的是,这种方式返回的写入字节数会跟源字节数相等 87 | //从ascii85.Encode()的文档中可以知道Encode()不大适合处理大数据流,而眼前的这个函数的话肯定是适合处理大数据流的。 88 | //对于这个编码生成的序列我们不能采用上面的ascii85.Decode()函数来进行解码,否则解码后的字节序列会丢掉后面的2个字节,还原不了源字节序列。 89 | //而应该采用下面讲到的这个函数来进行解码 90 | 91 | fmt.Println("--------------函数ascii85.NewEncoder()-----------------") 92 | 93 | //src_ls222:=[]byte{64 ,58, 69, 95, 87 ,65 ,83, 40,}//这个数据是无法通过ascii85.NewDecoder()进行解码的 94 | src_ls222:=[]byte{64 ,58, 69, 95, 87 ,65 ,83, 40,111 ,66}//只能解码由ascii85.Encode()编码后的数据,不能解码由ascii85.newEncode()编码后的数据,至于为什么不大清楚 95 | //reader := bytes.NewReader(src_ls222)//这种方式创建io.Reader也是可以的 96 | reader := bytes.NewBuffer(src_ls222) 97 | newDecoder_reader := ascii85.NewDecoder(reader) 98 | dst_ls222:=make([]byte,15) 99 | n2, err333 := newDecoder_reader.Read(dst_ls222) 100 | if err333 !=nil{ 101 | fmt.Println(err333) 102 | } 103 | fmt.Println(n2) 104 | 105 | fmt.Println("解码的源序列字节数为:",len(src_ls222),"要解码数据为:",string(src_ls222)) 106 | fmt.Println("解码后的序列的字节数为:", n2,"解码后的数据为:",dst_ls222) 107 | //输出: 108 | // 8 109 | // 解码的源序列字节数为: 10 要解码数据为: @:E_WAS(oB 110 | // 解码后的序列的字节数为: 8 解码后的数据为: [97 98 99 100 101 102 0 0 0 0 0 0 0 0 0] 111 | 112 | //总结,解码最好通过ascii85.Decoder()来进行解码,但是编码的话我们可以通过2中方式来进行编码,分别是ascii85.NewEncoder()和ascii85.Encoder() 113 | 114 | } 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /io_pro/main/encoding_asn1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/asn1" 5 | "fmt" 6 | "os" 7 | "sort" 8 | "time" 9 | ) 10 | 11 | type myPerson struct { 12 | Name string 13 | Age int 14 | Country string 15 | Isfat bool//这里所有的字段首字母都必须大写 16 | } 17 | 18 | func main() { 19 | fmt.Println("-----------Marshal函数---------------") 20 | //Marshal函数返回val的ASN.1编码。 21 | //除了Unmarshal可以识别的struct标记外,此外还提供了供Unmarshal函数识别的结构体标签,可用如下标签: 22 | // ia5: 使字符串序列化为ASN.1 IA5String类型 23 | // omitempty: 使空切片被跳过 24 | // printable: 使字符串序列化为ASN.1 PrintableString类型 25 | // utf8: 使字符串序列化为ASN.1 UTF8字符串 26 | // utc: 使time.Time序列化为ASN.1 UTCTime类型值 27 | // generalized: 使time.Time序列化为ASN.1 GeneralizedTime类型值 28 | fmt.Println("你好啊") 29 | var P = myPerson{ 30 | Name: "anko", 31 | Age: 22, 32 | Country: "China", 33 | Isfat: false, 34 | } 35 | bytes, e := asn1.Marshal(P) 36 | if e != nil { 37 | fmt.Println(e) 38 | } 39 | fmt.Println(bytes) //[48 19 19 4 97 110 107 111 2 1 22 19 5 67 104 105 110 97 1 1 0] 40 | fmt.Println(string(bytes)) 41 | 42 | //asn1.MarshalWithParams() 43 | fmt.Println("-----------UnMarshal函数---------------") 44 | 45 | src_ls:=[]byte{48 ,19, 19, 4 ,97, 110, 107, 111, 2 ,1, 22, 19, 5, 67, 104, 105, 110, 97, 1, 1, 0} 46 | 47 | var P1 myPerson 48 | 49 | rest, e1 := asn1.Unmarshal(src_ls, &P1)//这里必须传递的是指针&P1,否则报错 50 | if e1 != nil{ 51 | fmt.Println(e1) 52 | } 53 | 54 | fmt.Println(rest) 55 | fmt.Println(string(rest)) 56 | fmt.Println(P1) 57 | //输出: 58 | // [] 59 | //(空字符串) 60 | // {anko 22 China false} 61 | //这里我们测试了struct这个复杂类型,但是其实像int和string类型都是可以的! 62 | fmt.Println("------------------string类型的序列化与反序列化-----------------") 63 | s := "hello" 64 | //s := "hello\u00bc"//非ASCII字符会报错,必须只能是ascii字符 65 | mdata, _ := asn1.Marshal(s) 66 | fmt.Println(mdata,"----",string(mdata)) 67 | var newstr string 68 | asn1.Unmarshal(mdata, &newstr) 69 | fmt.Println(newstr) 70 | //输出: 71 | // [19 5 104 101 108 108 111] ---- hello 72 | // hello 73 | 74 | fmt.Println("------------------int类型的序列化与反序列化-----------------") 75 | s1 := 16 76 | mdata1, _ := asn1.Marshal(s1) 77 | fmt.Println(mdata1,"----",string(mdata1)) 78 | var newstr1 int 79 | asn1.Unmarshal(mdata1, &newstr1) 80 | fmt.Println(newstr) 81 | //输出: 82 | // [2 1 16] ----  83 | // hello 84 | 85 | fmt.Println("------------------time类型的序列化与反序列化-----------------") 86 | 87 | t := time.Now() 88 | mdata, err44 := asn1.Marshal(t) 89 | checkError(err44) 90 | fmt.Println(t) 91 | 92 | var newtime = new(time.Time) 93 | _, err1234 := asn1.Unmarshal(mdata,newtime)//因为这里newtime已经是指针了,所以不要再加上&来取指针了,不然会报错 94 | checkError(err1234) 95 | fmt.Println(newtime) 96 | //输出: 97 | // 2019-10-10 10:57:05.6999874 +0800 CST m=+0.003908801 98 | // 2019-10-10 10:57:05 +0800 CST 99 | 100 | 101 | fmt.Println("-----------------asn1包的类型系统------------------------") 102 | // BitString是需要ASN.1 BIT STRING类型时使用的结构。 将位字符串填充到内存中最近的字节,并记录有效位数。 填充位将为零。 103 | var BS = asn1.BitString{ 104 | Bytes: []byte{'a', 'b', 'c', 'd'}, 105 | BitLength: 4, 106 | } 107 | // RightAlign返回一个切片,其中填充位在开头。 切片可以与BitString共享内存。 108 | // At返回给定索引处的位。 如果索引超出范围,则返回false。 109 | fmt.Println(BS.Bytes) //[97 98 99 100] 110 | fmt.Println(BS.BitLength) //4 111 | fmt.Println(BS.At(2)) //2 112 | fmt.Println(BS.RightAlign()) //[6 22 38 54] 113 | fmt.Println(BS) //{[97 98 99 100] 4} 114 | 115 | fmt.Println("----------------------") 116 | var i asn1.Enumerated = 1 117 | fmt.Println(i) //1 118 | 119 | var b asn1.Flag = true 120 | fmt.Println(b) //true 121 | 122 | var O1 asn1.ObjectIdentifier = []int{1, 2, 3, 4} 123 | 124 | var O2 asn1.ObjectIdentifier = []int{1, 2, 3, 4} 125 | var O3 asn1.ObjectIdentifier = []int{1, 2, 3} 126 | var O4 asn1.ObjectIdentifier = []int{1, 2, 3, 0} 127 | 128 | fmt.Println(O1) //1.2.3.4 129 | fmt.Println(O1.String()) //1.2.3.4 130 | fmt.Println(O1.Equal(O2)) //true 131 | fmt.Println(O1.Equal(O3)) //false 132 | fmt.Println(len(O1)) //4 133 | sort.Ints(O4) 134 | fmt.Println(O4) //0.1.2.3 135 | O4 = append(O4, 5) 136 | fmt.Println(O4) //0.1.2.3.5 137 | //属性基本跟[]int类型完全一样 138 | 139 | fmt.Println("----------------------") 140 | 141 | // NullBytes包含表示DER编码的ASN.1 NULL类型的字节。 142 | NBytes := asn1.NullBytes 143 | fmt.Println(NBytes) //[5 0] 144 | fmt.Println(NBytes) //[5 0] 145 | 146 | // RawContent用于表示需要为结构保留未解码的DER数据。 要使用它, 147 | // 结构的第一个字段必须具有此类型。 任何其他字段都具有此类型是错误的。 148 | var RC = asn1.RawContent{'a', 'b', 'c'} 149 | fmt.Println(RC) //[97 98 99] 150 | fmt.Println(len(RC)) //3 151 | 152 | // RawValue表示未解码的ASN.1对象。 153 | var RV = asn1.RawValue{ 154 | Class: 1, 155 | Tag: 2, 156 | IsCompound: false, 157 | Bytes: []byte{'a', 'b'}, 158 | FullBytes: []byte{'c', 'd'}, 159 | } 160 | fmt.Println(RV.Class) 161 | fmt.Println(RV.Tag) 162 | fmt.Println(RV.IsCompound) 163 | fmt.Println(RV.Bytes) 164 | fmt.Println(RV.FullBytes) 165 | //输出: 166 | // 1 167 | // 2 168 | // false 169 | // [97 98] 170 | // [99 100] 171 | 172 | fmt.Println(asn1.TagUTF8String) //12,其实这个数字对应一个类型,被用于上面的asn1.RawValue.Tag 173 | fmt.Println(asn1.ClassContextSpecific) //2,其实这个数字对应一个类型,被用于上面的asn1.RawValue.Class 174 | 175 | //对asn1还不大熟悉,暂且先讲这么多 176 | } 177 | 178 | func checkError(err error) { 179 | if err != nil { 180 | fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) 181 | os.Exit(1) 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /io_pro/main/encoding_asn1_01.go: -------------------------------------------------------------------------------- 1 | /* ASN1 DaytimeServer 2 | */ 3 | package main 4 | 5 | import ( 6 | "encoding/asn1" 7 | "fmt" 8 | "net" 9 | "os" 10 | "time" 11 | ) 12 | 13 | //服务端:等待客户端连接并且连接后发送服务器的时间 14 | func main() { 15 | 16 | service := ":1200" 17 | tcpAddr, err := net.ResolveTCPAddr("tcp", service) 18 | checkError1(err) 19 | 20 | listener, err := net.ListenTCP("tcp", tcpAddr)//在这里阻塞监听端口1200 21 | checkError1(err) 22 | 23 | for { 24 | conn, err := listener.Accept()//解阻塞后来到这里创建新的连接 25 | if err != nil { 26 | continue 27 | } 28 | 29 | //daytime := time.Now()//获取服务器当前的时间 30 | daytime := time.Date(1990,12,11,2,3,4,5,time.Local)//自己创建一个时间发送过去 31 | // Ignore return network errors. 32 | mdata, _ := asn1.Marshal(daytime)//按照asn1来编码服务器的时间 33 | // Write将数据写入连接。 34 | //可以使写入超时并在固定的时间限制后使用Timeout()== true返回错误; 请参见SetDeadline和SetWriteDeadline。 35 | conn.Write(mdata)//将编码后的东西写进入conn里面 36 | conn.Close() // 关闭连接 37 | } 38 | } 39 | 40 | func checkError1(err error) { 41 | if err != nil { 42 | fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) 43 | os.Exit(1) 44 | } 45 | } -------------------------------------------------------------------------------- /io_pro/main/encoding_base64.go: -------------------------------------------------------------------------------- 1 | package main 2 | /* 3 | 这个包的api跟encoding.base32完全一样,因为不再累叙 4 | */ 5 | -------------------------------------------------------------------------------- /io_pro/main/encoding_gob_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "bytes" 4 | "encoding/gob" 5 | "fmt" 6 | "log" 7 | "math" 8 | ) 9 | //接口 10 | type Pythagoras interface { 11 | Hypotenuse() float64 12 | } 13 | 14 | //实现接口的结构体 15 | type Point struct { 16 | //x, Y int//私有的额字段不允许,如果你需要对私有字段进行编码解码的话, 17 | // 那么就要实现GobEncoder和GobDecoder接口,在func (t Time) GobEncode(){}有实现这个接口,你可以去看看 18 | X, Y int 19 | } 20 | func (p Point) Hypotenuse() float64 {//求 21 | return math.Hypot(float64(p.X), float64(p.Y)) 22 | } 23 | 24 | // interfaceEncode编码器函数 将接口值编码到编码器中。 25 | func interfaceEncode(enc *gob.Encoder, p Pythagoras) { 26 | //除非已注册具体类型(或者说结构体),否则编码将失败。 我们在调用函数Example_interface()中注册了它。 27 | //将指针传递给接口,以便Encode看到(并因此发送)接口类型的值。 如果我们直接传递p,它将看到具体类型。 28 | //有关背景,请参见博客文章“反射定律(The Laws of Reflection)”。 29 | err := enc.Encode(&p)//必须是指针 30 | if err != nil { 31 | log.Fatal("encode:", err) 32 | } 33 | } 34 | // interfaceDecode解码器函数 解码流中的下一个接口值并返回它。 35 | func interfaceDecode(dec *gob.Decoder) Pythagoras { 36 | //除非导线上的具体类型(或者说结构体)已注册,否则解码将失败。 我们在调用函数Example_interface()中注册了它。 37 | var p Pythagoras 38 | err := dec.Decode(&p)//必须是指针,指明解码成什么数据结构 39 | if err != nil { 40 | log.Fatal("decode:", err) 41 | } 42 | fmt.Printf("解码后的数据类型为:%T\n",p) 43 | fmt.Printf("解码后的数据为:%#v\n",p) 44 | return p//返回解码后的数据,这个数据不是接口,是接口的实现struct---Point类实例 45 | } 46 | 47 | 48 | //此示例说明如何编码接口值。 与常规类型的主要区别是注册实现接口的具体类型。 49 | func Example_interface() { 50 | var network bytes.Buffer //网络的替身。装载编码后的数据的容器 51 | //我们必须注册编码器和解码器的具体类型(通常与编码器在不同的机器上)。 在每一端,这告诉引擎正在发送实现该接口的具体类型。 52 | gob.Register(Point{})//指明要编码哪个结构体,必须在gob实例化编码器或者解码器之前调用 53 | 54 | //事实上RegisterName是Register的底层实现,Register的参数是默认的类型名字,但是RegisterName的参数是完全的包名+类型名字,仅此而已, 55 | //在绝大多数情况下都应该使用Register,因为这更加方便!其他的东西跟上面的Register的用法完全一致,因此不在这累叙了! 56 | //gob.RegisterName() 57 | 58 | //创建一个编码器并发送一些值。 59 | enc := gob.NewEncoder(&network)//编码到哪里去存着 60 | for i := 1; i <= 3; i++ { 61 | interfaceEncode(enc, Point{3 * i, 4 * i})//在这里实例化并且将实例传递过去 62 | } 63 | fmt.Println("编码后的数据为:",network) 64 | 65 | //创建一个解码器并接收一些值。 66 | dec := gob.NewDecoder(&network)//指定解码什么,指明编码什么数据结构 67 | for i := 1; i <= 3; i++ { 68 | result := interfaceDecode(dec) 69 | fmt.Printf("%T---%v\n",result,result.Hypotenuse())//调用struct的方法 70 | } 71 | 72 | //输出: 73 | // 编码后的数据为: {[44 16 0 10 109 97 105 110 46 80 111 105 110 116 255 129 3 1 1 5 80 111 74 | // 105 110 116 1 255 130 0 1 2 1 1 88 1 4 0 1 1 89 1 4 0 0 0 8 255 130 5 1 75 | // 6 1 8 0 21 16 0 10 109 97 105 110 46 80 111 105 110 116 255 130 5 1 12 1 76 | // 16 0 21 16 0 10 109 97 105 110 46 80 111 105 110 116 255 130 5 1 18 1 24 0] 0 0} 77 | // 解码后的数据类型为:main.Point 78 | // 解码后的数据为:main.Point{X:3, Y:4} 79 | // main.Point---5 80 | // 解码后的数据类型为:main.Point 81 | // 解码后的数据为:main.Point{X:6, Y:8} 82 | // main.Point---10 83 | // 解码后的数据类型为:main.Point 84 | // 解码后的数据为:main.Point{X:9, Y:12} 85 | // main.Point---15 86 | } 87 | 88 | 89 | func main() { 90 | fmt.Println("-------------------gob.Register()和gob.RegisterName()编解码数据----------------------") 91 | Example_interface() 92 | 93 | } 94 | -------------------------------------------------------------------------------- /io_pro/main/encoding_json_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | 9 | //多重json的序列化和反序列化 10 | 11 | 12 | func main() { 13 | 14 | ////id:1 ,name:张三,parent:0; 15 | ////id:2 ,name:李四,parent:1; 16 | ////id:2 ,name:王五,parent:2; 17 | //str:=` 18 | // [{id:1, 19 | // name:张三, 20 | // parent:0, 21 | // children:[ 22 | // id:2 , 23 | // name:李四, 24 | // parent:1, 25 | // children:[{ 26 | // id:3, 27 | // name:王五, 28 | // parent:2] 29 | // ]} 30 | // ] 31 | // },] 32 | //` 33 | 34 | //------------------序列化----------------------- 35 | 36 | type dst_struct struct { 37 | Id int `json:"id"` 38 | Name string `json:"name"` 39 | Parent int `json:"parent"` 40 | Children *dst_struct `json:"children"` 41 | } 42 | 43 | var dst_obj2 =dst_struct{ 44 | Id: 3, 45 | Name: "王五", 46 | Parent: 2, 47 | Children: nil, 48 | } 49 | 50 | var dst_obj1 =dst_struct{ 51 | Id: 2, 52 | Name: "李四", 53 | Parent: 1, 54 | Children: &dst_obj2, 55 | } 56 | 57 | var dst_obj =dst_struct{ 58 | Id: 1, 59 | Name: "张三", 60 | Parent: 0, 61 | Children: &dst_obj1, 62 | } 63 | 64 | json_bytes, e := json.Marshal(&dst_obj) 65 | check_err(e) 66 | fmt.Printf("%v\n",json_bytes) 67 | fmt.Printf("%s\n",string(json_bytes)) 68 | //输出: 69 | //{"id":1, 70 | // "name":"张三", 71 | // "parent":0, 72 | // "children":{"id":2, 73 | // "name":"李四", 74 | // "parent":1, 75 | // "children":{"id":3, 76 | // "name":"王五", 77 | // "parent":2, 78 | // "children":null}}} 79 | 80 | 81 | 82 | //------------------反序列化----------------------- 83 | 84 | //方式1: 85 | //var Unmarshal_obj2 =dst_struct{ 86 | // Children:nil, 87 | //} 88 | //var Unmarshal_obj1 =dst_struct{ 89 | // Children:&Unmarshal_obj2, 90 | //} 91 | // 92 | //var Unmarshal_obj =dst_struct{ 93 | // Children:&Unmarshal_obj1, 94 | //} 95 | 96 | //方式2: 97 | //var Unmarshal_obj =dst_struct{ 98 | // Children:&dst_struct{ 99 | // Children:&dst_struct{ 100 | // Children:nil, 101 | // }, 102 | // }, 103 | //} 104 | 105 | //方式3: 106 | var Unmarshal_obj =dst_struct{ 107 | 108 | } 109 | 110 | e = json.Unmarshal(json_bytes, &Unmarshal_obj) 111 | check_err(e) 112 | fmt.Printf("%#v\n",Unmarshal_obj) 113 | fmt.Printf("%#v\n",Unmarshal_obj.Children) 114 | fmt.Printf("%#v\n",Unmarshal_obj.Children.Children) 115 | //输出: 116 | //main.dst_struct{Id:1, Name:"张三", Parent:0, Children:(*main.dst_struct)(0xc00005c540)} 117 | //&main.dst_struct{Id:2, Name:"李四", Parent:1, Children:(*main.dst_struct)(0xc00005c510)} 118 | //&main.dst_struct{Id:3, Name:"王五", Parent:2, Children:(*main.dst_struct)(nil)} 119 | } 120 | 121 | 122 | 123 | func check_err(err error) { 124 | if err != nil { 125 | fmt.Println(err) 126 | panic(err) 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /io_pro/main/encoding_xml_02.go: -------------------------------------------------------------------------------- 1 | // xml.go 2 | package main 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "strings" 7 | ) 8 | var t, token xml.Token//申明Token,像这样2个一起申明,即使其中一个不使用也是可以的! 9 | var err error 10 | func main() { 11 | input := "LauraLynn" 12 | inputReader := strings.NewReader(input) 13 | p := xml.NewDecoder(inputReader)//创建解析input字符串的解码器 14 | for t, err = p.Token(); err == nil; t, err = p.Token() {//p.Token()获取解码器的Token,遍历结束后err == EOF而不是nil 15 | switch token := t.(type) { 16 | case xml.StartElement://如果是开始标签 17 | name := token.Name.Local//获取标签的名字 18 | fmt.Printf("Token name: %s\n", name) 19 | for _, attr := range token.Attr {//获取标签的属性,这个属性包含名字和值 20 | attrName := attr.Name.Local 21 | attrValue := attr.Value//分别取得属性的名字和值 22 | fmt.Printf("An attribute is: %s %s\n", attrName, attrValue) 23 | // ... 24 | } 25 | case xml.EndElement://如果是结束标签 26 | fmt.Println("End of token") 27 | case xml.CharData://如果是文本字符 28 | content := string([]byte(token)) 29 | fmt.Printf("This is the content: %v\n", content) 30 | // ... 31 | default://如果什么都不是的话,什么都不做 32 | // ... 33 | } 34 | } 35 | 36 | //输出: 37 | // Token name: Person 38 | // Token name: FirstName 39 | // This is the content: Laura 40 | // End of token 41 | // Token name: LastName 42 | // This is the content: Lynn 43 | // End of token 44 | // End of token 45 | } -------------------------------------------------------------------------------- /io_pro/main/flag_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | var ( 10 | levelFlag = flag.Int("level", 11, "级别") 11 | bnFlag int 12 | ) 13 | 14 | func init() { 15 | flag.IntVar(&bnFlag, "bn", 12, "份数") 16 | } 17 | 18 | func main() { 19 | 20 | flag.Parse() 21 | // Args保留以程序名称开头的命令行参数。按照空格进行分割参数 22 | count := len(os.Args) 23 | fmt.Println("参数总个数:",count) 24 | 25 | fmt.Println("参数详情:") 26 | for i := 0 ; i < count ;i++{ 27 | fmt.Println(i,":",os.Args[i]) 28 | } 29 | 30 | fmt.Println("\n参数值:") 31 | fmt.Println("级别:", *levelFlag) 32 | fmt.Println("份数:", bnFlag) 33 | } 34 | 35 | 36 | /* 37 | 运行结果:(compress_zlib.go改为相应的文件名即可) 38 | 39 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go 40 | 参数总个数: 1 41 | 参数详情: 42 | 0 : C:\Users\Administrator\AppData\Local\Temp\___go_build_compress_zlib_go.exe 43 | 44 | 参数值: 45 | 级别: 11 46 | 份数: 12 47 | 48 | 49 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go -level 111 -bn=122 50 | 参数总个数: 4 51 | 参数详情: 52 | 0 : C:\Users\ADMINI~1\AppData\Local\Temp\go-build779318678\b001\exe\compress_zlib.exe 53 | 1 : -level 54 | 2 : 111 55 | 3 : -bn=122 56 | 57 | 参数值: 58 | 级别: 111 59 | 份数: 122 60 | 61 | 62 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go -level 111 -bn 122 63 | 参数总个数: 5 64 | 参数详情: 65 | 0 : C:\Users\ADMINI~1\AppData\Local\Temp\go-build387111486\b001\exe\compress_zlib.exe 66 | 1 : -level 67 | 2 : 111 68 | 3 : -bn 69 | 4 : 122 70 | 71 | 参数值: 72 | 级别: 111 73 | 份数: 122 74 | 75 | 76 | 77 | */ -------------------------------------------------------------------------------- /io_pro/main/flag_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func init() { 11 | flagSet.Var(&addrFlag, "a", "b") 12 | } 13 | 14 | type StringArray []string 15 | 16 | func (s *StringArray) String() string { 17 | return fmt.Sprint([]string(*s)) 18 | } 19 | 20 | func (s *StringArray) Set(value string) error { 21 | *s = append(*s, value)//可以看到这里确实可以存储多个值,而不是替代旧值! 22 | return nil 23 | } 24 | 25 | var ( 26 | /* 27 | 参数解析出错时错误处理方式 28 | switch f.errorHandling { 29 | case ContinueOnError: 30 | return err 31 | case ExitOnError: 32 | os.Exit(2) 33 | case PanicOnError: 34 | panic(err) 35 | } 36 | */ 37 | 38 | //flagSet = flag.NewFlagSet(os.Args[0],flag.PanicOnError)//以抛出异常的形式处理错误 39 | flagSet = flag.NewFlagSet(os.Args[0],flag.ExitOnError)//以退出整个程序的形式处理错误 40 | //flagSet = flag.NewFlagSet("xcl",flag.ExitOnError) 41 | verFlag = flagSet.String("ver", "", "version")//版本号,这里的值是一个空字符串,表示没给! 42 | xtimeFlag = flagSet.Duration("time", 10*time.Minute, "time Duration")//发行时间 43 | 44 | addrFlag = StringArray{}//联系地址 45 | ) 46 | 47 | 48 | 49 | 50 | func main() { 51 | fmt.Println("os.Args[0]:", os.Args[0]) 52 | 53 | fmt.Println("-------------") 54 | fmt.Println(flagSet.NFlag()) 55 | fmt.Println(flagSet.Arg(1)) 56 | fmt.Println(flagSet.Arg(2)) 57 | fmt.Println(flagSet.Args()) 58 | fmt.Println("-------------") 59 | 60 | flagSet.Parse(os.Args[1:]) //flagSet.Parse(os.Args[0:]),从第一个参数开始才是要被解析的参数! 61 | 62 | fmt.Println("-------------") 63 | fmt.Println(flagSet.NFlag()) 64 | fmt.Println(flagSet.Arg(1)) 65 | fmt.Println(flagSet.Arg(2)) 66 | fmt.Println(flagSet.Args()) 67 | fmt.Println("-------------") 68 | //以上会输出: 69 | // ------------- 70 | // 0 71 | // 72 | // 73 | // [] 74 | // ------------- 75 | // ------------- 76 | // 3 77 | // 78 | // 79 | // [] 80 | // ------------- 81 | // 还是不大懂这几个方法到底是怎么用的! 82 | 83 | // NFlag返回已设置的标志数。 84 | fmt.Println("当前命令行参数类型个数(NFlag()):", flagSet.NFlag()) 85 | // NArg()是在处理标志flag后剩余的参数个数。 86 | for i := 0; i != flagSet.NArg(); i++ { 87 | // Arg返回第i个命令行参数。 Arg(0)是标志已处理后的第一个剩余参数。 如果请求的元素不存在,则Arg返回一个空字符串。 88 | fmt.Printf("arg[%d]=%s\n", i, flag.Arg(i)) 89 | } 90 | 91 | fmt.Println("\n参数值:") 92 | fmt.Println("ver:", *verFlag) 93 | fmt.Println("xtimeFlag:", *xtimeFlag) 94 | fmt.Println("addrFlag:",addrFlag.String()) 95 | // Args返回非标志命令行参数。 96 | for i,param := range flag.Args(){ 97 | fmt.Printf("---#%d :%s\n",i,param) 98 | } 99 | } 100 | 101 | 102 | 103 | /* 104 | 运行结果: 105 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go -ver 9.0 -a ba -a ca -a d2 -ver 10.0 -time 2m0s 106 | os.Args[0]: C:\Users\ADMINI~1\AppData\Local\Temp\go-build062115438\b001\exe\compress_zlib.exe 107 | 当前命令行参数类型个数(NFlag()): 3 108 | 109 | 参数值: 110 | ver: 10.0 111 | xtimeFlag: 2m0s 112 | addrFlag: [ba ca d2] 113 | 114 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go -ver 9.0 -a ba -a ca -a d2 -ver 10.0 115 | os.Args[0]: C:\Users\ADMINI~1\AppData\Local\Temp\go-build887043822\b001\exe\compress_zlib.exe 116 | 当前命令行参数类型个数(NFlag()): 2 117 | 118 | 参数值: 119 | ver: 10.0 120 | xtimeFlag: 10m0s 121 | addrFlag: [ba ca d2] 122 | 123 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3>go run compress_zlib.go 124 | os.Args[0]: C:\Users\ADMINI~1\AppData\Local\Temp\go-build940038518\b001\exe\compress_zlib.exe 125 | 当前命令行参数类型个数(NFlag()): 0 126 | 127 | 参数值: 128 | ver: 129 | xtimeFlag: 10m0s 130 | addrFlag: [] 131 | 132 | C:\Users\Administrator\Desktop\go_pro\src\io_pro\main3> 133 | 134 | //下面是一些出错时候的错误的处理方式 135 | 136 | 137 | -- flagSet = flag.NewFlagSet(os.Args[0],flag.PanicOnError) 结果: 138 | C:\TEMP\testflag>go run tfs.go -ver 9.0 -a ba -a ca -a d2 -ver 10.0 -time 2m0s33 139 | os.Args[0]: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\go-build841833143\command-line-arguments\_obj\exe\tfs.exe 140 | invalid value "2m0s33" for flag -time: time: missing unit in duration 2m0s33 141 | Usage of C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\go-build841833143\command-line-arguments\_obj\exe\tfs.exe: 142 | -a=[]: b 143 | -time=10m0s: time Duration 144 | -ver="": version 145 | panic: invalid value "2m0s33" for flag -time: time: missing unit in duration 2m0s33 146 | 147 | goroutine 1 [running]: 148 | flag.(*FlagSet).Parse(0x10b18180, 0x10b42008, 0xc, 0xc, 0x0, 0x0) 149 | c:/go/src/flag/flag.go:814 +0xee 150 | main.main() 151 | C:/TEMP/testflag/tfs.go:41 +0x163 152 | exit status 2 153 | 154 | 155 | -- flagSet = flag.NewFlagSet(os.Args[0],flag.ExitOnError) 结果: 156 | C:\TEMP\testflag>go run tfs.go -ver 9.0 -a ba -a ca -a d2 -ver 10.0 -time 2m0s33 157 | os.Args[0]: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\go-build501686683\command-line-arguments\_obj\exe\tfs.exe 158 | invalid value "2m0s33" for flag -time: time: missing unit in duration 2m0s33 159 | Usage of C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\go-build501686683\command-line-arguments\_obj\exe\tfs.exe: 160 | -a=[]: b 161 | -time=10m0s: time Duration 162 | -ver="": version 163 | exit status 2 164 | 165 | 166 | */ -------------------------------------------------------------------------------- /io_pro/main/flate/flate.txt: -------------------------------------------------------------------------------- 1 | abc西班牙政府都傻眼了,美国和西方的政客及媒体一时不知说什么。那些媒体的第一反应是 " 低调报道 "。很显然,美国和西方大力支持的香港式民主开始向西方回流。老胡要说一句,这真是报应啊。 2 | 不仅西班牙,英国的环保主义者也试图学习香港示威者的战术占领机场,同样在澳大利亚,也有一批环保主义者试图模仿香港示威者采取行动。香港示威者的暴力方式有可能嫁接到西方社会广泛存在的各种问题上,通过变异的方式逐渐引爆。加泰罗尼亚只是一个开始。abc -------------------------------------------------------------------------------- /io_pro/main/flate/flate_dst.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/flate/flate_dst.txt -------------------------------------------------------------------------------- /io_pro/main/github.com.axgle.mahonia.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | //"bytes" 5 | "fmt" 6 | "github.com/axgle/mahonia" 7 | "log" 8 | "os" 9 | "os/exec" 10 | //"io" 11 | ) 12 | 13 | //src为要转换的字符串,srcCode为待转换的编码格式,targetCode为要转换的编码格式 14 | func ConvertToByte(src string, srcCode string, targetCode string) []byte { 15 | srcCoder := mahonia.NewDecoder(srcCode) 16 | srcResult := srcCoder.ConvertString(src) 17 | tagCoder := mahonia.NewDecoder(targetCode) 18 | _, cdata, _ := tagCoder.Translate([]byte(srcResult), true) 19 | return cdata 20 | } 21 | 22 | func main() { 23 | for key, value := range os.Environ() { 24 | fmt.Println(key, ":",value) 25 | } 26 | // LookPath在由PATH环境变量命名的目录中搜索一个名为可执行文件的文件。 27 | //如果文件包含斜杠,则直接尝试使用该斜杠,并且不查询PATH。 28 | // LookPath还使用PATHEXT环境变量来匹配合适的候选者。 29 | //结果可能是绝对路径,也可能是相对于当前目录的路径。 30 | //path, err := exec.LookPath("go.exe") 31 | path, err := exec.LookPath(`C:\Go\bin\go.exe`)//也可以给一个完整的路径 32 | if err != nil { 33 | log.Fatal("在当前系统的环境变量中无法找到相应的文件") 34 | } 35 | fmt.Println(path)//C:\Go\bin\go.exe 36 | fmt.Printf("找到了,路径是:%s\n", path) 37 | 38 | fmt.Println("-------------------") 39 | cmd := exec.Command(`ping`,"www.baidu.com" ) 40 | //cmd.Stdin = strings.NewReader("some input")//这里自己创建一个*reader,因为不是所有的命令都有输入的! 41 | 42 | 43 | fmt.Println(cmd.Stdin) 44 | //设置输入流 45 | writeCloser, err222 := cmd.StdinPipe() 46 | if err222 !=nil{ 47 | fmt.Println(err222) 48 | } 49 | slice := make([]byte, 20) 50 | slice=append(slice,'b','a') 51 | n, err333 := writeCloser.Write(slice)//一定要在命令开始之前设置 52 | if err333 !=nil{ 53 | fmt.Println(err333) 54 | } 55 | fmt.Println(n) 56 | by_slice:=make([]byte,22) 57 | fmt.Println(cmd.Stdin.Read(by_slice)) 58 | fmt.Println(by_slice) 59 | 60 | fmt.Println("======***********========") 61 | 62 | //out, err777 := cmd.Output()//返回一个接受输出的[]byte结构,设置了这个的话就不用设置cmd.run()了,因为在这个方法里面写了 63 | out, err777 := cmd.CombinedOutput()//执行命令并返回标准输出和错误输出合并的切片。 64 | if err777 != nil { 65 | log.Fatal(err777) 66 | } 67 | //cmd.Start() 68 | //fmt.Println(cmd.SysProcAttr)//不是所有系统都会设置这个东西 69 | //fmt.Println(cmd.SysProcAttr.CmdLine) 70 | 71 | fmt.Println("cmd.ProcessState",cmd.ProcessState.String())//exit status 0 72 | fmt.Println("cmd.ProcessState",cmd.ProcessState.Pid())//32 73 | fmt.Println("cmd.ProcessState",cmd.ProcessState.Exited())//true 74 | fmt.Println("cmd.Process",cmd.Process)//包含一个已经存在的进程的信息,只有在调用Wait或Run后才可用,如&{8576 18446744073709551615 1 {{0 0} 0 0 0 0}} 75 | fmt.Println("cmd.Env",cmd.Path)//C:\windows\system32\ping.exe 76 | fmt.Println("cmd.Env",cmd.Env)//如为空切片,则是在当前进程的环境下执行。 77 | fmt.Println("cmd.Args",cmd.Args)//[ping www.baidu.com] 78 | fmt.Println("cmd.Dir",cmd.Dir)//空字符串表示调用者的进程当前目录下执行 79 | fmt.Printf("The date is %s\n", out) 80 | 81 | 82 | //设置错误的输出管道 83 | //stderrPipe, err555 := cmd.StderrPipe()//这个要在start之前设置 84 | //if err555 != nil { 85 | // log.Fatal(err555) 86 | //} 87 | 88 | //设置输出流 89 | //var out bytes.Buffer 90 | //cmd.Stdout = &out 91 | //多种方式写入输出流 92 | //readCloser, err444 := cmd.StdoutPipe() 93 | //if err444 !=nil{ 94 | // fmt.Println(err444) 95 | //} 96 | //fmt.Println(readCloser) 97 | // 98 | // 99 | ////err111 := cmd.Run()//这个阻塞然后接受数据最后关闭所有管道了 100 | //err111 := cmd.Start()//这个阻塞然后接受数据但是不关闭管道了 101 | //if err111 != nil { 102 | // log.Fatal(err111) 103 | //} 104 | // 105 | //s2:=make([]byte,50) 106 | //stderrPipe.Read(s2)//这个只有读取错误才会输出错误 107 | //fmt.Println("stderrPipe:",s2) 108 | // 109 | //sl:=make([]byte,30) 110 | //fmt.Println(readCloser.Read(sl)) 111 | 112 | 113 | 114 | 115 | 116 | 117 | cmd.Wait()//必须在所有管道读取之后才wait,他主要是关闭管道,释放相关的资源的作用 118 | //fmt.Println(sl) 119 | //fmt.Println(string(sl)) 120 | 121 | 122 | ////ls:=make([]byte,200) 123 | ////utf8.EncodeRune(out.Bytes()) 124 | ////for len(out.Bytes()) > 0 { 125 | //// r, size := utf8.DecodeRune(out.Bytes()) 126 | //// fmt.Printf("%c %v", r, size) 127 | //// b = b[size:] 128 | ////} 129 | //////lrune:=bytes.Runes(ls) 130 | ////fmt.Println(string(lrune)) 131 | // 132 | ////b := out.Bytes() 133 | ////for len(out.Bytes()) > 0 { 134 | //// r, size := utf8.DecodeRune(out.Bytes()) 135 | //// fmt.Printf("%c %v", r, size) 136 | //// b = b[size:] 137 | ////} 138 | //fmt.Println("--------------------") 139 | //b := out.Bytes() 140 | // 141 | // 142 | // 143 | //fmt.Print() 144 | ////fmt.Print(out.String()) 145 | //fmt.Print(out) 146 | //fmt.Println("---2222-----------------") 147 | //for len(b) > 0 { 148 | // r, size := utf8.DecodeRune(b) 149 | // //fmt.Print(r,",") 150 | // fmt.Printf("%v",string(r)) 151 | // b = b[size:] 152 | //} 153 | // 154 | ////对string由gbk转码为utf8 155 | //fmt.Println("******************") 156 | //response := ConvertToByte(out.String(), "gbk", "utf8") 157 | //fmt.Println(response) 158 | //fmt.Println(string(response)) 159 | // 160 | ////写入到文件 161 | //f,err:=os.OpenFile("test4.txt",os.O_APPEND,0777) 162 | //if err !=nil{ 163 | // fmt.Println(err) 164 | //} 165 | //f.Write(response) 166 | //f.Close() 167 | } 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /io_pro/main/golang.org.x.text.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "bytes" 4 | "fmt" 5 | "golang.org/x/text/encoding/simplifiedchinese" 6 | "io/ioutil" 7 | "log" 8 | ) 9 | 10 | func main() { 11 | //编码unicode成为GB18030码 12 | enc := simplifiedchinese.GB18030.NewEncoder()//申明一个编码器(相对于unicode来说确实是编码) 13 | encBuf := bytes.NewBuffer(make([]byte, 0))//申明一个encBuf来存储转换后的原生字节 14 | // 序列(无任何编码的遵循unicode协议的字节序列,他是unicode值,但是unicode不是一种编码,而是一种规范和协议) 15 | 16 | // Writer包装另一个Writer对其UTF-8输出进行编码。 17 | //只要使用了返回的Writer,编码器就不能用于任何其他操作。 18 | writ := enc.Writer(encBuf)//申明一个对接encBuf缓存的写入器,这个写入器是由编码器生成的, 19 | // 因此它具有编码的功能, 在这儿是把GB18030转成原生字节的转码器 20 | writ.Write([]byte("这段内容是要被编码转换"))//把一个原生字节序列或者叫unicode字符串经过 21 | // 写入器(内含GB18030编码器)写入到encBuf缓存容器中去,此时缓存容器里面存的是GB18030编码后的 22 | //字节序列 23 | fmt.Println(encBuf)//这个是buf类型 24 | fmt.Println(encBuf.Bytes())//转成字节类型才能打印 25 | fmt.Println("编码后的内容", encBuf.String())//String()是对缓存容器里面的原生字节序列进行go内置的utf8解码 26 | //并且打印出utf8字符串,但是由于他是GB18030值,而go却采用的是utf8的解码器去解码,所以不会成功打印的! 27 | //-------------------------------------------------------------- 28 | 29 | //解码GB18030成为unicode之后再编码成为utf8 30 | dec := simplifiedchinese.GB18030.NewDecoder()//声明一个解码器(相对于unicode来说确实是解码) 31 | read := dec.Reader(encBuf) //跟上面一样写入缓存需要一个写入器,读出缓存也需要一个读取器来读取缓存容器里面的内容 32 | decBuf, err := ioutil.ReadAll(read)//上面说到编码器写入到缓存容器中,这时候解码器需要从 33 | //缓存容器中读取GB18030字节序列出来,并且返回新的字节切片 34 | if err != nil { 35 | log.Println(err) 36 | } 37 | fmt.Println(decBuf)//[232 191 153 230 174 181 229 134 133 229 174 185 230 152 175 232 166 129 232 162 38 | // 171 231 188 150 231 160 129 232 189 172 230 141 162] 39 | fmt.Println("解码后的内容", string(decBuf))//跟上面string函数一样 40 | 41 | 42 | //缩写方式1如下: 43 | //reader := simplifiedchinese.GB18030.NewDecoder().Reader(resp.Body) 44 | //buf, err := ioutil.ReadAll(reader) 45 | 46 | //中级缩写方式2如下: 47 | ////utf8转gbk 48 | //src:="编码转换内容内容" 49 | ////src:=[]byte{78, 45, 86, 253, 78, 186}//unicode码值 50 | //fmt.Println(src) 51 | //fmt.Println([]byte(src))//[231 188 150 231 160 129 232 189 172 230 141 52 | //// 162 229 134 133 229 174 185 229 134 133 229 174 185] 53 | ////每3个字节为一个中文字,这是典型的utf8编码后的字节序列 54 | // 55 | ////将utf8的字节序列转化为gbk的字节序列 56 | //data, _ := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(src)), simplifiedchinese.GBK.NewEncoder())) 57 | ////[177 224 194 235 215 170 187 187 196 218 200 221 196 218 200 221] 58 | ////每2个字节为一个中文字 59 | //fmt.Println(data) //byte 60 | ////因为他采用的是utf8来解码序列了,很明显这是gbk才能解码的序列 61 | //fmt.Println(string(data)) //打印为乱码:����ת���������� 62 | } 63 | -------------------------------------------------------------------------------- /io_pro/main/gzip/dst.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/gzip/dst.gz -------------------------------------------------------------------------------- /io_pro/main/gzip/dst2.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/gzip/dst2.gz -------------------------------------------------------------------------------- /io_pro/main/gzip/gzip.txt: -------------------------------------------------------------------------------- 1 | abc西班牙政府都傻眼了,美国和西方的政客及媒体一时不知说什么。那些媒体的第一反应是 " 低调报道 "。很显然,美国和西方大力支持的香港式民主开始向西方回流。老胡要说一句,这真是报应啊。 2 | 不仅西班牙,英国的环保主义者也试图学习香港示威者的战术占领机场,同样在澳大利亚,也有一批环保主义者试图模仿香港示威者采取行动。香港示威者的暴力方式有可能嫁接到西方社会广泛存在的各种问题上,通过变异的方式逐渐引爆。加泰罗尼亚只是一个开始。abc -------------------------------------------------------------------------------- /io_pro/main/gzip/gzip02.txt: -------------------------------------------------------------------------------- 1 | 因为Unicode可以采用16位或者32位编码,所以计算机在处理时需要知道其字节顺序,BOM就是用来标识字节流的字节顺序的,但字节顺序这个概念对UTF-8来说是没有意义的,所以BOM对UTF-8同样没有意义。然而Unicode标准BOM却在UTF-8编码格式中存在,其存在位置在文件开头,以三个字节0xEF, 0xBB, 0xBF表示。 2 | UTF-8编码不推荐使用无意义的BOM,但许多Windows程序却在保存UTF-8编码的文件时将其存为带BOM的格式(即在文件开头加上0xEFBBBF三个字节),这么干的就包括Windows记事本。这是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。对于一般的文件,这样并不会产生什么麻烦。但对于PHP来说,BOM是个大麻烦。 3 | PHP并不会忽略BOM,所以在读取、包含或者引用这些文件时,会把BOM作为该文件开头正文的一部分。根据嵌入式语言的特点,这串字符将被直接执行(显示)出来。由此造成即使页面的 top padding 设置为0,也无法让整个网页紧贴浏览器顶部。 -------------------------------------------------------------------------------- /io_pro/main/index2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | router := gin.Default() 10 | router.LoadHTMLGlob("templates/*") //解析模板,或者采用下面注释掉的代码来进行解析模板,如果你学过了text.template包下的解析函数的话,那么此刻这2个函数对你来说都不是大问题! 11 | //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html") 12 | router.GET("/index", func(c *gin.Context) { 13 | //填充执行模板 14 | c.HTML(http.StatusOK, "index.tmpl", gin.H{ 15 | "title": "Main website", 16 | }) 17 | }) 18 | router.Run(":8080") 19 | } 20 | -------------------------------------------------------------------------------- /io_pro/main/io_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | func main() { 8 | byte_slice:=[]byte{0,1,2,3,4,5,6} 9 | 10 | var R =io.SectionReader{} 11 | src,err:=R.Read(byte_slice) 12 | 13 | fmt.Println(src,err) 14 | } 15 | 16 | -------------------------------------------------------------------------------- /io_pro/main/io_ioutil_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "io/ioutil" 7 | ) 8 | //创建一个io.Reader对象 9 | type myReader struct { 10 | s string//字符串 11 | i int64//当前的字节索引 12 | prevRune int // index of previous rune; or < 0 13 | 14 | } 15 | 16 | func newmyReader(s string) *myReader { 17 | return &myReader{ 18 | s: s,//字符串,表示可以通过字符串创建 19 | i: 0,//读索引 20 | prevRune: -1,//Rune的索引 21 | } 22 | } 23 | 24 | func (r *myReader) Read(b []byte) (n int, err error) { 25 | if r.i >= int64(len(r.s)) { 26 | r.i=0//置零指针 27 | return 0, io.EOF//返回io.EOF告诉调用方已经读到结尾了 28 | } 29 | r.prevRune = -1 30 | n = copy(b, r.s[r.i:]) 31 | r.i += int64(n) 32 | 33 | return//读取部分,返回部分字节,但不是读到末尾了 34 | } 35 | func(r *myReader) resetIndex() { 36 | ioutil.ReadAll(r) 37 | } 38 | 39 | func main() { 40 | mR:=newmyReader("abcdef124") 41 | ls:=make([]byte,13) 42 | n,err111:=mR.Read(ls) 43 | if err111 != nil { 44 | fmt.Println(err111) 45 | } 46 | fmt.Println("此次读取的ls:",ls,"长度为:",n) 47 | 48 | mR.resetIndex() 49 | bytes, e := ioutil.ReadAll(mR) 50 | if e != nil{ 51 | fmt.Println("==================",e) 52 | } 53 | fmt.Println("接着上次的读取停止位置一次性读取剩余的全部bytes:",bytes) 54 | fmt.Println("len(bytes)",len(bytes),"cap(bytes)",cap(bytes)) 55 | } 56 | 57 | -------------------------------------------------------------------------------- /io_pro/main/io_ioutil_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "strings" 7 | ) 8 | 9 | func main() { 10 | // r := strings.NewReader("Hello, Reader!") 11 | 12 | bytes, e := ioutil.ReadFile(`main\test.txt`) //读取整个文件,第一个参数跟打开的主文件目录有关,感觉很奇怪 13 | if e != nil { 14 | fmt.Println(e) 15 | } 16 | fmt.Println(bytes) 17 | fmt.Println(string(bytes)) 18 | fmt.Println(len(bytes), cap(bytes)) 19 | fmt.Println("------------------------------------") 20 | 21 | Fi, err000 := ioutil.ReadDir("main") //按字母排序返回一个os.FileInfo对象列表 22 | if err000 != nil { 23 | fmt.Println(err000) 24 | } 25 | fmt.Println(Fi) 26 | for _, v := range Fi { 27 | fmt.Println(v.Name()) 28 | } 29 | fmt.Println("------------------------------------") 30 | 31 | r := strings.NewReader("Hello, Reader!") 32 | RClose := ioutil.NopCloser(r) //完全是为了让io.Reader方便转为io.ReadCloser对象而不用通过实现io.ReadCloser来实例化这个对象 33 | ls := make([]byte, 10) 34 | RClose.Read(ls) 35 | fmt.Println(string(ls)) 36 | RClose.Close() //什么都没做,所以一般不会用这个方法的 37 | fmt.Println("------------------------------------") 38 | 39 | err222 := ioutil.WriteFile("main/test3.txt", []byte{99, 100, 101, 102, 103, 104, 105, 106}, 0777) //直接将字节写入到文件中去,需要指定文件权限名 40 | if err222 != nil { 41 | fmt.Println(err222) 42 | } 43 | 44 | // fmt.Println("------------------------------------") 45 | 46 | // newDir, err333 := ioutil.TempDir("main", "temp_") //在main里面创建一个以temp_前缀为开始的随机名字的文件夹, 47 | // // 即使之前已经创建过一次也再次创建,因为每次创建的文件目录名字是不一样的 48 | // fmt.Println(newDir) 49 | // fmt.Println(err333) 50 | 51 | // fmt.Println("------------------------------------") 52 | 53 | // newFile, err444 := ioutil.TempFile("main", "tempF_") //在main里面创建一个以temp_前缀为开始的随机名字的文件夹 54 | // fmt.Println(newFile) 55 | // fmt.Println(err444) 56 | 57 | fmt.Println("------------------------------------") 58 | 59 | ls111 := []byte{99, 100, 101, 102, 103, 104, 105, 106} 60 | n, err555 := ioutil.Discard.Write(ls111) //事实上这里什么都没写入的!不过不知道到底有什么用 61 | if err555 != nil { 62 | fmt.Println(err555) 63 | } 64 | fmt.Println(n) 65 | fmt.Println(ioutil.Discard) //0 66 | // ioutil.devNull //这个名字是小写,所以不能外用! 67 | 68 | } 69 | -------------------------------------------------------------------------------- /io_pro/main/log/log.txt: -------------------------------------------------------------------------------- 1 | p3032019/10/29 这是一条日志 2 | -------------------------------------------------------------------------------- /io_pro/main/log/output.txt: -------------------------------------------------------------------------------- 1 | p303 2019/10/29 这是一条Output方法输出到文件的日志111 2 | -------------------------------------------------------------------------------- /io_pro/main/log_syslog.md: -------------------------------------------------------------------------------- 1 | # 此包在着手写的日程中,请期待! 2 | 3 | -------------------------------------------------------------------------------- /io_pro/main/lzw/.idea/lzw.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /io_pro/main/lzw/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /io_pro/main/lzw/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /io_pro/main/lzw/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /io_pro/main/lzw/lzw.txt: -------------------------------------------------------------------------------- 1 | abc京世园会的各国朋友致以谢意。他表示,本届世园会以“绿色生活,美丽家园”为主题,精彩纷呈、成果丰硕。 2 | 在开幕式上,中国国家主席习近平倡导共同建设美丽地球家sdsdsdsd园、构建人类命运共同体。这是一场文明互鉴的绿色盛会,促进了各国文明交流、民心相通和绿色合作。这是一场创新荟萃的科技盛会,展现了绿色科技应用的美好前景。 3 | 这是一场走进自然的体验盛会,中外访客用心感受环保与发展相互促进、人与自然和谐共处的美好abc -------------------------------------------------------------------------------- /io_pro/main/lzw/lzw_dst.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/lzw/lzw_dst.pdf -------------------------------------------------------------------------------- /io_pro/main/lzw/lzw_dst.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/lzw/lzw_dst.txt -------------------------------------------------------------------------------- /io_pro/main/lzw/lzw_src.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/lzw/lzw_src.pdf -------------------------------------------------------------------------------- /io_pro/main/math_cmplx.md: -------------------------------------------------------------------------------- 1 | # 关于复数的这个包不大想写,请自行了解。用法跟math中的其他包没什么特别大的区别! -------------------------------------------------------------------------------- /io_pro/main/mytemp/templ1.txt: -------------------------------------------------------------------------------- 1 | 亲爱的:{{.Name}} 2 | {{if .Attended}} 3 | It was 这是我自定义的模板templ111,a pleasure to see you at the wedding.{{else}} 4 | It is a shame you couldn't make it to the wedding.{{end}} 5 | {{with .Gift}}Thank you for the lovely {{.}}. 6 | {{end}} 7 | -------------------------------------------------------------------------------- /io_pro/main/mytemp/templ2.txt: -------------------------------------------------------------------------------- 1 | 亲爱的:{{.Name}} 2 | {{if .Attended}} 3 | It was 这是我自定义的模板templ222,a pleasure to see you at the wedding.{{else}} 4 | It is a shame you couldn't make it to the wedding.{{end}} 5 | {{with .Gift}}Thank you for the lovely {{.}}. 6 | {{end}} 7 | -------------------------------------------------------------------------------- /io_pro/main/os_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | mapping := func(key string) string { 10 | m := make(map[string]string) 11 | m = map[string]string{ 12 | "world": "kitty", 13 | "hello": "hi", 14 | } 15 | if m[key] != "" { 16 | return m[key] 17 | } 18 | return key 19 | } 20 | s := "hello,world" // hello,world,由于hello world之前没有$符号,则无法利用map规则进行转换 21 | s1 := "$hello,$world $finish" // hi,kitty finish,finish没有在map规则中,所以还是返回原来的值 22 | fmt.Println(os.Expand(s, mapping)) 23 | fmt.Println(os.Expand(s1, mapping)) 24 | 25 | //s2 := "hello $GOROOT11" 26 | s2 := "hello $GOROOT" 27 | fmt.Println(os.ExpandEnv(s2))//$GOROOT替换为环境变量的值,而h没有环境变量可以替换,返回空字符串 28 | 29 | 30 | 31 | } -------------------------------------------------------------------------------- /io_pro/main/os_04.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | attr := &os.ProcAttr{ 10 | Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, //其他变量如果不清楚可以不设定 11 | } 12 | //notepad.exe 打开main/tmp.txt文件 13 | p, err := os.StartProcess(`C:\Windows\System32\notepad.exe`, []string{`C:\Windows\System32\notepad.exe`, 14 | `C:\Users\Administrator\Desktop\go_pro\src\io_pro\main\test.txt`}, attr)//阻塞的,直到文件被关闭 15 | 16 | fmt.Println("1111111111") 17 | if err != nil { 18 | fmt.Println(err) 19 | } 20 | fmt.Println(p) //&{3308 288 0 {{0 0} 0 0 0 0}} 21 | pro, _ := os.FindProcess(p.Pid) //查找进程 22 | fmt.Println(pro) //&{3308 244 0 {{0 0} 0 0 0 0}} 23 | 24 | 25 | // StartProcess使用名称,argv和attr指定的程序,参数和属性启动新进程。 argv slice在新进程中将变为os.Args,因此它通常以程序名称开头。 26 | //如果调用的goroutine已使用runtime.LockOSThread锁定了操作系统线程,并修改了任何可继承的OS级线程状态(例如Linux或Plan 9命名空间),则新进程将继承调用者的线程状态。 27 | // StartProcess是一个低级接口。 os / exec软件包提供了更高级别的接口。 28 | //如果有错误,它将是* PathError类型。 29 | 30 | 31 | } -------------------------------------------------------------------------------- /io_pro/main/os_05.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | attr := &os.ProcAttr{ 11 | Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, //其他变量如果不清楚可以不设定 12 | } 13 | //notepad.exe 打开main/tmp.txt文件 14 | p, err := os.StartProcess(`C:\Windows\System32\notepad.exe`, []string{`C:\Windows\System32\notepad.exe`, 15 | `C:\Users\Administrator\Desktop\go_pro\src\io_pro\main\test.txt`}, attr)//阻塞的,直到文件被关闭 16 | 17 | fmt.Println("1111111111") 18 | if err != nil { 19 | fmt.Println(err) 20 | } 21 | fmt.Println(p) //&{3308 288 0 {{0 0} 0 0 0 0}} 22 | pro, _ := os.FindProcess(p.Pid) //查找进程 23 | fmt.Println(pro) //&{3308 244 0 {{0 0} 0 0 0 0}} 24 | 25 | fmt.Println("------------------------") 26 | fmt.Println("333") 27 | time.Sleep(4) 28 | go func() { 29 | fmt.Println("444") 30 | time.Sleep(6e9)//nano 31 | //发送一个信号给进程p, 在windows中没有实现发送中断interrupt 32 | p.Signal(os.Kill) //kill process 33 | }() 34 | fmt.Println("222") 35 | pstat, err := p.Wait() 36 | if err != nil { 37 | fmt.Println("111",err) 38 | } 39 | 40 | fmt.Println(pstat) //exit status 1,如果是linux的话会显示signal: killed 41 | 42 | 43 | // StartProcess使用名称,argv和attr指定的程序,参数和属性启动新进程。 argv slice在新进程中将变为os.Args,因此它通常以程序名称开头。 44 | //如果调用的goroutine已使用runtime.LockOSThread锁定了操作系统线程,并修改了任何可继承的OS级线程状态(例如Linux或Plan 9命名空间),则新进程将继承调用者的线程状态。 45 | // StartProcess是一个低级接口。 os / exec软件包提供了更高级别的接口。 46 | //如果有错误,它将是* PathError类型。 47 | 48 | 49 | } -------------------------------------------------------------------------------- /io_pro/main/os_exec_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "log" 7 | "os/exec" 8 | "strings" 9 | ) 10 | 11 | 12 | 13 | func main() { 14 | 15 | fmt.Println("-------------------") 16 | cmd := exec.Command(`ping`,"www.baidu.com" ) 17 | 18 | cmd.Stdin = strings.NewReader("some input") 19 | var out bytes.Buffer 20 | cmd.Stdout = &out 21 | err := cmd.Run() 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | //simplifiedchinese.GB18030 27 | fmt.Println(out.String()) 28 | 29 | fmt.Println("======***********========") 30 | 31 | 32 | 33 | cmd.Wait()//必须在所有管道读取之后才wait,他主要是关闭管道,释放相关的资源的作用 34 | 35 | } 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /io_pro/main/os_signal_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | attr := &os.ProcAttr{ 12 | Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, //其他变量如果不清楚可以不设定 13 | } 14 | //notepad.exe 打开main/tmp.txt文件 15 | p, err := os.StartProcess(`C:\Windows\System32\notepad.exe`, []string{`C:\Windows\System32\notepad.exe`, 16 | `C:\Users\Administrator\Desktop\go_pro\src\io_pro\main\test.txt`}, attr)//阻塞的,直到文件被关闭 17 | 18 | fmt.Println("1111111111") 19 | if err != nil { 20 | fmt.Println(err) 21 | } 22 | fmt.Println(p) //&{3308 288 0 {{0 0} 0 0 0 0}} 23 | pro, _ := os.FindProcess(p.Pid) //查找进程 24 | fmt.Println(pro) //&{3308 244 0 {{0 0} 0 0 0 0}} 25 | 26 | fmt.Println("------------------------") 27 | fmt.Println("333") 28 | time.Sleep(4) 29 | //创建一个主协程跟子协程通信的通道 30 | //为了实现在不同的协程中控制另外一个协程 31 | 32 | go func() { 33 | ch:=make(chan os.Signal,1) 34 | fmt.Println("444") 35 | time.Sleep(6e9)//nano 36 | signal.Notify(ch, os.Interrupt)//往管道塞进东西 37 | //发送一个信号给进程p, 在windows中没有实现发送中断interrupt 38 | p.Signal(os.Interrupt) //kill process 39 | //signal.Notify(ch, os.Interrupt, os.Kill)//os.Interrupt在windows中不起作用 40 | //signal.Notify(ch, os.Kill)//往管道塞进东西 41 | fmt.Println("5555555555555") 42 | s := <-ch 43 | fmt.Println("Got signal:", s) 44 | 45 | }() 46 | 47 | fmt.Println("77777777777777777") 48 | 49 | fmt.Println("222") 50 | pstat, err := p.Wait() 51 | if err != nil { 52 | fmt.Println("111",err) 53 | } 54 | time.Sleep(6e9) 55 | //fmt.Println("程序执行结束") 56 | fmt.Println(pstat) //exit status 1,如果是linux的话会显示signal: killed 57 | 58 | 59 | // StartProcess使用名称,argv和attr指定的程序,参数和属性启动新进程。 argv slice在新进程中将变为os.Args,因此它通常以程序名称开头。 60 | //如果调用的goroutine已使用runtime.LockOSThread锁定了操作系统线程,并修改了任何可继承的OS级线程状态(例如Linux或Plan 9命名空间),则新进程将继承调用者的线程状态。 61 | // StartProcess是一个低级接口。 os / exec软件包提供了更高级别的接口。 62 | //如果有错误,它将是* PathError类型。 63 | 64 | 65 | } -------------------------------------------------------------------------------- /io_pro/main/os_signal_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | ) 10 | 11 | func main() { 12 | fmt.Println("111111111") 13 | //c := make(chan os.Signal, 3) 14 | //signal.Notify(c, os.Interrupt) 15 | // Block until a signal is received. 16 | 17 | 18 | ch := make(chan os.Signal, 1) 19 | //监控按键以及其他程序或者子协程的运行,用于监控或者重启程序以及程序配置的重新加载 20 | signal.Notify(ch, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM,os.Interrupt) 21 | for { 22 | s := <-ch 23 | switch s { 24 | case syscall.SIGQUIT: 25 | log.Fatalln("SIGSTOP") 26 | return 27 | case syscall.SIGHUP: 28 | log.Fatalln("SIGHUP") 29 | return 30 | case syscall.SIGKILL: 31 | log.Fatalln("SIGKILL") 32 | return 33 | case os.Interrupt: 34 | log.Fatalln("os.Interrupt") 35 | return 36 | default: 37 | log.Fatalln("default") 38 | return 39 | } 40 | } 41 | 42 | 43 | //fmt.Println("222222222222") 44 | //s := <-c 45 | //fmt.Println("333333333333") 46 | //fmt.Println("Got signal:", s) 47 | //fmt.Println("344444444444444") 48 | 49 | } -------------------------------------------------------------------------------- /io_pro/main/os_signal_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "sync" 8 | "syscall" 9 | "time" 10 | ) 11 | //子协程 12 | func consumer(stop <-chan bool) { 13 | for { 14 | select { 15 | //不停的检测来自系统的信号的管道的是否有值,一旦有值就停止子协程,stop是系统信号有无标志的管道 16 | case <-stop: 17 | fmt.Println("exit sub goroutine") 18 | return 19 | default: 20 | fmt.Println("running...") 21 | time.Sleep(500 * time.Millisecond) 22 | } 23 | } 24 | } 25 | func main() { 26 | stop := make(chan bool) 27 | var wg sync.WaitGroup 28 | //开启三个协程 29 | for i := 0; i < 3; i++ { 30 | wg.Add(1) 31 | go func(stop <-chan bool) { 32 | defer wg.Done() 33 | consumer(stop)//协程主函数 34 | }(stop) 35 | } 36 | waitForSignal()//阻塞 37 | //一旦解开阻塞就说明有来自系统的信号了,接着关闭这个管道就相当于往这个管道上面发送2个false值 38 | //第一个false值是管道元素的零值,第二个值是管道的标志位值,当关闭管道的时候会将此标志设置为 39 | //false并且将这个值发送到管道里面去。 40 | close(stop) 41 | fmt.Println("stopping all jobs!") 42 | wg.Wait()//之所以 要上锁是因为多个进程不同步操作这段代码会导致管道里面的值来自多个进程! 43 | } 44 | func waitForSignal() { 45 | //创建信号管道,没指定缓存代表监听所有类型的信号,一般指定1即可 46 | sigs := make(chan os.Signal) 47 | signal.Notify(sigs, os.Interrupt) 48 | signal.Notify(sigs, syscall.SIGTERM) 49 | <-sigs//阻塞监听是否有来自系统的信号出现,一旦出现就解开阻塞 50 | } 51 | -------------------------------------------------------------------------------- /io_pro/main/os_user_01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os/user" 6 | ) 7 | 8 | func main() { 9 | user111,err:=user.Current() 10 | if err != nil{ 11 | fmt.Println(err) 12 | } 13 | //输出结果:&{S-1-5-21-1198569543-3519917723-292291289-500 S-1-5-21-1198569543-3519917723-292291289-513 WIN-5EP8LP6GHN7\Administrator C:\Users\Administrator} 14 | fmt.Println(user111) 15 | fmt.Println(user111.Name)//为空字符串 16 | fmt.Println(user111.Gid)//S-1-5-21-1198569543-3519917723-292291289-513 17 | fmt.Println(user111.Uid)//S-1-5-21-1198569543-3519917723-292291289-500 18 | fmt.Println(user111.Username)//WIN-5EP8LP6GHN7\Administrator 19 | fmt.Println(user111.GroupIds())//[S-1-5-32-544 S-1-5-21-1198569543-3519917723-292291289-513] 20 | fmt.Println(user111.HomeDir)//C:\Users\Administrator 21 | 22 | fmt.Println("---------------------") 23 | user222,err222:=user.Lookup(`WIN-5EP8LP6GHN7\Administrator`) 24 | if err222 != nil{ 25 | fmt.Println(err222) 26 | } 27 | //&{S-1-5-21-1198569543-3519917723-292291289-500 S-1-5-21-1198569543-3519917723-292291289-513 WIN-5EP8LP6GHN7\Administrator C:\Users\Administrator} 28 | fmt.Println(user222) 29 | 30 | fmt.Println("---------------------") 31 | user333,err333:=user.LookupId("S-1-5-21-1198569543-3519917723-292291289-500") 32 | if err333 != nil{ 33 | fmt.Println(err333) 34 | } 35 | //&{S-1-5-21-1198569543-3519917723-292291289-500 S-1-5-21-1198569543-3519917723-292291289-513 WIN-5EP8LP6GHN7\Administrator C:\Users\Administrator} 36 | fmt.Println(user333) 37 | 38 | 39 | fmt.Println("---------------------") 40 | user444,err444:=user.LookupGroupId("S-1-5-21-1198569543-3519917723-292291289-513")//注意这个返回的不是*user,而是*Group 41 | if err444 != nil{ 42 | fmt.Println(err444) 43 | } 44 | 45 | fmt.Println(user444.Name)//None 46 | fmt.Println(user444.Gid)//S-1-5-21-1198569543-3519917723-292291289-513 47 | 48 | 49 | 50 | } -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201182115354.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201182115354.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201182548667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201182548667.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201182557772.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201182557772.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201182734459.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201182734459.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201183128167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201183128167.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201183232729.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201183232729.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201183452657.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201183452657.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201183742563.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201183742563.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201183918097.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201183918097.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201185235815.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201185235815.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201192742193.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201192742193.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201192834669.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201192834669.png -------------------------------------------------------------------------------- /io_pro/main/pic/image-20191201192855541.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/main/pic/image-20191201192855541.png -------------------------------------------------------------------------------- /io_pro/main/reflect_03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | 10 | type ppp struct { 11 | name string 12 | age int 13 | } 14 | var p ppp 15 | //=ppp{"anko",88} 16 | fmt.Printf("%#v\n",p) 17 | if reflect.ValueOf(p).IsValid(){ 18 | fmt.Println("有效值,非zero Value") 19 | }else { 20 | fmt.Println("zero Value,无效值") 21 | } 22 | //只要是reflect.ValueOf()返回的值都不会是reflect.Value{}这个零值 23 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p).Elem()).IsZero()) 24 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p)).IsZero())//这个有没有疑问的? 25 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.Value{}).IsZero())//这个有没有疑问的? 26 | fmt.Printf("%#v\n",reflect.ValueOf(p).IsZero()) 27 | fmt.Printf("%#v\n",reflect.ValueOf(&p).IsZero()) 28 | 29 | fmt.Println() 30 | var p1 *ppp 31 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p1).Elem()).IsZero()) 32 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p1).Elem()).IsZero()) 33 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p1)).IsZero()) 34 | fmt.Printf("%#v\n",reflect.ValueOf(p1).IsZero()) 35 | fmt.Printf("%#v\n",reflect.ValueOf(&p1).IsZero()) 36 | 37 | 38 | fmt.Println() 39 | var p2 *ppp 40 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向*ppp) 41 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p2).Elem()).IsNil()) 42 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向ppp) 43 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p2).Elem()).IsNil()) 44 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向*ppp) 45 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p2)).IsNil()) 46 | fmt.Printf("%#v\n",reflect.ValueOf(p2).IsNil()) 47 | fmt.Printf("%#v\n",reflect.ValueOf(&p2).IsNil()) 48 | 49 | //输出: 50 | // main.ppp{name:"", age:0} 51 | // 有效值,非zero Value 52 | // false 53 | // false 54 | // true 55 | // false 56 | // 57 | // false 58 | // true 59 | // false 60 | // true 61 | // false 62 | // 63 | // true 64 | // false 65 | } 66 | -------------------------------------------------------------------------------- /io_pro/main/sql_driver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql/driver" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | 10 | //// Value is a value that drivers must be able to handle. 11 | //// It is either nil, a type handled by a database driver's NamedValueChecker 12 | //// interface, or an instance of one of these types: 13 | //// 14 | //// int64 15 | //// float64 16 | //// bool 17 | //// []byte 18 | //// string 19 | //// time.Time 20 | //// 21 | //// If the driver supports cursors, a returned Value may also implement the Rows interface 22 | //// in this package. This is used, for example, when a user selects a cursor 23 | //// such as "select cursor(select * from my_table) from dual". If the Rows 24 | //// from the select is closed, the cursor Rows will also be closed. 25 | //// 值是驱动程序必须能够处理的值。 26 | //// 它要么是nil,由数据库驱动程序的NamedValueChecker接口处理的类型,或者是以下类型之一的实例: 27 | //// 28 | //// int64 29 | //// float64 30 | //// bool 31 | //// []byte 32 | //// string 33 | //// time.Time 34 | //// 35 | //// 如果驱动程序支持游标,则返回的Value也可以在此包中实现Rows接口。 36 | //// 例如,当用户选择一个游标,例如“从双精度选择游标(从my_table中选择*)”时,将使用此功能。 如果选择中的行被关闭,则游标行也将被关闭。 37 | //type Value interface{} 38 | 39 | 40 | 41 | // IsValue reports whether v is a valid Value parameter type. 42 | // IsValue报告v是否为有效的type Value interface{}参数类型。 43 | var i int=5 44 | fmt.Println(driver.IsValue(i)) 45 | var i1 int32=5 46 | fmt.Println(driver.IsValue(i1)) 47 | var i2 int64=5 48 | fmt.Println(driver.IsValue(i2)) 49 | 50 | var i3 bool=true 51 | fmt.Println(driver.IsValue(i3)) 52 | //输出: 53 | // false 54 | // false 55 | // true 56 | // true 57 | //更多类型请自行测试 58 | 59 | // IsScanValue is equivalent to IsValue. 60 | // It exists for compatibility. 61 | // IsScanValue等效于IsValue。 62 | //它是为了兼容而存在。 63 | //底层完全等价于IsValue() 64 | fmt.Println(driver.IsScanValue(i)) 65 | fmt.Println(driver.IsScanValue(i1)) 66 | fmt.Println(driver.IsScanValue(i2)) 67 | fmt.Println(driver.IsScanValue(i3)) 68 | //输出: 69 | // false 70 | // false 71 | // true 72 | // true 73 | //更多类型请自行测试 74 | 75 | 76 | //这整个包都是定义了接口而已,如果需要自己写实现的话会非常的复杂,如果需要探究的,请自行查看"github.com/go-sql-driver/mysql"包里面的实现 77 | //其实很多接口类型的用法都已经在sql包中讲到了 78 | 79 | 80 | 81 | } 82 | 83 | 84 | 85 | func check_err_sql(err error) { 86 | if err != nil { 87 | fmt.Println(err) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /io_pro/main/sql_regester().go: -------------------------------------------------------------------------------- 1 | //这整个文件都是为了说明sql.Register()的用法 2 | package main 3 | 4 | import ( 5 | "database/sql" 6 | "fmt" 7 | "github.com/go-sql-driver/mysql" 8 | 9 | //_ "github.com/go-sql-driver/mysql" //一定要导入这个 10 | ) 11 | /* 12 | 13 | 在进行下面的测试之前,我们必须将外置库\src\github.com\go-sql-driver\mysql\driver.go中的2行注释掉: 14 | 第一行是开头的导入包行: 15 | import ( 16 | "context" 17 | //"database/sql"//将这行注释掉 18 | "database/sql/driver" 19 | "net" 20 | "sync" 21 | ) 22 | 第2行是本文件中的最后一个init()函数: 23 | //func init() { 24 | // sql.Register("mysql", &MySQLDriver{}) 25 | //} 26 | 27 | 你可以看到上面的init函数其实跟我们要写的函数是一样的!因为如果我们要测试sql.Register()函数的话则只能这样测试,这个函数 28 | 就是用来注册驱动的!如果你不注册的话,例如将我们这本文件中init()函数注释掉然后执行本文件的话会抛出以下的异常: 29 | panic: sql: unknown driver "mysql" (forgotten import?) 30 | 31 | goroutine 1 [running]: 32 | main.main() 33 | C:/Users/Administrator/Desktop/go_pro/src/io_pro/main3/compress_zlib.go:14 +0x473 34 | 35 | 36 | 其实报错就是这样报错:db, err := sql.Open("mysql", "root:mysql@/godb"),因为mysql这个驱动还没注册(注册不是指简单的指定名称 37 | 即可,我们之所以不自己写注册驱动代码是因为目前来说还不会写(在后面会讲解到怎么写),所以既然有第三方写好的了,我们就拿来测试sql.Register()函数的功能。) 38 | */ 39 | func main() { 40 | db, err := sql.Open("mysql111", "root:mysql@/godb")//这个mysql111必须跟下面的init函数中注册的name相同才可以 41 | if err != nil { 42 | panic(err.Error()) 43 | } 44 | 45 | defer db.Close() 46 | 47 | err = db.Ping() 48 | if err != nil { 49 | panic(err.Error()) 50 | } 51 | 52 | rows, err := db.Query("select * from person") 53 | check_err_sql(err) 54 | 55 | type person struct { 56 | id int 57 | name string 58 | age int 59 | } 60 | 61 | for b:=rows.Next(); b != false;b=rows.Next() { 62 | var p =person{} 63 | err := rows.Scan(&p.id, &p.name, &p.age) 64 | check_err_sql(err) 65 | fmt.Println(p) 66 | } 67 | //输出: 68 | // {1 anko 20} 69 | // {2 gogo 32} 70 | 71 | } 72 | 73 | func check_err_sql(err error) { 74 | if err != nil { 75 | fmt.Println(err) 76 | } 77 | } 78 | //本init函数会在所有本文件的代码执行之前执行 79 | func init() { 80 | fmt.Println("-------------------注册驱动---------------------------") 81 | 82 | //// Driver is the interface that must be implemented by a database 83 | //// driver. 84 | //// 85 | //// Database drivers may implement DriverContext for access 86 | //// to contexts and to parse the name only once for a pool of connections, 87 | //// instead of once per connection. 88 | ////驱动程序是必须由数据库驱动程序实现的接口。 89 | ////数据库驱动程序可以实现DriverContext来访问上下文,并且对于连接池仅解析一次名称,而不是对每个连接解析一次。 90 | //type Driver interface { 91 | // // Open returns a new connection to the database. 92 | // // The name is a string in a driver-specific format. 93 | // // 94 | // // Open may return a cached connection (one previously 95 | // // closed), but doing so is unnecessary; the sql package 96 | // // maintains a pool of idle connections for efficient re-use. 97 | // // 98 | // // The returned connection is only used by one goroutine at a 99 | // // time. 100 | // // Open返回到数据库的新连接。 101 | // //name是驱动程序特定格式的字符串。 102 | // //Open可以返回一个缓存的连接(以前关闭了一个连接),但是没有必要这样做; sql软件包维护一个空闲连接池,以进行有效的重用。 103 | // //返回的连接一次只能由一个goroutine使用。 104 | // Open(name string) (Conn, error) 105 | //} 106 | 107 | 108 | //// If a Driver implements DriverContext, then sql.DB will call 109 | //// OpenConnector to obtain a Connector and then invoke 110 | //// that Connector's Conn method to obtain each needed connection, 111 | //// instead of invoking the Driver's Open method for each connection. 112 | //// The two-step sequence allows drivers to parse the name just once 113 | //// and also provides access to per-Conn contexts. 114 | ////如果驱动程序实现了DriverContext,则sql.DB将调用OpenConnector以获得连接器,然后调用该连接器的Conn方法以获取每个所需的连接,而不是为每个连接调用驱动程序的Open方法。 115 | ////两步序列允许驱动程序仅解析一次名称,还提供对每个Conn上下文的访问。 116 | //type DriverContext interface { 117 | // // OpenConnector must parse the name in the same format that Driver.Open 118 | // // parses the name parameter. 119 | // // OpenConnector必须以与Driver.Open解析name参数相同的格式解析名称。 120 | // OpenConnector(name string) (Connector, error) 121 | //} 122 | 123 | 124 | // Register makes a database driver available by the provided name. 125 | // If Register is called twice with the same name or if driver is nil, 126 | // it panics. 127 | // Register通过提供的名称name使数据库驱动程序driver可用。 128 | // 如果使用相同的名称两次调用Register或驱动程序为nil,则会出现紧急情况。 129 | sql.Register("mysql111", &mysql.MySQLDriver{}) 130 | //sql.Register("mysql111", &mysql.MySQLDriver{})//重复注册相同的名称两次会报错 131 | } -------------------------------------------------------------------------------- /io_pro/main/tar_data/text1.txt: -------------------------------------------------------------------------------- 1 | 1111111adsdsdsd李克强在致辞中代表中国政府和人民祝贺本届世园会成功举办,并对支持和参与北京世园会的各国朋友致以谢意。他表示,本届世园会以“绿色生活,美丽家园”为主题,精彩纷呈、成果丰硕。 2 | 在开幕式上,中国国家主席习近平倡导共同建设美丽地球家sdsdsdsd园、构建人类命运共同体。这是一场文明互鉴的绿色盛会,促进了各国文明交流、民心相通和绿色合作。这是一场创新荟萃的科技盛会,展现了绿色科技应用的美好前景。 3 | 这是一场走进自然的体验盛会,中外访客用心感受环保与发展相互促进、人与自然和谐共处的美好。sdsdsds -------------------------------------------------------------------------------- /io_pro/main/tar_data/text2.txt: -------------------------------------------------------------------------------- 1 | 2222222222“保持中美关aaabbbb系健康稳定发展,对两国对世界都有利。双方要坚持协abc调、合作、稳定的基调,在相互尊重基础上管控分歧,在互惠互利基础上拓展合作,推动两国关系沿着正确轨道向前发展。” 2 | 习近平主席在致特朗普总统的口信中强调了中方主张,特朗普总统请刘鹤副总理转达对习近平主席的感谢,并明确表示“美中经贸磋商取得了实质性的第一阶段成果,这对美中两国和世界都是重大利好”。abc -------------------------------------------------------------------------------- /io_pro/main/test.txt: -------------------------------------------------------------------------------- 1 | abc伟大的时代创造伟大的工程,伟大的工程反映伟大的时代。党的十八大以来,C919大型客机飞上蓝天, 2 | 港珠澳大桥主体工程全线贯通,复兴号奔驰在祖国广袤的大地上.......一项项民生工程顺利落地,正如习近平所言, 3 | “中国制造、中国创造、中国建造共同发力,继续改变着中国的面貌。”abc 4 | 习近平指出,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女排今 5 | SDSDSDSDSDSD -------------------------------------------------------------------------------- /io_pro/main/test111.txt: -------------------------------------------------------------------------------- 1 | abc伟abc伟abc伟abc伟 -------------------------------------------------------------------------------- /io_pro/main/test222.txt: -------------------------------------------------------------------------------- 1 | 123BBB7890 -------------------------------------------------------------------------------- /io_pro/main/test3.txt: -------------------------------------------------------------------------------- 1 | 下午4时45分,女排队员、教练员代表步入人民大会堂福建厅,习近平同大家一一握手。在听取了领队和教练员、运动员代表发言后,习近平表示,在举国上下庆祝新中国成立70周年的时刻,我首先欢迎你们凯旋,向你们致以热烈的祝贺。 2 | 习近平强调,在第十三届女排世界杯比赛中,你们以十一连胜的骄人成绩夺得了冠军,成功卫冕,为祖国和人民赢得了荣誉。你们不畏强手、敢打敢拼,打出了风格、赛出了水平。在提前一轮锁定冠军的情况下,你们在最后一场比赛中没有丝毫懈怠,尊重对手,尊重自己,坚持打好每一个球,很好诠释了奥林匹克精神和中华体育精神。中国女排夺得了第五个女排世界杯冠军,第十次荣膺世界排球“三大赛”冠军,激发了全国人民的爱国热情,增强了全国人民的民族自信心和自豪感。 -------------------------------------------------------------------------------- /io_pro/main/text_scanner_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "text/scanner" 7 | "unicode" 8 | ) 9 | 10 | 11 | 12 | 13 | func main() { 14 | 15 | 16 | fmt.Println("-----------scanner.IsIdentRune()-------------") 17 | 18 | Example_isIdentRune() 19 | 20 | fmt.Println("-----------scanner.Mode-------------") 21 | Example_mode() 22 | 23 | fmt.Println("-----------scanner.whitespace-------------") 24 | Example_whitespace() 25 | } 26 | 27 | func Example_isIdentRune() { 28 | const src = "%var1 var2%" 29 | 30 | var s scanner.Scanner 31 | s.Init(strings.NewReader(src)) 32 | s.Filename = "default" 33 | 34 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 35 | fmt.Printf("%s: %s\n", s.Position, s.TokenText()) 36 | } 37 | 38 | fmt.Println() 39 | //将上面已经设置好的s初始化(跟重置状态信息差不多) 40 | s.Init(strings.NewReader(src)) 41 | s.Filename = "percent" 42 | 43 | // treat leading '%' as part of an identifier (//将前导'%'视为标识符的一部分) 44 | //Ident是Identify(识别)的缩写,IsIdentRune判断是否是rune 45 | s.IsIdentRune = func(ch rune, i int) bool { 46 | // IsLetter reports whether the rune is a letter (category L). 47 | // IsLetter报告该符文是否为字母(类别L)。 48 | 49 | // IsDigit reports whether the rune is a decimal digit. 50 | // IsDigit报告该符文是否为十进制数字。 51 | //我们把字母,数字和索引为0时候的%号(索引不为0的%号不识别为rune)都认为是rune 52 | return ch == '%' && i == 0 || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0 53 | } 54 | 55 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 56 | fmt.Printf("%s: %s\n", s.Position, s.TokenText()) 57 | } 58 | 59 | // Output: 60 | // default:1:1: % 61 | // default:1:2: var1 62 | // default:1:7: var2 63 | // default:1:11: % 64 | // 65 | // percent:1:1: %var1 66 | // percent:1:7: var2 67 | // percent:1:11: % 68 | } 69 | 70 | 71 | func Example_mode() { 72 | const src = ` 73 | // Comment begins at column 5. 74 | 75 | This line should not be included in the output. 76 | 77 | /* 78 | This multiline comment 79 | should be extracted in 80 | its entirety. 81 | */ 82 | hello world! 83 | ` 84 | 85 | var s scanner.Scanner 86 | s.Init(strings.NewReader(src)) 87 | s.Filename = "comments" 88 | s.Mode ^= scanner.SkipComments // don't skip comments (//不要跳过注释,默认不会识别注释) 89 | 90 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 91 | txt := s.TokenText() 92 | // HasPrefix tests whether the string s begins with prefix. 93 | // HasPrefix测试字符串s是否以前缀开头。 94 | if strings.HasPrefix(txt, "//") || strings.HasPrefix(txt, "/*") { 95 | fmt.Printf("(注释)%s: %s\n", s.Position, txt) 96 | }else { 97 | fmt.Println(txt) 98 | } 99 | 100 | } 101 | 102 | // Output: 103 | // (注释)comments:2:5: // Comment begins at column 5. 104 | // This 105 | // line 106 | // should 107 | // not 108 | // be 109 | // included 110 | // in 111 | // the 112 | // output 113 | // . 114 | // (注释)comments:6:1: /* 115 | // This multiline comment 116 | // should be extracted in 117 | // its entirety. 118 | // */ 119 | // hello 120 | // world 121 | // ! 122 | } 123 | 124 | 125 | 126 | func Example_whitespace() { 127 | // tab-separated values (//制表符分隔的值) 128 | const src = `aa ab ac ad 129 | ba bb bc bd 130 | ca cb cc cd 131 | da db dc dd` 132 | 133 | var ( 134 | col, row int 135 | s scanner.Scanner 136 | tsv [4][4]string // large enough for example above (//足够大,例如以上) 137 | ) 138 | s.Init(strings.NewReader(src)) 139 | // The Whitespace field controls which characters are recognized 140 | // as white space. To recognize a character ch <= ' ' as white space, 141 | // set the ch'th bit in Whitespace (the Scanner's behavior is undefined 142 | // for values ch > ' '). The field may be changed at any time. 143 | //“空白”字段控制将哪些字符识别为空白。 要将字符ch <=' '识别为空白,请在Whitespace属性中设置第ch位(对于值ch>' ', 144 | // 扫描仪Scanner的行为未定义)。 该字段可以随时更改。 145 | // 注意下面的表现形式 146 | s.Whitespace ^= 1<<'\t' | 1<<'\n' // don't skip tabs and new lines (//不要跳过制表符和换行符,也就是识别他们) 147 | 148 | for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { 149 | switch tok { 150 | case '\n': 151 | row++ 152 | col = 0 153 | case '\t': 154 | col++ 155 | default: 156 | tsv[row][col] = s.TokenText() 157 | } 158 | } 159 | 160 | fmt.Print(tsv) 161 | 162 | // Output: 163 | // [[aa ab ac ad] [ba bb bc bd] [ca cb cc cd] [da db dc dd]] 164 | } 165 | 166 | 167 | 168 | 169 | 170 | func check_err(err error) { 171 | if err != nil { 172 | fmt.Println(err) 173 | panic(err) 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /io_pro/main/text_tabwriter_02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "text/tabwriter" 7 | ) 8 | 9 | 10 | func Example_elastic() { 11 | // Observe how the b's and the d's, despite appearing in the 12 | // second cell of each line, belong to different columns. 13 | //观察b和d尽管出现在每行的第二个单元格中,但它们如何属于不同的列。 14 | w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, '.', tabwriter.AlignRight|tabwriter.Debug) 15 | fmt.Fprintln(w, "a\tb\tc") 16 | fmt.Fprintln(w, "aa\tbb\tcc") 17 | fmt.Fprintln(w, "aaa\t") // trailing tab(//尾随制表符),这行会导致下面的行中的列不再对齐上面了 18 | fmt.Fprintln(w, "aaaa\tdddd\teeee") 19 | fmt.Fprintln(w, "a\tb\tc") 20 | fmt.Fprintln(w, "aa\tbb\tcc") 21 | w.Flush() 22 | 23 | // output: 24 | // ....a|..b|c 25 | // ...aa|.bb|cc 26 | // ..aaa| 27 | // .aaaa|.dddd|eeee 28 | // ....a|....b|c 29 | // ...aa|...bb|cc 30 | 31 | //假设注释掉第三行"aaa\t",则会输出: 32 | // ....a|....b|c 33 | // ...aa|...bb|cc 34 | // .aaaa|.dddd|eeee 35 | // ....a|....b|c 36 | // ...aa|...bb|cc 37 | //对比以上两次的输出可以发现,假设出现更宽的列的话,那么接下来的列宽的将会扩展,但是之前的不会扩展,还是以之前的宽度进行对齐 38 | } 39 | 40 | func Example_trailingTab() { 41 | // Observe that the third line has no trailing tab, 42 | // so its final cell is not part of an aligned column. 43 | //请注意,第三行没有尾随制表符,因此其最后一个单元格不是对齐列的一部分。 44 | const padding = 3 45 | 46 | 47 | // NewWriter allocates and initializes a new tabwriter.Writer. 48 | // The parameters are the same as for the Init function. 49 | // NewWriter分配并初始化一个新的tabwriter.Writer。 50 | //这些参数与Init函数的参数相同。 51 | //底层:return new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags) 52 | 53 | //多个flags标志属性之间用|老进行连接,表示一起发挥作用 54 | w := tabwriter.NewWriter(os.Stdout, 0, 0, padding, '-', tabwriter.AlignRight|tabwriter.Debug) 55 | fmt.Fprintln(w, "a\tb\taligned\t")//1 56 | fmt.Fprintln(w, "aa\tbb\taligned\t")//2 57 | fmt.Fprintln(w, "aaa\tbbb\tunaligned") //3// no trailing tab(//没有尾随制表符),这行会导致下面的行中的列不再对齐上面了 58 | fmt.Fprintln(w, "aaaa\tbbbb\taligneddddd\t")//4 59 | fmt.Fprintln(w, "aaaa\tbbbb\tali\t")//5 60 | w.Flush() 61 | 62 | // output: 63 | // ------a|------b|---aligned| 64 | // -----aa|-----bb|---aligned| 65 | // ----aaa|----bbb|unaligned 66 | // ---aaaa|---bbbb|---aligneddddd| 67 | // ---aaaa|---bbbb|-----------ali| 68 | //事实上对不对其行中的列,底层是用一个width的宽度值随着扫描每个单元格的长度同步更新的,也就是width保持最大的值,其实别不存在出现断层的概念, 69 | //我只是为了便于表述才这样说的,比如,为了表述,我简称width为w(w并不是整个单元格的宽度,还要加上padding) 70 | //扫描第1行中的第三列时候:w=len("aligned"),因为w初始化时候为0,所以这里开始扫描时候肯定赋值给w,所以更新w, 71 | //扫描第2行中的第三列时候:w=len("aligned"),因为len("aligned")=len("aligned"),不更新w 72 | //扫描第3行中的第三列时候:w=len("unaligned"),因为len("aligned") 2 | 3 | 4 | John 5 | Doe 6 | 7 | 42 8 | false 9 | Hanga Roa 10 | Easter Island 11 | 12 | -------------------------------------------------------------------------------- /io_pro/test/test01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main111() { 8 | x := make([]int, 1, 10) 9 | 10 | var a []int 11 | for i := 0; i < 10; i++ { 12 | 13 | a = append(x, i) 14 | fmt.Printf("%p---%p---%v----%v---%v === %p---%p---%v----%v---%v\n", a, &a[0], len(a), cap(a), a, x, &x[0], len(x), cap(x), x) 15 | } 16 | 17 | fmt.Println("--------------------------------------------------") 18 | fmt.Printf("%p---%p---%v----%v---%v === %p---%p---%v----%v---%v\n", a, &a[0], len(a), cap(a), a, x, &x[0], len(x), cap(x), x) 19 | fmt.Println("a:", a) 20 | fmt.Println("x:", x) 21 | fmt.Println("sdsdsd") 22 | 23 | } 24 | -------------------------------------------------------------------------------- /io_pro/test/test02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import ( 4 | // "fmt" 5 | // "io/ioutil" 6 | // "strings" 7 | // ) 8 | 9 | // func main() { 10 | // r := strings.NewReader("Hello, Reader!") 11 | 12 | // bytes, e := ioutil.ReadAll(r) 13 | // if e != nil { 14 | // fmt.Println(e) 15 | // } 16 | // fmt.Println(bytes) 17 | // fmt.Println(len(bytes), cap(bytes)) 18 | 19 | // bytes111, e111 := ioutil.ReadAll(r) 20 | // if e111 != nil { 21 | // fmt.Println(e111) 22 | // } 23 | // fmt.Println(bytes111) 24 | // fmt.Println(len(bytes111), cap(bytes111)) 25 | 26 | // bytes222, e222 := ioutil.ReadAll(r) //只能读取一次,多次调用一律不再重新读 27 | // if e222 != nil { 28 | // fmt.Println(e222) 29 | // } 30 | // fmt.Println(bytes222) 31 | // fmt.Println(len(bytes222), cap(bytes222)) 32 | 33 | // //b := make([]byte, 8) 34 | // //for { 35 | // // n, err := r.Read(b) 36 | // // fmt.Printf("n = %v err = %v b = %v\n", n, err, b) 37 | // // fmt.Printf("b[:n] = %q\n", b[:n]) 38 | // // if err == io.EOF { 39 | // // break 40 | // // } 41 | // //} 42 | // } 43 | -------------------------------------------------------------------------------- /io_pro/test/test03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import ( 4 | // "fmt" 5 | // ) 6 | 7 | // func main() { 8 | // var a = ^uint(0) 9 | 10 | // fmt.Println(a) 11 | // } 12 | -------------------------------------------------------------------------------- /io_pro/test/test04.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import ( 4 | // "encoding/json" 5 | // "fmt" 6 | // ) 7 | 8 | // func main() { 9 | // json1 := `[{"aa":"astr1"},{"aa":"bstr1"}]` 10 | // var j1 []interface{} 11 | // json.Unmarshal([]byte(json1), &j1) 12 | 13 | // fmt.Println(j1) 14 | // // vv := j1[0] //现在编译器认为他是interface {}类型而不是map类型,所以不能使用map的键来寻找相应的值,总之不能调用map的任何方法 15 | // a11 := j1[0] 16 | // vv, ok := a11.(map[string]interface{}) //为了使interface {}类型缩小范围,我们使用断言来转换类型为map,如果出错的话,那么我们将断言失败 17 | // fmt.Println(ok) 18 | // fmt.Println("==", vv["aa"]) 19 | // fmt.Println("----------1---------") 20 | 21 | // vvv111, ok111 := vv["aa"].(string) //因为上面的断言已经使得interface {}类型转成了map类型,所以我们这时候可以使用map["aa"]来取值, 22 | // // 但是注意我们上面断言的是map[string]interface{}类型(不能断言map[string]string类型,每次只能断言一个数据结构的类型) ,但是我们 23 | // // 还没断言map里面的interface{}类型,因此我们这时候有需要再来一次对map的键值中的值的断言 24 | // fmt.Println(ok111) 25 | // fmt.Printf("%T\n", vvv111) 26 | // fmt.Println("----------2---------") 27 | 28 | // //以下是原型,上面是我的探究 29 | // // for k, v := range j1 { 30 | // // fmt.Println(k, reflect.TypeOf(v).String()) 31 | 32 | // // if v2, ok := v.(map[string]string); ok { 33 | // // println("string断言成功") 34 | // // println(v2["aa"]) 35 | // // } else if v2, ok := v.(map[string]interface{}); ok { 36 | // // fmt.Println("键值为interface:") 37 | // // fmt.Println(v2["aa"]) 38 | // // } else { 39 | // // fmt.Println("失败:") 40 | // // } 41 | // // } 42 | 43 | // //------------------------------------------------ 44 | // // a := 8 45 | // // if a > 6 { 46 | // // fmt.Println("大于6") 47 | // // } else if a > 7 {//else if表示上面的条件成功的话则不再执行其他的if或者else 48 | // // fmt.Println("大于7") 49 | // // } else { 50 | // // fmt.Println("小于等于6") 51 | // // } 52 | // } 53 | -------------------------------------------------------------------------------- /io_pro/test/test05.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import "fmt" 4 | 5 | // func check_value(x interface{}) { 6 | // // if _, ok := x.([]interface{}); ok {//这是错误的!interface{}单体怎么能断言成功一个[]interface{}的集体呢? 7 | // if _, ok := x.([]int); ok { 8 | // fmt.Println("arg is slice") 9 | // } else { 10 | // fmt.Println("arg is not slice") 11 | // } 12 | // } 13 | 14 | // func main() { 15 | // var x interface{} 16 | // x = []int{1, 2} 17 | // check_value(x) 18 | // } 19 | -------------------------------------------------------------------------------- /io_pro/test/test06.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import "fmt" 4 | 5 | // type Tester interface { 6 | // getName() string 7 | // } 8 | // type Tester2 interface { 9 | // printName() 10 | // } 11 | 12 | // //===Person类型==== 13 | // type Person struct { 14 | // name string 15 | // } 16 | 17 | // func (p Person) getName() string { 18 | // return p.name 19 | // } 20 | // func (p Person) printName() { 21 | // fmt.Println(p.name) 22 | // } 23 | 24 | // //============ 25 | // func main() { 26 | // var t Tester 27 | // t = Person{"xiaohua"} 28 | // check(t) 29 | // } 30 | // func check(t Tester) { 31 | // //第一种情况 32 | // if f, ok1 := t.(Person); ok1 { 33 | // fmt.Println("1111111111111111111") 34 | // fmt.Printf("%T\n%s\n", f, f.getName()) 35 | // } 36 | // //第二种情况 37 | // if t, ok2 := t.(Tester2); ok2 { //重用变量名t(无需重新声明) 38 | // fmt.Println("222222222222222222") 39 | // check2(t) //若类型断言为true,则新的t被转型为Tester2接口类型,但其动态类型和动态值不变 40 | // } 41 | // } 42 | // func check2(t Tester2) { 43 | // t.printName() 44 | // } 45 | -------------------------------------------------------------------------------- /io_pro/test/test07.go: -------------------------------------------------------------------------------- 1 | package main 2 | // 3 | //import ( 4 | // "fmt" 5 | // "github.com/axgle/mahonia" 6 | //) 7 | // 8 | ////src为要转换的字符串,srcCode为待转换的编码格式,targetCode为要转换的编码格式 9 | //func ConvertToByte(src string, srcCode string, targetCode string) []byte { 10 | // srcCoder := mahonia.NewDecoder(srcCode) 11 | // srcResult := srcCoder.ConvertString(src) 12 | // tagCoder := mahonia.NewDecoder(targetCode) 13 | // _, cdata, _ := tagCoder.Translate([]byte(srcResult), true) 14 | // return cdata 15 | //} 16 | // 17 | //func main() { 18 | // //r := '世' 19 | // 20 | // ls := []byte{34, 11, 8, 146, 147, 214, 236, 5, 16, 152, 148, 189, 4, 42, 0, 50, 10, 8, 12, 18, 6, 49, 50, 51, 52, 53, 54} 21 | // //对string由gbk转码为utf8 22 | // fmt.Println("******************") 23 | // response := ConvertToByte(string(ls), "gbk", "utf8") 24 | // fmt.Println(response) 25 | // fmt.Println(string(response)) 26 | //} 27 | -------------------------------------------------------------------------------- /io_pro/test/test08.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "golang.org/x/text/encoding/simplifiedchinese" 7 | "io/ioutil" 8 | "log" 9 | ) 10 | 11 | func main34343() { 12 | //编码unicode成为GB18030码 13 | enc := simplifiedchinese.GB18030.NewEncoder() //申明一个编码器(相对于unicode来说确实是编码) 14 | encBuf := bytes.NewBuffer(make([]byte, 0)) //申明一个encBuf来存储转换后的原生字节 15 | // 序列(无任何编码的遵循unicode协议的字节序列,他是unicode值,但是unicode不是一种编码,而是一种规范和协议) 16 | 17 | // Writer包装另一个Writer对其UTF-8输出进行编码。 18 | //只要使用了返回的Writer,编码器就不能用于任何其他操作。 19 | writ := enc.Writer(encBuf) //申明一个对接encBuf缓存的写入器,这个写入器是由编码器生成的, 20 | // 因此它具有编码的功能, 在这儿是把GB18030转成原生字节的转码器 21 | writ.Write([]byte{34, 11, 8, 146, 147, 214, 236, 5, 16, 152, 148, 189, 4, 42, 0, 50, 10, 8, 12, 18, 6, 49, 50, 51, 52, 53, 54}) //把一个原生字节序列或者叫unicode字符串经过 22 | // 写入器(内含GB18030编码器)写入到encBuf缓存容器中去,此时缓存容器里面存的是GB18030编码后的 23 | //字节序列 24 | fmt.Println(encBuf) //这个是buf类型 25 | fmt.Println(encBuf.Bytes()) //转成字节类型才能打印 26 | fmt.Println("编码后的内容", encBuf.String()) //String()是对缓存容器里面的原生字节序列进行go内置的utf8解码 27 | //并且打印出utf8字符串,但是由于他是GB18030值,而go却采用的是utf8的解码器去解码,所以不会成功打印的! 28 | //-------------------------------------------------------------- 29 | 30 | //解码GB18030成为unicode之后再编码成为utf8 31 | dec := simplifiedchinese.GB18030.NewDecoder() //声明一个解码器(相对于unicode来说确实是解码) 32 | read := dec.Reader(encBuf) //跟上面一样写入缓存需要一个写入器,读出缓存也需要一个读取器来读取缓存容器里面的内容 33 | decBuf, err := ioutil.ReadAll(read) //上面说到编码器写入到缓存容器中,这时候解码器需要从 34 | //缓存容器中读取GB18030字节序列出来,并且返回新的字节切片 35 | if err != nil { 36 | log.Println(err) 37 | } 38 | fmt.Println(decBuf) //[232 191 153 230 174 181 229 134 133 229 174 185 230 152 175 232 166 129 232 162 39 | // 171 231 188 150 231 160 129 232 189 172 230 141 162] 40 | fmt.Println("解码后的内容", string(decBuf)) //跟上面string函数一样 41 | 42 | //缩写方式1如下: 43 | //reader := simplifiedchinese.GB18030.NewDecoder().Reader(resp.Body) 44 | //buf, err := ioutil.ReadAll(reader) 45 | 46 | //中级缩写方式2如下: 47 | ////utf8转gbk 48 | //src:="编码转换内容内容" 49 | ////src:=[]byte{78, 45, 86, 253, 78, 186}//unicode码值 50 | //fmt.Println(src) 51 | //fmt.Println([]byte(src))//[231 188 150 231 160 129 232 189 172 230 141 52 | //// 162 229 134 133 229 174 185 229 134 133 229 174 185] 53 | ////每3个字节为一个中文字,这是典型的utf8编码后的字节序列 54 | // 55 | ////将utf8的字节序列转化为gbk的字节序列 56 | //data, _ := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(src)), simplifiedchinese.GBK.NewEncoder())) 57 | ////[177 224 194 235 215 170 187 187 196 218 200 221 196 218 200 221] 58 | ////每2个字节为一个中文字 59 | //fmt.Println(data) //byte 60 | ////因为他采用的是utf8来解码序列了,很明显这是gbk才能解码的序列 61 | //fmt.Println(string(data)) //打印为乱码:����ת���������� 62 | } 63 | -------------------------------------------------------------------------------- /io_pro/test/test09.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | ) 8 | 9 | func main23468() { 10 | b := bytes.NewBuffer(make([]byte, 0)) 11 | bw := bufio.NewWriter(b) 12 | bw.WriteString("123") 13 | fmt.Println("--",b) 14 | c := bytes.NewBuffer(make([]byte, 0)) 15 | bw.Reset(c) 16 | bw.WriteString("456") 17 | bw.Flush() 18 | fmt.Println("--",b) 19 | fmt.Println(c) 20 | //输出: 21 | //-- 22 | //-- 23 | //456 24 | } -------------------------------------------------------------------------------- /io_pro/test/test10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main1135(){ 8 | x := "hello" 9 | for _, y := range x { 10 | x=fmt.Sprintf("%s %s",x,string(y))//连接多个字符串不会加配内存 11 | } 12 | fmt.Println(x) 13 | } -------------------------------------------------------------------------------- /io_pro/test/test11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main0897(){ 8 | x := "hello" 9 | y:=&x 10 | 11 | fmt.Println(x) 12 | fmt.Println(y) 13 | fmt.Printf("%p---%v\n",&x,x) 14 | fmt.Printf("%p---%v\n",y,*y) 15 | 16 | *y="HELLO" 17 | fmt.Printf("%p---%v\n",&x,x) 18 | fmt.Printf("%p---%v\n",y,*y) 19 | fmt.Println(*y) 20 | 21 | 22 | z:=x[1:2] 23 | fmt.Printf("%p---%v\n",&z,z) 24 | q:=&z 25 | fmt.Printf("%p---%v\n",q,*q) 26 | *q="e" 27 | fmt.Printf("%p---%v\n",&z,z) 28 | fmt.Printf("%p---%v\n",q,*q) 29 | 30 | fmt.Printf("%p---%v\n",&x,x) 31 | fmt.Printf("%p---%v\n",y,*y) 32 | 33 | //输出如下: 34 | // hello 35 | // 0xc0000301f0 36 | // 0xc0000301f0---hello 37 | // 0xc0000301f0---hello 38 | // 0xc0000301f0---HELLO 39 | // 0xc0000301f0---HELLO 40 | // HELLO 41 | // 0xc000030260---E 42 | // 0xc000030260---E 43 | // 0xc000030260---e 44 | // 0xc000030260---e 45 | // 0xc0000301f0---HELLO 46 | // 0xc0000301f0---HELLO 47 | 48 | //从上面可以知道确实不可以更改字符串的单个元素 49 | } -------------------------------------------------------------------------------- /io_pro/test/test12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main6893(){ 9 | t661:=time.Date(2018,12,11,13,05,06,99,time.Local) 10 | fmt.Println("===========序列化后的结果=============") 11 | 12 | // MarshalBinary实现encoding.BinaryMarshaler接口。 13 | byte1, _ := t661.MarshalBinary() 14 | fmt.Println(byte1) 15 | fmt.Println(string(byte1)) 16 | byte2, _ := t661.MarshalJSON() 17 | fmt.Println(byte2) 18 | fmt.Println(string(byte2)) 19 | byte3, _ := t661.MarshalText() 20 | fmt.Println(byte3) 21 | fmt.Println(string(byte3)) 22 | //输出如下: 23 | // ===========序列化后的结果============= 24 | // [1 0 0 0 14 211 161 60 130 0 0 0 99 1 224] 25 | //  ӡ<� c� 26 | // [34 50 48 49 56 45 49 50 45 49 49 84 49 51 58 48 53 58 48 54 46 48 48 48 48 48 48 48 57 57 43 48 56 58 48 48 34] 27 | // "2018-12-11T13:05:06.000000099+08:00" 28 | // [50 48 49 56 45 49 50 45 49 49 84 49 51 58 48 53 58 48 54 46 48 48 48 48 48 48 48 57 57 43 48 56 58 48 48] 29 | // 2018-12-11T13:05:06.000000099+08:00 30 | fmt.Println("===========================") 31 | 32 | var Dt=time.Date(2017,12,11,13,05,06,99,time.Local)//仅仅年份不同 33 | //var t time.Time//在有数据的time类实例里面序列化也是可以的 34 | fmt.Println(Dt.UnmarshalBinary(byte1))//,二进制原始字节 35 | fmt.Println(Dt.UnmarshalJSON(byte2))//,加引号的utf8编码自己,就是json了 36 | fmt.Println(Dt.UnmarshalText(byte3))//,utf8编码字节 37 | fmt.Println(byte1) 38 | fmt.Println(string(byte1)) 39 | fmt.Println(byte2) 40 | fmt.Println(string(byte2)) 41 | fmt.Println(byte3) 42 | fmt.Println(string(byte3)) 43 | fmt.Println("===========反序列化后的结果=============") 44 | fmt.Println(Dt) 45 | fmt.Println(Dt.String()) 46 | //输出如下: 47 | // =========================== 48 | // 49 | // 50 | // 51 | // [1 0 0 0 14 211 161 60 130 0 0 0 99 1 224] 52 | //  ӡ<� c� 53 | // [34 50 48 49 56 45 49 50 45 49 49 84 49 51 58 48 53 58 48 54 46 48 48 48 48 48 48 48 57 57 43 48 56 58 48 48 34] 54 | // "2018-12-11T13:05:06.000000099+08:00" 55 | // [50 48 49 56 45 49 50 45 49 49 84 49 51 58 48 53 58 48 54 46 48 48 48 48 48 48 48 57 57 43 48 56 58 48 48] 56 | // 2018-12-11T13:05:06.000000099+08:00 57 | // ===========反序列化后的结果============= 58 | // 2018-12-11 13:05:06.000000099 +0800 CST 59 | // 2018-12-11 13:05:06.000000099 +0800 CST 60 | } -------------------------------------------------------------------------------- /io_pro/test/test13.go: -------------------------------------------------------------------------------- 1 | /* ASN.1 2 | */ 3 | 4 | package main 5 | 6 | import ( 7 | "encoding/asn1" 8 | "fmt" 9 | "os" 10 | ) 11 | type person struct { 12 | Name string 13 | Age int 14 | Isfat bool 15 | } 16 | 17 | 18 | func main23845() { 19 | P:=person{ 20 | Name: "anko", 21 | Age: 18, 22 | Isfat: false, 23 | } 24 | mdata, err := asn1.Marshal(P) 25 | checkError(err) 26 | fmt.Println(mdata,"字符串为:",string(mdata)) 27 | 28 | var n person 29 | ls, err1 := asn1.Unmarshal(mdata, &n) 30 | checkError(err1) 31 | fmt.Println(ls) 32 | fmt.Println("After marshal/unmarshal: ", n) 33 | 34 | fmt.Println("-------------------------------------") 35 | 36 | } 37 | 38 | func checkError(err error) { 39 | if err != nil { 40 | fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) 41 | os.Exit(1) 42 | } 43 | } -------------------------------------------------------------------------------- /io_pro/test/test14.go: -------------------------------------------------------------------------------- 1 | //例子1------------------------------------------------------------- 2 | package main 3 | 4 | import "fmt" 5 | 6 | func demo(recoverShallowerPanicAtFirst bool) { 7 | fmt.Println("====================") 8 | defer func() { 9 | if !recoverShallowerPanicAtFirst{ 10 | // 恢复恐慌1 11 | defer fmt.Println("恐慌", recover(), "被恢复了") 12 | } 13 | defer func() { 14 | // 恢复恐慌2 15 | fmt.Println("恐慌", recover(), "被恢复了") 16 | }() 17 | if recoverShallowerPanicAtFirst { 18 | // 恢复恐慌1 19 | defer fmt.Println("恐慌", recover(), "被恢复了") 20 | } 21 | defer fmt.Println("现在有两个恐慌共存") 22 | panic(2) 23 | }() 24 | panic(1) 25 | } 26 | 27 | func main34876() { 28 | demo(true) 29 | demo(false) 30 | } 31 | 32 | 33 | 34 | //例子2------------------------------------------------------------- 35 | //package main 36 | // 37 | //import "fmt" 38 | // 39 | //func demo() { 40 | // defer func() { 41 | // // recover panic 1 42 | // defer fmt.Println(" (done).") 43 | // defer recover() 44 | // defer fmt.Println("To recover panic 1 ...") 45 | // 46 | // defer func() { 47 | // // recover panic 2 48 | // fmt.Println("panic", recover(), "is recovered") 49 | // }() 50 | // 51 | // defer fmt.Println("now, two active panics coexist") 52 | // panic(2) 53 | // }() 54 | // panic(1) 55 | //} 56 | // 57 | //func main() { 58 | // demo() 59 | //} 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /io_pro/test/test15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func producer8(out chan int) { 9 | go generate(out) 10 | } 11 | 12 | func generate(out chan int) { 13 | fmt.Println("hello,i am producer") 14 | for i := 0; i < 10; i++ { 15 | fmt.Printf("producer one %v \n", i+1) 16 | out <- i 17 | 18 | } 19 | //close(out) 20 | } 21 | 22 | func consumer8(in <- chan int) { 23 | Loop: 24 | for { 25 | select { 26 | case <-time.After(2e9): 27 | fmt.Printf("time out\n") 28 | break Loop 29 | case v1, ok := <-in: 30 | if ok { 31 | fmt.Printf("recive one %v %v \n", v1, ok) 32 | time.Sleep(3e9) 33 | } 34 | if !ok { 35 | fmt.Println("chan无知可取。。。。") 36 | 37 | } 38 | 39 | } 40 | } 41 | } 42 | 43 | func testCurrencyPatternsGenerators() { 44 | 45 | out := make(chan int) 46 | producer8(out) 47 | go consumer8(out) 48 | //for i:=0;i<100 ;i++ { 49 | // fmt.Println(i) 50 | //} 51 | time.Sleep(30e9) 52 | fmt.Println("程序结束") 53 | } 54 | func main4592() { 55 | 56 | testCurrencyPatternsGenerators() 57 | } 58 | -------------------------------------------------------------------------------- /io_pro/test/test16.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "bytes" 4 | "encoding/gob" 5 | "fmt" 6 | "log" 7 | "math" 8 | ) 9 | //接口 10 | type Pythagoras interface { 11 | Hypotenuse() float64 12 | } 13 | 14 | //实现接口的结构体 15 | type Point struct { 16 | X, Y int 17 | } 18 | func (p Point) Hypotenuse() float64 {//求 19 | return math.Hypot(float64(p.X), float64(p.Y)) 20 | } 21 | 22 | // interfaceEncode编码器函数 将接口值编码到编码器中。 23 | func interfaceEncode(enc *gob.Encoder, p Pythagoras) { 24 | //除非已注册具体类型(或者说结构体),否则编码将失败。 我们在调用函数Example_interface()中注册了它。 25 | //将指针传递给接口,以便Encode看到(并因此发送)接口类型的值。 如果我们直接传递p,它将看到具体类型。 26 | //有关背景,请参见博客文章“反射定律(The Laws of Reflection)”。 27 | err := enc.Encode(&p)//必须是指针 28 | if err != nil { 29 | log.Fatal("encode:", err) 30 | } 31 | } 32 | // interfaceDecode解码器函数 解码流中的下一个接口值并返回它。 33 | func interfaceDecode(dec *gob.Decoder) Pythagoras { 34 | //除非导线上的具体类型(或者说结构体)已注册,否则解码将失败。 我们在调用函数Example_interface()中注册了它。 35 | var p Pythagoras 36 | err := dec.Decode(&p)//必须是指针,指明解码成什么数据结构 37 | if err != nil { 38 | log.Fatal("decode:", err) 39 | } 40 | fmt.Printf("解码后的数据类型为:%T\n",p) 41 | fmt.Printf("解码后的数据为:%#v\n",p) 42 | return p//返回解码后的数据,这个数据不是接口,是接口的实现struct---Point类实例 43 | } 44 | 45 | 46 | //此示例说明如何编码接口值。 与常规类型的主要区别是注册实现接口的具体类型。 47 | func Example_interface() { 48 | var network bytes.Buffer //网络的替身。装载编码后的数据的容器 49 | //我们必须注册编码器和解码器的具体类型(通常与编码器在不同的机器上)。 在每一端,这告诉引擎正在发送实现该接口的具体类型。 50 | gob.Register(Point{})//指明要编码哪个结构体 51 | //创建一个编码器并发送一些值。 52 | enc := gob.NewEncoder(&network)//编码到哪里去存着 53 | for i := 1; i <= 3; i++ { 54 | interfaceEncode(enc, Point{3 * i, 4 * i})//在这里实例化并且将实例传递过去 55 | } 56 | fmt.Println("编码后的数据为:",network) 57 | 58 | //创建一个解码器并接收一些值。 59 | dec := gob.NewDecoder(&network)//指定解码什么,指明编码什么数据结构 60 | for i := 1; i <= 3; i++ { 61 | result := interfaceDecode(dec) 62 | fmt.Printf("%T---%v\n",result,result.Hypotenuse())//调用struct的方法 63 | } 64 | 65 | //输出: 66 | // 编码后的数据为: {[44 16 0 10 109 97 105 110 46 80 111 105 110 116 255 129 3 1 1 5 80 111 67 | // 105 110 116 1 255 130 0 1 2 1 1 88 1 4 0 1 1 89 1 4 0 0 0 8 255 130 5 1 68 | // 6 1 8 0 21 16 0 10 109 97 105 110 46 80 111 105 110 116 255 130 5 1 12 1 69 | // 16 0 21 16 0 10 109 97 105 110 46 80 111 105 110 116 255 130 5 1 18 1 24 0] 0 0} 70 | // 解码后的数据类型为:main.Point 71 | // 解码后的数据为:main.Point{X:3, Y:4} 72 | // main.Point---5 73 | // 解码后的数据类型为:main.Point 74 | // 解码后的数据为:main.Point{X:6, Y:8} 75 | // main.Point---10 76 | // 解码后的数据类型为:main.Point 77 | // 解码后的数据为:main.Point{X:9, Y:12} 78 | // main.Point---15 79 | } 80 | 81 | 82 | func main232546() { 83 | Example_interface() 84 | } -------------------------------------------------------------------------------- /io_pro/test/test17.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func f() { 6 | f() 7 | } 8 | 9 | func main87890() { 10 | defer func() { 11 | fmt.Println("出现异常===========================") 12 | recover() // 对于栈溢出,无法防止程序崩溃,也无法捕获异常或者恢复它 13 | }() 14 | f() 15 | 16 | } 17 | -------------------------------------------------------------------------------- /io_pro/test/test18.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode/utf8" 6 | ) 7 | 8 | func main2356() { 9 | str:="\u8bf7\u6c42\u7684\u6570\u636e"//unicode码值的16进制表示 10 | fmt.Println(str) 11 | fmt.Println(utf8.ValidString(str)) 12 | } 13 | -------------------------------------------------------------------------------- /io_pro/test/test19.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | func main346() { 10 | testInput := "

Foo

\n\n

Bar\n" 11 | d := xml.NewDecoder(strings.NewReader(testInput)) 12 | T1, err1111 := d.Token() 13 | check_EncDec_err(err1111) 14 | T2, err2222 := d.Token() 15 | check_EncDec_err(err2222) 16 | 17 | T3, err333 := d.Token() 18 | check_EncDec_err(err333) 19 | 20 | T4, err444 := d.Token() 21 | check_EncDec_err(err444) 22 | 23 | fmt.Println(T1) 24 | fmt.Println(T2) 25 | fmt.Println(T3) 26 | fmt.Println(T4) 27 | } 28 | 29 | func check_EncDec_err(err error) { 30 | if err != nil{ 31 | fmt.Println("----",err) 32 | } 33 | } -------------------------------------------------------------------------------- /io_pro/test/test20.go: -------------------------------------------------------------------------------- 1 | package main -------------------------------------------------------------------------------- /io_pro/test/test21.go: -------------------------------------------------------------------------------- 1 | // xml.go 2 | package main 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "strings" 7 | ) 8 | var t, token xml.Token//申明Token,像这样2个一起申明,即使其中一个不使用也是可以的! 9 | var err error 10 | func main34343345() { 11 | input := "LauraLynn" 12 | inputReader := strings.NewReader(input) 13 | p := xml.NewDecoder(inputReader)//创建解析input字符串的解码器 14 | for t, err = p.Token(); err == nil; t, err = p.Token() {//p.Token()获取解码器的Token,遍历结束后err == EOF而不是nil 15 | switch token := t.(type) { 16 | case xml.StartElement://如果是开始标签 17 | name := token.Name.Local//获取标签的名字 18 | fmt.Printf("Token name: %s\n", name) 19 | for _, attr := range token.Attr {//获取标签的属性,这个属性包含名字和值 20 | attrName := attr.Name.Local 21 | attrValue := attr.Value//分别取得属性的名字和值 22 | fmt.Printf("An attribute is: %s %s\n", attrName, attrValue) 23 | // ... 24 | } 25 | case xml.EndElement://如果是结束标签 26 | fmt.Println("End of token") 27 | case xml.CharData://如果是文本字符 28 | content := string([]byte(token)) 29 | fmt.Printf("This is the content: %v\n", content) 30 | // ... 31 | default://如果什么都不是的话,什么都不做 32 | // ... 33 | } 34 | } 35 | 36 | //输出: 37 | // Token name: Person 38 | // Token name: FirstName 39 | // This is the content: Laura 40 | // End of token 41 | // Token name: LastName 42 | // This is the content: Lynn 43 | // End of token 44 | // End of token 45 | } -------------------------------------------------------------------------------- /io_pro/test/test22.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var f1 = func(i int) { 6 | fmt.Println("X") 7 | } 8 | 9 | func main234526() { 10 | //f1(0) 11 | //var f1 func(i int) 12 | f1:=func (i int) { 13 | fmt.Println(i) 14 | if i>0{ 15 | f1(i-1) 16 | } 17 | } 18 | f1(10) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /io_pro/test/test23.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main3465() { 9 | f := `D:\\con`//不能使用con,是bug 10 | file, err := os.Open(f) 11 | 12 | if err != nil { 13 | fmt.Println("打开文件发生了错误,错误信息为:", err) 14 | } 15 | fmt.Printf("file的类型是:%T,值是:%v\n", file, file) 16 | 17 | dst_byte := make([]byte, 5) 18 | n, err := file.Read(dst_byte) 19 | if err != nil { 20 | fmt.Println("读取发生了错误,错误信息为:", err) 21 | } 22 | fmt.Println("读取到的字节个数为:", n) 23 | fmt.Println("读取到的字节的装载切片为:", dst_byte) 24 | } 25 | -------------------------------------------------------------------------------- /io_pro/test/test24.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main346289() { 9 | file, e := os.Open("test/config.xml") 10 | check_EncDec_err(e) 11 | info, e := file.Stat() 12 | check_EncDec_err(e) 13 | 14 | dst_byte := make([]byte, info.Size()) 15 | n, e := file.Read(dst_byte) 16 | check_EncDec_err(e) 17 | 18 | fmt.Println("读取到的文件的字节数是:", n) 19 | fmt.Println("读取到的文件字节是:", dst_byte) 20 | fmt.Printf("读取到的文件字符串是:\n%v\n", string(dst_byte)) 21 | 22 | ret, e := file.Seek(0, 0) 23 | check_EncDec_err(e) 24 | 25 | fmt.Println("将文件读写指针移动到:", ret) 26 | 27 | dst_byte1 := make([]byte, info.Size()) 28 | n1, e := file.Read(dst_byte1) 29 | check_EncDec_err(e) 30 | 31 | fmt.Println("读取到的文件的字节数是:", n1) 32 | fmt.Println("读取到的文件字节是:", dst_byte) 33 | fmt.Printf("读取到的文件字符串是:\n%v\n", string(dst_byte)) 34 | } 35 | -------------------------------------------------------------------------------- /io_pro/test/test25.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io_pro/test/testdir" 6 | ) 7 | 8 | func main3467() { 9 | fmt.Println(testdir.Sum1(4,5)) 10 | } -------------------------------------------------------------------------------- /io_pro/test/test26.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | type inter interface { 4 | 5 | } 6 | type Person struct { 7 | Name string 8 | Age int 9 | } 10 | //func (*Person)Say() Person { 11 | // fmt.Println("某人在say....") 12 | // return Person{ 13 | // Name: "anko111", 14 | // Age: 22, 15 | // } 16 | //} 17 | 18 | func (*Person)Say() { 19 | fmt.Println("某人在say....") 20 | } 21 | 22 | type money float64 23 | 24 | func (n *money)Discrib() string { 25 | return "money is xxxx" 26 | } 27 | 28 | func main346763() { 29 | var m money=16 30 | fmt.Println(m.Discrib()) 31 | 32 | var f float64 =18.8 33 | var f2m= money(f) 34 | 35 | fmt.Println(f2m) 36 | fmt.Println(&f2m) 37 | //fmt.Println(&(money(f)))//虽然money(f)确实是一个实例,但是可能是go的一个bug,也可能是go不允许这样写,不过前者的原因大些 38 | fmt.Println(&(struct {}{}))//struct {}{}是一个实例 39 | 40 | P:=Person{ 41 | Name: "anko", 42 | Age: 20, 43 | } 44 | //&P.Say()//这样代表取say()返回值的指针。报错,即使我在Say()中返回一个Person{ Name: "anko111", Age: 22, }对象也会报错,go的词法识别并没有那么智能 45 | (&P).Say()//这样代表取P的指针 46 | //fmt.Println(&Person)//Person是类型名,不允许对其取指针 47 | // 48 | //fmt.Println(&(inter{}))//不允许对接口进行取指针 49 | } 50 | -------------------------------------------------------------------------------- /io_pro/test/test27.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type ls []string 6 | 7 | type ls_chid ls 8 | 9 | func (*ls_chid) name() { 10 | fmt.Println("name....") 11 | } 12 | 13 | func main236237() { 14 | 15 | ls_chid_obj := ls_chid{"abc", "你好啊", "edf"} 16 | 17 | for _, v := range ls_chid_obj { 18 | fmt.Println(v) 19 | } 20 | ls_chid_obj.name() 21 | fmt.Printf("%T---", ls_chid_obj) 22 | } 23 | -------------------------------------------------------------------------------- /io_pro/test/test28.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type T_ls interface { 8 | Name() *P 9 | } 10 | 11 | type P struct { 12 | } 13 | 14 | func (*P) Name() *P { 15 | fmt.Println("name....") 16 | return nil 17 | } 18 | 19 | var p P 20 | 21 | func ret_ls() T_ls { 22 | fmt.Println("ret_ls....") 23 | return p.Name() 24 | } 25 | 26 | func main3472336() { 27 | ls := ret_ls() 28 | 29 | fmt.Printf("类型:%T,值:%v\n", ls, ls) 30 | 31 | 32 | if ls != (*P)(nil) { 33 | fmt.Println("不是nil") 34 | } 35 | if ls == (*P)(nil) { 36 | fmt.Println("是nil") 37 | } 38 | 39 | // var str []byte 40 | // str=nil 41 | 42 | // if str != nil { 43 | // fmt.Println("str不是nil 000") 44 | // } 45 | 46 | // if str == nil { 47 | // fmt.Println("str是nil 00011") 48 | // } 49 | 50 | // if reflect.TypeOf(str) != nil { 51 | // fmt.Println("str不是nil 111") 52 | // } 53 | // if reflect.ValueOf(str).IsNil(){ 54 | // fmt.Println("str是nil 222") 55 | // } 56 | 57 | // if reflect.TypeOf(nil) == nil { 58 | // fmt.Println("是nil") 59 | // } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /io_pro/test/test29.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type jiekou interface { 8 | meth() 9 | } 10 | 11 | type zifu string 12 | 13 | //对于go,我们不说zifu这个类实现了接口jiekou,我们说zifu的实例zifu实现了这个接口jiekou,如果下面是*zifu的话,我们就说 14 | //zifu的*zifu实例实现了接口jiekou,但是不能说zifu的实例zifu实现了接口!他们是完全不同的东西!切记!这也是导致了下面将 15 | //实例zifu(a)还是实例*zifu(&a)赋给接口j! 16 | func (t zifu) meth() { 17 | fmt.Println("meth start.....") 18 | fmt.Printf("p(t.meth)===%p\n", (&t).meth) 19 | fmt.Printf("p(t)====%p\n", &t) 20 | fmt.Printf("%T调用方法成功!\n", t) 21 | fmt.Println("meth end.....") 22 | } 23 | 24 | func main88769() { 25 | a := zifu("a test") 26 | 27 | fmt.Println("测试zifu的类型:") 28 | a.meth() 29 | (&a).meth() 30 | 31 | fmt.Println() 32 | fmt.Println("测试接口:") 33 | 34 | // var j &jiekou//不可以对接口进行取值,因为此时的接口类型为nil,不可以对类 35 | // 型nil进行取内存,因为类型nil代表的是没申请内存,既然不存在内存,那就更加不存在去内存地址的可能了! 36 | // 所以不允许对其取指针!同理我们也不能写&nil! 37 | var j jiekou 38 | fmt.Println("j赋值之前的地址:", &j) 39 | fmt.Printf("j赋值之前的类型T(j)---%T\n", j) 40 | 41 | j = a 42 | fmt.Println("j赋值之后的地址:", &j) 43 | fmt.Printf("j赋值之后的类型T(j)---%T\n", j) 44 | fmt.Printf("p(j.meth)===%p\n", j.meth) 45 | fmt.Println("--------") 46 | j.meth() 47 | 48 | } 49 | -------------------------------------------------------------------------------- /io_pro/test/test30.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "os/exec" 8 | "path" 9 | "path/filepath" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | const ( 15 | LOGDIR = "logs" 16 | LOGFILE = "oradev.log" 17 | ) 18 | 19 | //别人的代码,不用理会这个文件,也不要执行 20 | type LogStruct struct { 21 | LogDirFilePath string 22 | file *os.File 23 | } 24 | type LogInterface interface { 25 | InitLog() error 26 | CloseLog() 27 | Write() 28 | } 29 | 30 | //初始化日志系统接口 31 | func (l *LogStruct) InitLog() error { 32 | fmt.Printf("Start adlog system initialization...\n\n") 33 | 34 | // 检查日志文件是否存在, 35 | res, err := FileCreate(LOGDIR, LOGFILE) 36 | if err != nil { 37 | return err 38 | } 39 | if res != nil { 40 | l.LogDirFilePath = *res 41 | logFile, err := os.OpenFile(l.LogDirFilePath, os.O_WRONLY|os.O_APPEND, os.ModePerm) 42 | if err != nil { 43 | return fmt.Errorf("Log system initialization failed: %s\n", err) 44 | } 45 | l.file = logFile 46 | fmt.Printf("Log system initialization complete.\n\n") 47 | } 48 | return nil 49 | } 50 | func (l *LogStruct) Write(tp string, info interface{}) { 51 | fmt.Println("lfile: ", l.file) 52 | fmt.Println("path: ", l.LogDirFilePath) 53 | adlog := log.New(l.file, "", log.Ldate|log.Ltime) 54 | if tp == "INFO: " { 55 | adlog.Println(tp, info) 56 | } 57 | if tp == "WARNING: " { 58 | adlog.Println(tp, info) 59 | } 60 | if tp == "ERROR: " { 61 | adlog.Println(tp, info) 62 | } 63 | if tp == "FATAL: " { 64 | adlog.Println(tp, info) 65 | os.Exit(1) 66 | } 67 | } 68 | func INFO(info interface{}) error { 69 | l := &LogStruct{} 70 | l.Write("INFO: ", info) 71 | return fmt.Errorf("++++++++++++++++++++++++++++++++++++++++++++++++++") 72 | } 73 | func WARNING(info interface{}) { 74 | l := LogStruct{} 75 | l.Write("WARNING: ", info) 76 | } 77 | func ERROR(info interface{}) { 78 | l := LogStruct{} 79 | l.Write("ERROR: ", info) 80 | } 81 | func FATAL(info interface{}) { 82 | l := LogStruct{} 83 | l.Write("FATAL: ", info) 84 | } 85 | 86 | //关闭日志文件 87 | func (l *LogStruct) CloseLog() { 88 | if l.file != nil { 89 | l.file.Close() 90 | } else { 91 | fmt.Println("close log: ", l.file) 92 | } 93 | } 94 | 95 | //关闭日志文件 96 | func CLog() { 97 | l := LogStruct{} 98 | l.CloseLog() 99 | } 100 | 101 | // directory and file create 102 | func FileCreate(dir string, filename string) (*string, error) { 103 | var pfres string 104 | 105 | //homedir := GetHomeDirectory() 106 | homedir := `C:\Users\Administrator\Desktop\go_pro\src\io_pro\test` 107 | if homedir != "" { 108 | exist, err := PathExists(path.Join(homedir, dir)) 109 | if err != nil { 110 | return nil, fmt.Errorf("Get directory property information occurred Error: %v\n", err) 111 | } 112 | if exist { 113 | fmt.Printf("Check if directory exists - exists: %s\n\n", path.Join(homedir, dir)) 114 | } else { 115 | fmt.Printf("Check if directory exists - Non-exists: %s\n", path.Join(homedir, dir)) 116 | // 创建文件夹 117 | err := os.Mkdir(path.Join(homedir, dir), os.ModePerm) 118 | if err != nil { 119 | return nil, fmt.Errorf("directory created failed: %s\n\n", err) 120 | } else { 121 | fmt.Printf("directory created successfully: %s\n\n", path.Join(homedir, dir)) 122 | } 123 | } 124 | } else { 125 | return nil, fmt.Errorf("Program home directory acquisition failed\n\n") 126 | } 127 | if filename != "" { 128 | exist, err := PathExists(filepath.Join(path.Join(homedir, dir), filename)) 129 | if err != nil { 130 | return nil, fmt.Errorf("Get file property information occurred Error: %v\n", err) 131 | } 132 | if exist { 133 | fmt.Printf("Check if file exists - exists: %s\n", filepath.Join(path.Join(homedir, dir), filename)) 134 | pfres = filepath.Join(path.Join(homedir, dir), filename) 135 | return &pfres, nil 136 | } else { 137 | fmt.Printf("Check if file exists - Non-exists: %s\n\n", filepath.Join(path.Join(homedir, dir), filename)) 138 | _, err := os.OpenFile(filepath.Join(path.Join(homedir, dir), filename), os.O_EXCL|os.O_CREATE, os.ModePerm) 139 | if err != nil { 140 | return nil, fmt.Errorf("file creation failed: %s\n\n", err) 141 | } else { 142 | fmt.Printf("file created successfully: %s\n\n", filepath.Join(path.Join(homedir, dir), filename)) 143 | pfres = filepath.Join(path.Join(homedir, dir), filename) 144 | return &pfres, nil 145 | } 146 | } 147 | } else { 148 | return nil, fmt.Errorf("File name cannot be empty") 149 | } 150 | return nil, nil 151 | } 152 | 153 | //Get program home directory 154 | func GetHomeDirectory() (homedir string) { 155 | file, _ := exec.LookPath(os.Args[0]) 156 | ExecFilePath, _ := filepath.Abs(file) 157 | execfileslice := strings.Split(ExecFilePath, "/") 158 | HomeDirectory := execfileslice[:len(execfileslice)-2] 159 | for _, v := range HomeDirectory { 160 | if v != "" { 161 | homedir += `/` + v 162 | } 163 | } 164 | if homedir != "" { 165 | fmt.Printf("Program home directory initialized successfully: %s\n", homedir) 166 | return homedir 167 | } else { 168 | fmt.Printf("Program home directory initialized failed\n") 169 | } 170 | return "" 171 | } 172 | 173 | // 判断文件夹是否存在 174 | func PathExists(path string) (bool, error) { 175 | _, err := os.Stat(path) 176 | if err == nil { 177 | return true, nil 178 | } 179 | if os.IsNotExist(err) { 180 | return false, nil 181 | } 182 | return false, err 183 | } 184 | 185 | func main8938373() { 186 | l := LogStruct{} 187 | err := (&l).InitLog() 188 | if err != nil { 189 | fmt.Println(err) 190 | os.Exit(1) 191 | } 192 | 193 | r := INFO(time.Now().Format("2006-01-02 15:04:05")) 194 | fmt.Println("r:", r) 195 | 196 | } 197 | -------------------------------------------------------------------------------- /io_pro/test/test31.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "time" 7 | ) 8 | 9 | func main346787() { 10 | chan_int3 := make(chan int, 3) 11 | go func() { 12 | n:=0 13 | for n<20000000{ 14 | chan_int3<-n 15 | n++ 16 | } 17 | }() 18 | //time.Sleep(2e9)//确保上面的g程存值 19 | loop: 20 | //for { 21 | T_After:=time.After(3e9) 22 | v,ok:=reflect.ValueOf(T_After).TryRecv() 23 | fmt.Println(v,ok) 24 | 25 | if v.Kind()!=reflect.Invalid{ 26 | fmt.Println("3s时间到,准备执行退出循环",v) 27 | //break loop 28 | return 29 | } 30 | //select { 31 | //case i:=<-chan_int3: 32 | // fmt.Println("取到通道的值为:",i) 33 | for m:=0;m<200000000 ;m++ { 34 | m++ 35 | } 36 | goto loop 37 | //} 38 | //} 39 | fmt.Println("for循环已经退出。。。准备结束整个程序") 40 | } 41 | -------------------------------------------------------------------------------- /io_pro/test/test32.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main34792() { 9 | chan_int3 := make(chan int, 3) 10 | chan_int4 := make(chan int, 4) 11 | go func() { 12 | n:=0 13 | for n<20000000{ 14 | chan_int3<-n 15 | n++ 16 | } 17 | }() 18 | time.Sleep(2e9)//确保上面的g程存值 19 | 20 | go func() { 21 | time.Sleep(2e9) 22 | n:=0 23 | for n<200{ 24 | chan_int4<-n 25 | n++ 26 | } 27 | }() 28 | 29 | for { 30 | 31 | select { 32 | case i:=<-chan_int4: 33 | fmt.Println("取到chan_int4通道的值为==============:",i) 34 | case i:=<-chan_int3: 35 | fmt.Println("取到chan_int3通道的值为:",i) 36 | for m:=0;m<200000 ;m++ { 37 | m++ 38 | } 39 | } 40 | } 41 | fmt.Println("for循环已经退出。。。准备结束整个程序") 42 | } 43 | -------------------------------------------------------------------------------- /io_pro/test/test33.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "time" 7 | ) 8 | 9 | func main568343() { 10 | ticker := time.NewTicker(2e9) 11 | defer ticker.Stop() 12 | ch1 := make(chan string, 3) 13 | ch2 := make(chan string, 3) 14 | 15 | go func() { 16 | for i := 0; i < 2000000; i++ { 17 | ch1 <- "ch1---" + strconv.Itoa(i) 18 | } 19 | }() 20 | 21 | go func() { 22 | for i := 0; i < 3000000; i++ { 23 | ch1 <- "ch2---" + strconv.Itoa(i) 24 | } 25 | }() 26 | for { 27 | select { 28 | case u := <-ch1: 29 | fmt.Println(u) 30 | case v := <-ch2: 31 | fmt.Println(v) 32 | case <-ticker.C: 33 | fmt.Println("2s时间到,进入 ticker case") 34 | 35 | default: 36 | fmt.Println("default case") 37 | break 38 | } 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /io_pro/test/test34.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "fmt" 4 | "time" 5 | ) 6 | func main45789() { 7 | tick := time.Tick(1e8) 8 | boom := time.After(5e8) 9 | for { 10 | select { 11 | case <-tick: 12 | fmt.Println("tick.") 13 | case <-boom: 14 | fmt.Println("BOOM!") 15 | return 16 | default: 17 | fmt.Println("." ) 18 | time.Sleep(5e7)//2个5e7=1e8 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /io_pro/test/test35.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main347834() { 9 | start() 10 | fmt.Println("start end") 11 | time.Sleep(8e9) 12 | fmt.Println("main end") 13 | } 14 | 15 | func start() { 16 | fmt.Println("here") 17 | go func() { 18 | time.Sleep(2e9) 19 | fmt.Println("goroutine running") 20 | }() 21 | 22 | //tick := time.Tick(1e8) 23 | //boom := time.After(5e8) 24 | //select { 25 | //case <-tick: 26 | // fmt.Println("tick.") 27 | //case <-boom: 28 | // fmt.Println("BOOM!") 29 | // return 30 | //default: 31 | // fmt.Println("." ) 32 | // time.Sleep(5e7)//2个5e7=1e8 33 | //} 34 | } 35 | -------------------------------------------------------------------------------- /io_pro/test/test36.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | // "fmt" 5 | "fmt" 6 | "reflect" 7 | // "time" 8 | ) 9 | 10 | func main45893() { 11 | // start := time.Microsecond.Nanoseconds() 12 | // slice_dst := make([][]string, 0, 7) 13 | 14 | // str1 := "1" 15 | // str2 := "anko" 16 | // str := &[]string{str1, str2} 17 | // for i := 0; i < cap(slice_dst); i++ { 18 | // slice_dst = append(slice_dst, *str) 19 | // } 20 | // end := time.() 21 | // fmt.Printf("%+v----%v", slice_dst,end-start) 22 | // fmt.Println(reflect.TypeOf((interface{})(nil)).Kind()) 23 | fmt.Println(reflect.TypeOf((*interface{})(nil)).Elem().Kind()) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /io_pro/test/test37.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type add struct { 6 | x int 7 | } 8 | 9 | func (a add) add1(y ...int) int { 10 | return a.x + y[0] 11 | } 12 | 13 | func main92738() { 14 | var ad = add{} 15 | sum := ad.add1(5, 6) 16 | fmt.Println(sum) 17 | } 18 | -------------------------------------------------------------------------------- /io_pro/test/test38.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "reflect" 8 | ) 9 | 10 | func update( aa11 *interface{}){ 11 | *aa11=5 12 | } 13 | 14 | func main34356() { 15 | var aa11 interface{}=4 16 | fmt.Printf("aa11更改之前:%T---%v\n",aa11,aa11) 17 | update(&aa11) 18 | fmt.Printf("aa11更改之后:%T---%v\n",aa11,aa11) 19 | 20 | var r io.Reader 21 | r=bytes.NewBuffer([]byte{'a','b','c'}) 22 | fmt.Printf("%#v\n",reflect.TypeOf(r).Elem()) 23 | //输出: 24 | // aa11更改之前:int---4 25 | // aa11更改之后:int---5 26 | // &reflect.rtype{size:0x28, ptrdata:0x8, hash:0x64cbaa3a, tflag:0x7, align:0x8, fieldAlign:0x8, kind:0x19, alg:(*reflect.typeAlg)(0x620620), gcdata:(*uint8)(0x5499b0), str:33168, ptrToThis:253920} 27 | a:=3 28 | b:=3 29 | fmt.Printf("%#v\n",reflect.DeepEqual(&a,&b)) 30 | } 31 | -------------------------------------------------------------------------------- /io_pro/test/test39.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func changeValue(a unsafe.Pointer){ 9 | 10 | fmt.Printf("changeValue_a:\t%T--%p--%v\n",a,a,a) 11 | i:=(*int)(a) 12 | fmt.Println("changeValue_i:\t",i) 13 | *i=5 14 | } 15 | 16 | func main346773() { 17 | var cls int=4 18 | var a =unsafe.Pointer(&cls) 19 | 20 | fmt.Printf("main_a:\t%T=====%p======%v\n",a,a,a) 21 | fmt.Printf("changeValue前cls:\t%T_____%p_____%v\n",cls,&cls,cls) 22 | changeValue(a) 23 | fmt.Printf("changeValue后cls:\t%T_____%p_____%v\n",cls,&cls,cls) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /io_pro/test/test40.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import("fmt";"time") 4 | 5 | 6 | func main45782() { 7 | for i:=0;i<3;i++{ 8 | 9 | var a int 10 | fmt.Println("请输入一个值:") 11 | n,err:=fmt.Scanln(&a) 12 | if err!=nil{ 13 | fmt.Println(err) 14 | } 15 | fmt.Println("输出:",a,"\t字符串个数为:",n) 16 | time.Sleep(2e9) 17 | 18 | } 19 | time.Sleep(5e9) 20 | } -------------------------------------------------------------------------------- /io_pro/test/test41.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | ) 8 | 9 | type StructA struct { 10 | Username string `json:"user"` 11 | Process string `json:"process"` 12 | } 13 | 14 | func main345676() { 15 | 16 | var test1 StructA 17 | err := json.Unmarshal([]byte(`{"user": "user123", "process": "something"}`), &test1) 18 | if err != nil { 19 | fmt.Println(err) 20 | } 21 | fmt.Printf("%#v\n",test1) 22 | // do some work with test1 23 | 24 | buffer := new(bytes.Buffer) 25 | encoder := json.NewEncoder(buffer) 26 | //encoder.SetEscapeHTML() 27 | 28 | //无法更改struct的tag值,只能传创建struct 29 | //fmt.Printf("%v\n",&test1.Username) 30 | //elem := reflect.TypeOf(&test1).Elem().Field(0) 31 | // 32 | //fmt.Println(elem.Tag) 33 | //reflect.ValueOf(&elem.Tag).Elem().SetString("user12345") 34 | //fmt.Println(elem.Tag) 35 | //fmt.Printf("%v\n",&test1.Username) 36 | // 37 | //fmt.Println(reflect.TypeOf(test1).Field(0).Tag) 38 | //fmt.Println(reflect.TypeOf(&test1).Elem().Field(0).Tag.Lookup(`user`)) 39 | // 40 | // 41 | //fmt.Println(reflect.TypeOf(test1).Field(0).Tag) 42 | 43 | err = encoder.Encode(&test1) 44 | if err != nil { 45 | fmt.Println(err) 46 | } 47 | fmt.Println(buffer) 48 | 49 | 50 | jsonByte, err := json.Marshal(&test1) 51 | if err != nil { 52 | fmt.Println(err) 53 | } 54 | 55 | fmt.Println(string(jsonByte)) 56 | 57 | } 58 | 59 | func (u *StructA) MarshalJSON() ([]byte, error) { 60 | type Alias StructA 61 | return json.Marshal(&struct { 62 | Username string `json:"username"` 63 | *Alias 64 | }{ 65 | Username: u.Username, 66 | Alias: (*Alias)(u), 67 | }) 68 | } -------------------------------------------------------------------------------- /io_pro/test/test42.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main67942() { 6 | ls := []int{1, 2, 3, 4, 5} 7 | ch := make(chan int, 1) 8 | 9 | for _, i := range ls { 10 | loop: 11 | select { 12 | //取值 13 | case x := <-ch: 14 | fmt.Println(x) 15 | 16 | if x !=5{ 17 | goto loop 18 | } 19 | //存值 20 | case ch <- i: 21 | fmt.Println("存值:", i) 22 | 23 | if i ==5 { 24 | goto loop 25 | } 26 | 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /io_pro/test/test43.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "fmt" 4 | "sync" 5 | ) 6 | 7 | var wg sync.WaitGroup 8 | 9 | func main345667() { 10 | 11 | ls:=[]int{1,2,3,4,5} 12 | ch := make(chan int) 13 | 14 | //取值 15 | go func (){ 16 | ret:=0 17 | for { 18 | n := <-ch 19 | ret+=n//事实上你的这些操作都可以在存值的时候做,而不是在这里做,整体表现出你的需求不明确 20 | fmt.Printf("%v接收成功,和为%v\n",n, ret) 21 | last_index:=len(ls)-1 22 | 23 | if n == ls[last_index]*ls[last_index]{ 24 | break 25 | } 26 | } 27 | defer wg.Done() 28 | }() 29 | wg.Add(1) 30 | 31 | //存值 32 | go func() { 33 | for _, v := range ls {//如果是引用类型而使用&ls的话会报错,假如是值类型则不会 34 | ch <- v*v 35 | } 36 | defer wg.Done() 37 | }() 38 | wg.Add(1) 39 | 40 | wg.Wait() 41 | fmt.Println("发送成功") 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /io_pro/test/test44.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type person1 struct { 6 | name string 7 | age string 8 | info []string 9 | } 10 | 11 | func (p1 *person1)String()string { 12 | var str string="==" + p1.name + p1.age 13 | return str 14 | } 15 | //不可以既实现指针类型的String()方法,又实现值类型的String()方法 16 | //func (p1 person1)String()string { 17 | // var str string="==" + p1.name + p1.age 18 | // return str 19 | //} 20 | 21 | type person2 struct { 22 | name string 23 | age string 24 | pp1 *person1 25 | } 26 | 27 | 28 | func main34677() { 29 | 30 | var p1 = &person1{name:"anko1--",age:"17",info:[]string{"info1","info2"}} 31 | var p2 = &person2{name:"anko2--",age:"18",pp1:p1} 32 | pp1 := p2.pp1 33 | fmt.Printf("%+v\n",*pp1) 34 | fmt.Printf("%+v\n",pp1) 35 | //{name:anko1-- age:17 info:[info1 info2]} 36 | //==anko1--17 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /io_pro/test/test45.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //至少传递0个参数 6 | func add1(ls_int ...int) int { 7 | num:=0 8 | for _, v := range ls_int { 9 | num+=v 10 | } 11 | return num 12 | } 13 | 14 | //至少传递一个参数 15 | func add2(default1 int,ls_int ...int) int { 16 | num:=default1 17 | for _, v := range ls_int { 18 | num+=v 19 | } 20 | return num 21 | } 22 | 23 | func main457993() { 24 | fmt.Println(add1()) 25 | fmt.Println(add1(3,5)) 26 | fmt.Println(add2(3)) 27 | fmt.Println(add2(3,7)) 28 | fmt.Println(add2(3,7,5)) 29 | } 30 | -------------------------------------------------------------------------------- /io_pro/test/test46.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main56794() { 9 | 10 | type ppp struct { 11 | name string 12 | age int 13 | } 14 | var p ppp 15 | //=ppp{"anko",88} 16 | fmt.Printf("%#v\n",p) 17 | if reflect.ValueOf(p).IsValid(){ 18 | fmt.Println("有效值,非zero Value") 19 | }else { 20 | fmt.Println("zero Value,无效值") 21 | } 22 | //只要是reflect.ValueOf()返回的值都不会是reflect.Value{}这个零值 23 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p).Elem()).IsZero()) 24 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p)).IsZero())//这个有没有疑问的? 25 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.Value{}).IsZero())//这个有没有疑问的? 26 | fmt.Printf("%#v\n",reflect.ValueOf(p).IsZero()) 27 | fmt.Printf("%#v\n",reflect.ValueOf(&p).IsZero()) 28 | //fmt.Printf("%#v\n",reflect.ValueOf(10).Elem()) 29 | 30 | fmt.Println() 31 | var p1 *ppp 32 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p1).Elem()).IsZero()) 33 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p1).Elem()).IsZero()) 34 | fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p1)).IsZero()) 35 | fmt.Printf("%#v\n",reflect.ValueOf(p1).IsZero()) 36 | fmt.Printf("%#v\n",reflect.ValueOf(&p1).IsZero()) 37 | 38 | 39 | fmt.Println() 40 | var p2 *ppp 41 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向*ppp) 42 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(&p2).Elem()).IsNil()) 43 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向ppp) 44 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p2).Elem()).IsNil()) 45 | //panic: reflect: call of reflect.Value.IsNil on struct Value(reflect.Value结构体----字段指针指向*ppp) 46 | //fmt.Printf("%#v\n",reflect.ValueOf(reflect.ValueOf(p2)).IsNil()) 47 | fmt.Printf("%#v\n",reflect.ValueOf(p2).IsNil()) 48 | fmt.Printf("%#v\n",reflect.ValueOf(&p2).IsNil()) 49 | 50 | //输出: 51 | // main.ppp{name:"", age:0} 52 | // 有效值,非zero Value 53 | // false 54 | // false 55 | // true 56 | // false 57 | // 58 | // false 59 | // true 60 | // false 61 | // true 62 | // false 63 | // 64 | // true 65 | // false 66 | } 67 | -------------------------------------------------------------------------------- /io_pro/test/test47.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //import "fmt" 4 | //import "io" 5 | // 6 | //type Human struct { 7 | // name string 8 | // age int 9 | //} 10 | // 11 | //type Human1 *Human 12 | // 13 | //func (Human1)say() {//接受者不能为pointer类型或者接口类型 14 | // fmt.Println("say hi") 15 | //} 16 | // 17 | //func main4579() { 18 | // h:=Human1{ 19 | // name: "anko", 20 | // age: 20, 21 | // } 22 | // h.say() 23 | // (&h).say() 24 | //} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | //package main 39 | // 40 | //import ( 41 | //"fmt" 42 | //) 43 | // 44 | //type notifier interface { 45 | // notify() 46 | //} 47 | // 48 | //type user struct { 49 | // name string 50 | // email string 51 | //} 52 | // 53 | //func (u *user) notify() { 54 | // fmt.Printf("Sending user email to %s<%s>\n", u.name, u.email) 55 | //} 56 | // 57 | //func main() { 58 | // u := user{"Bill", "bill@email.com"} 59 | // //sendNotification(u)//报错,u必须为*user类型 60 | // sendNotification(&u) 61 | // u.notify() 62 | // (&u).notify() 63 | // 64 | //} 65 | //// sendNotification 接受一个实现了 notifier 接口的值 66 | //// 并发送通知 67 | //func sendNotification(n notifier) { 68 | // fmt.Println("sendNotification----start") 69 | // n.notify() 70 | // fmt.Println("sendNotification----end") 71 | //} -------------------------------------------------------------------------------- /io_pro/test/test48.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | type Reader interface { 9 | MyRead(p []byte) (n int, err error) 10 | } 11 | 12 | type teach interface { 13 | //Reader //teach接口和Reader接口相互独立 14 | MyWrite(p []byte) (n int, err error) 15 | } 16 | 17 | type teacher struct { 18 | name string 19 | age int 20 | } 21 | //实现了独立接口Reader 22 | func (teacher)MyRead(p []byte) (n int, err error) { 23 | fmt.Println("MyRead()方法执行中") 24 | return len(p), nil 25 | } 26 | //实现了独立接口teach 27 | func (teacher)MyWrite(p []byte) (n int, err error) { 28 | fmt.Println("MyWrite()方法执行中") 29 | return len(p), nil 30 | } 31 | 32 | func main088239() { 33 | T:=teacher{ 34 | name: "anko", 35 | age: 20, 36 | } 37 | fmt.Println(T.name) 38 | fmt.Println(T.age) 39 | fmt.Println(T.MyRead([]byte{'a','b','c'})) 40 | fmt.Println(T.MyWrite([]byte{'x','y','z'})) 41 | 42 | fmt.Println("--------------") 43 | var iT teach 44 | if !reflect.ValueOf(iT).IsValid(){ 45 | fmt.Println("iT此时为nil,不能调用任何方法,否则会报错,为此,我们将iT赋值给一个实现类实例对象:") 46 | iT=T 47 | //fmt.Println(iT.MyRead([]byte{'a','b','c'}))//不存在MyRead方法 48 | fmt.Println(iT.(Reader).MyRead([]byte{'a','b','c'})) 49 | fmt.Println(iT.MyWrite([]byte{'x','y','z'})) 50 | }else { 51 | fmt.Println("iT非nil") 52 | //fmt.Println(iT.MyRead([]byte{'a','b','c'}))//不存在MyRead方法 53 | fmt.Println(iT.(Reader).MyRead([]byte{'a','b','c'})) 54 | fmt.Println(iT.MyWrite([]byte{'x','y','z'})) 55 | } 56 | } -------------------------------------------------------------------------------- /io_pro/test/test49.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | //func main() { 9 | // Myperson(map[string]interface{}{"name":"anko","age":18}) 10 | //} 11 | // 12 | //func Myperson(b map[string]interface{}) { 13 | // fmt.Println(b) 14 | //} 15 | 16 | //这个结构体作为 关键字传参封装函数 17 | type keyArgs struct{ 18 | name interface{} 19 | age interface{} 20 | } 21 | //对结构体进行默认值的检查 22 | func keyArgsDefaultValue(defaultValue ...interface{}) *keyArgs{ 23 | k,ok:= defaultValue[0].(*keyArgs) 24 | //defaultValue2 := defaultValue 25 | //断言失败,默认值 26 | if !ok{ 27 | k1:=&keyArgs{defaultValue[0],defaultValue[1]} 28 | return k1 29 | }else { 30 | //设置值 31 | for key, value0 := range defaultValue { 32 | switch reflect.ValueOf(*k).Field(key).Kind(){ 33 | 34 | case reflect.String: 35 | k.name=value0.(string) 36 | case reflect.Int: 37 | k.age=value0.(int) 38 | 39 | } 40 | } 41 | return k 42 | } 43 | 44 | 45 | 46 | } 47 | 48 | func defaultmy(defaultFun func(defaultValue ...interface{}) *keyArgs,k1 ...*keyArgs,) (kArg *keyArgs) { 49 | if len(k1)==0{ 50 | //默认值 51 | kArg =defaultFun("anko1",18) 52 | }else { 53 | //设置值 54 | kArg=defaultFun(k1[0]) 55 | } 56 | return 57 | } 58 | 59 | func Myperson(defaultFun func(defaultValue ...interface{}) *keyArgs,k1 ...*keyArgs) { 60 | var kArg *keyArgs=defaultmy(defaultFun,k1...) 61 | fmt.Printf("%T---%#v\n",kArg,kArg) 62 | } 63 | 64 | 65 | func main() { 66 | 67 | //Myperson(keyArgsDefaultValue) 68 | Myperson(keyArgsDefaultValue,&keyArgs{"anko",20}) 69 | 70 | 71 | 72 | } 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /io_pro/test/test50.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | ) 7 | 8 | 9 | 10 | func main998766() { 11 | var myint int =5 12 | var _ int =5 13 | 14 | var bf bytes.Buffer 15 | var r io.Reader=&bf 16 | //var _ io.Reader=&bf//弃用 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /io_pro/test/testdir/1.txt: -------------------------------------------------------------------------------- 1 | 这个文件夹以及文件都是为了做测试的! -------------------------------------------------------------------------------- /io_pro/test/testdir/2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/test/testdir/2.txt -------------------------------------------------------------------------------- /io_pro/test/testdir/sum.go: -------------------------------------------------------------------------------- 1 | package testdir 2 | 3 | func Sum1(a,b int) int { 4 | return a+b 5 | } -------------------------------------------------------------------------------- /io_pro/test/testdir/test16.go: -------------------------------------------------------------------------------- 1 | package testdir 2 | // 3 | //import ( 4 | // "fmt" 5 | // "time" 6 | //) 7 | // 8 | //func main34346() { 9 | // time.Sleep(2e9) 10 | // fmt.Println("-1111",time.Now()) 11 | // a:=<-time.After(2) 12 | // fmt.Println("-2222",a) 13 | //} 14 | -------------------------------------------------------------------------------- /io_pro/test/包说明.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/test/包说明.md -------------------------------------------------------------------------------- /io_pro/test1.txt: -------------------------------------------------------------------------------- 1 | abc伟大的时代创造伟大的工程,伟大的工程反映伟大的时代。党的十八大以来,C919大型客机飞上蓝天, 2 | 港珠澳大桥主体工程全线贯通,复兴号奔驰在祖国广袤的大地上.......一项项民生工程顺利落地,正如习近平所言, 3 | “中国制造、中国创造、中国建造共同发力,继续改变着中国的面貌。”abc 4 | 习近平指出,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中,本届女排世界杯期间,全国人民都在关注你们,每一场比赛都有亿万人民为你们加油。38年前,中国女排首夺世界冠军时,举国上下心潮澎湃,亿万观众热泪盈眶。中国女排“五连冠”,万人空巷看女排。广大人民群众对中国女排的喜爱,不仅是因为你们夺得了冠军,更重要的是你们在赛场上展现了祖国至上、团结协作、顽强拼搏、永不言败的精神面貌。女排精神代表着一个时代的精神,喊出了为中华崛起而拼搏的时代最强音。平凡孕育着伟大。你们天天坚持训练,咬牙克服伤病,默默承受挫折,特别在低谷时仍有一批人默默工作、不计回报。正是因为有这么一批人,才有了中国女排今 5 | SDSDSDSDSDSD -------------------------------------------------------------------------------- /io_pro/test2.txt: -------------------------------------------------------------------------------- 1 | abc伟大的时代创造伟大的工程,伟大的工程反映伟大的时代。党的十八大以来,C919大型客机飞上蓝天, 2 | 港珠澳大桥主体工程全线贯通,复兴号奔驰在祖国广袤的大地上.......一项项民生工程顺利落地,正如习近平所言, 3 | “中国制造、中国创造、中国建造共同发力,继续改变着中国的面貌。”abc -------------------------------------------------------------------------------- /io_pro/test3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnkoGo/Go-Library-Demo/f7f38a52aa4439be04ecfddab171a512298608ab/io_pro/test3.txt -------------------------------------------------------------------------------- /io_pro/test4.txt: -------------------------------------------------------------------------------- 1 | 2 | 正在 Ping www.a.shifen.com [183.232.231.172] 具有 32 字节的数据: 3 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 4 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 5 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 6 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 7 | 8 | 183.232.231.172 的 Ping 统计信息: 9 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 10 | 往返行程的估计时间(以毫秒为单位): 11 | 最短 = 10ms,最长 = 10ms,平均 = 10ms 12 | 13 | 正在 Ping www.a.shifen.com [183.232.231.172] 具有 32 字节的数据: 14 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 15 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 16 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 17 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 18 | 19 | 183.232.231.172 的 Ping 统计信息: 20 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 21 | 往返行程的估计时间(以毫秒为单位): 22 | 最短 = 10ms,最长 = 10ms,平均 = 10ms 23 | 24 | 正在 Ping www.a.shifen.com [183.232.231.172] 具有 32 字节的数据: 25 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 26 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 27 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 28 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 29 | 30 | 183.232.231.172 的 Ping 统计信息: 31 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 32 | 往返行程的估计时间(以毫秒为单位): 33 | 最短 = 10ms,最长 = 10ms,平均 = 10ms 34 | 35 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 36 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 37 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 38 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 39 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 40 | 41 | 183.232.231.174 的 Ping 统计信息: 42 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 43 | 往返行程的估计时间(以毫秒为单位): 44 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 45 | 46 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 47 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 48 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 49 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 50 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 51 | 52 | 183.232.231.174 的 Ping 统计信息: 53 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 54 | 往返行程的估计时间(以毫秒为单位): 55 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 56 | 57 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 58 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 59 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 60 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 61 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 62 | 63 | 183.232.231.174 的 Ping 统计信息: 64 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 65 | 往返行程的估计时间(以毫秒为单位): 66 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 67 | 68 | 正在 Ping www.a.shifen.com [183.232.231.172] 具有 32 字节的数据: 69 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 70 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 71 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 72 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 73 | 74 | 183.232.231.172 的 Ping 统计信息: 75 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 76 | 往返行程的估计时间(以毫秒为单位): 77 | 最短 = 10ms,最长 = 10ms,平均 = 10ms 78 | 79 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 80 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 81 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 82 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 83 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 84 | 85 | 183.232.231.174 的 Ping 统计信息: 86 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 87 | 往返行程的估计时间(以毫秒为单位): 88 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 89 | 90 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 91 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 92 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 93 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 94 | 来自 183.232.231.174 的回复: 字节=32 时间=10ms TTL=56 95 | 96 | 183.232.231.174 的 Ping 统计信息: 97 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 98 | 往返行程的估计时间(以毫秒为单位): 99 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 100 | 101 | 正在 Ping www.a.shifen.com [183.232.231.174] 具有 32 字节的数据: 102 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 103 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 104 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 105 | 来自 183.232.231.174 的回复: 字节=32 时间=11ms TTL=56 106 | 107 | 183.232.231.174 的 Ping 统计信息: 108 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 109 | 往返行程的估计时间(以毫秒为单位): 110 | 最短 = 11ms,最长 = 11ms,平均 = 11ms 111 | 112 | 正在 Ping www.a.shifen.com [183.232.231.172] 具有 32 字节的数据: 113 | 来自 183.232.231.172 的回复: 字节=32 时间=10ms TTL=55 114 | 来自 183.232.231.172 的回复: 字节=32 时间=11ms TTL=55 115 | 来自 183.232.231.172 的回复: 字节=32 时间=11ms TTL=55 116 | 来自 183.232.231.172 的回复: 字节=32 时间=11ms TTL=55 117 | 118 | 183.232.231.172 的 Ping 统计信息: 119 | 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 120 | 往返行程的估计时间(以毫秒为单位): 121 | 最短 = 10ms,最长 = 11ms,平均 = 10ms 122 | --------------------------------------------------------------------------------