视频来源:B站《golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]》

一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:Go语言自学系列 | 汇总_COCOgsta的博客-CSDN博客_go语言自学


Bufio

bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。

常量

const (defaultBufSize = 4096
)

变量

var (ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")ErrInvalidUnreadRune = errors.New("bufio: invalid uuse of UnreadRune")ErrBufferFull        = errors.New("bufio: buffer full")ErrNegativeCouunt    = errors.New("bufio: negative count")
)
var (ErrTooLong         = errors.New("bufio.Scanner: token too long")ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

会被Scanner类型返回的错误。

type Reader

type Reader struct {buf          []byterd           io.Reader // reader provided by the clientr, w         int       // buf read and write positionserr          errorlastByte     int // last byte read for UnreadByte; -1 means invalidlastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}

Reader实现了给一个io.Reader接口对象附加缓冲

func NewReader

func NewReader(rd io.Reader) *Reader

NewReaderSize创建一个具有默认大小缓冲、从r读取的*Reader。NewReader相当于NewReaderSize(rd, 4096)

func NewReaderSize

func NewReaderSize(rd io.Reader, size int) *Reader

NewReaderSize创建一个具有最少有size尺寸的缓冲、从r读取的Reader。如果参数r已经是一个具有足够大缓冲的Reader类型值,会返回r。

func (*Reader) Reset(r.io.Reader)

func (b *Reader) Reset(r io.Reader)

Reset丢弃缓冲中的数据,清除任何错误,将b重设为其下层从r读取数据。

func main() {s := strings.NewReader("ABCDEFG")str := strings.NewReader("12345")br := bufio.NewReader(s)b, _ := br.ReadString('\n')fmt.Println(b)br.Reset(str)b, _ = br.ReadString('\n')fmt.Println(b)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
ABCDEFG
12345

func (*Reader) Read

func (b *Reader) Read(p []byte) (n int, err error)

Read读取数据写入p。本方法返回去写入p的字节数。本方法一次调用最多会调用下层Reader接口一次Read方法,因此返回值n可能小于len(p)。读取到达结尾时,返回值n将为0而err将为io.EOF。

func main() {s := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")br := bufio.NewReader(s)p := make([]byte, 10)for {n, err := br.Read(p)if err == io.EOF {break} else {fmt.Printf("string(p[0:n]): %v\n", string(p[0:n]))}}
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
string(p[0:n]): ABCDEFGHIJ
string(p[0:n]): KLMNOPQRST
string(p[0:n]): UVWXYZ1234
string(p[0:n]): 567890

func (*Reader) ReadByte

func (b *Reader) ReadByte() (c byte, err error)

ReadByte读取并返回一个字节。如果没有可用的数据,会返回错误。

func (*Reader) UnreadByte

func (b *Reader) UnreadByte() error

UnreadByte吐出最近一次读取操作读取的最后一个字节。(只能吐出最后一个,多次调用会出问题)

func main() {s := strings.NewReader("ABCDEFG")br := bufio.NewReader(s)c, _ := br.ReadByte()fmt.Printf("%c\n", c)c, _ = br.ReadByte()fmt.Printf("%c\n", c)br.UnreadByte()c, _ = br.ReadByte()fmt.Printf("%c\n", c)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
A
B
B

func (*Reader) ReadRune

func (b *Reader) ReadRune() (r rune, size int, err error)

ReadRune读取一个utf-8编码的unicode码值,返回该码值、其编码长度和可能的错误。如果utf-8编码非法,读取位置只移动1字节,返回U+FFFD,返回值size为1而err为nil。如果没有可用的数据,会返回错误。

func (*Reader) UnreadRune

func (b *Reader) UnreadRune() error

UnreadRune吐出最后一次ReadRune调用读取的unicode码值。如果最近一次读取不是调用的ReadRune,会返回错误。(从这点看,UnreadRune比unreadByte严格很多)

func main() {s := strings.NewReader("你好,世界!")br := bufio.NewReader(s)c, size, _ := br.ReadRune()fmt.Printf("%c %v\n", c, size)c, size, _ = br.ReadRune()fmt.Printf("%c %v\n", c, size)br.UnreadRune()c, size, _ = br.ReadRune()fmt.Printf("%c %v\n", c, size)}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
你 3
好 3
好 3

func (*Reader) ReadLine

func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)

ReadLine尝试返回一行数据,不包括行尾标志的字节。如果行太长超过了缓冲,返回值isPrefix会被设为true,并返回行的前面一部分。该行剩下的部分将在之后的调用中返回。返回值isPrefix会在返回该行最后一个片段时才设为false。返回切片是缓冲的子切片,只在下一次读取操作之前有效。ReadLine要么返回一个非nil的line,要么返回一个非nil的err,两个返回值至少一个非nil。

返回的文本不包含行尾的标志字节(“\r\n”或"\n")。如果输入流结束时没有行尾标志字节,方法不会出错,也不会指出这一情况。在调用ReadLine之后调用UnreadByte会总是吐出最后一个读取的字节(很可能是该行的行尾标志字节),即使该字节不是ReadLine返回值的一部分。

func main() {s := strings.NewReader("ABC\nDEF\r\nGHI\r\nGHI")br := bufio.NewReader(s)w, isPrefix, _ := br.ReadLine()fmt.Printf("%q %v\n", w, isPrefix)w, isPrefix, _ = br.ReadLine()fmt.Printf("%q %v\n", w, isPrefix)w, isPrefix, _ = br.ReadLine()fmt.Printf("%q %v\n", w, isPrefix)w, isPrefix, _ = br.ReadLine()fmt.Printf("%q %v\n", w, isPrefix)}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
"ABC" false
"DEF" false
"GHI" false
"GHI" false

func (*Reader) ReadSlice

func (b *Reader) ReadSlice(delim byte) (line []byte, err error)

ReadSlice读取直到第一次遇到delim字节,返回缓冲里的包含已读取的数据和delim字节的切片。该返回值只在下一次读取操作之前合法。如果ReadSlice放在在读取到delim之前遇到了错误,它会返回在错误之前读取的数据在缓冲中的切片以及该错误(一般是io.EOF)。如果在读取delim之前缓冲就写满了,ReadSlice失败并返回ErrBufferFull。因为ReadSlice的返回值会被下一次I/O操作重写,调用者应尽量使用ReadBytes或ReadString替代本法功法。当且仅当ReadBytes方法返回的切片不以delim结尾时,会返回一次非nil的错误。

func main() {s := strings.NewReader("ABC,DEF,GHI,JKL")br := bufio.NewReader(s)w, _ := br.ReadSlice(',')fmt.Printf("%q\n", w)w, _ = br.ReadSlice(',')fmt.Printf("%q\n", w)w, _ = br.ReadSlice(',')fmt.Printf("%q\n", w)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
"ABC,"
"DEF,"
"GHI,"

func (*Reader) ReadString

func (b *Reader) ReadString(delim byte) (line string, err error)

ReadString读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的字符串。如果ReadString方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadString方法返回的切片不以delim结尾时,会返回一个非nil的错误。

func main() {s := strings.NewReader("ABC DEF GHI JKL")br := bufio.NewReader(s)w, _ := br.ReadString(' ')fmt.Printf("%q\n", w)w, _ = br.ReadString(' ')fmt.Printf("%q\n", w)w, _ = br.ReadString(' ')fmt.Printf("%q\n", w)}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
"ABC "
"DEF "
"GHI "

func (*Reader) WriteTo

func (b *Reader) WriteTo(w io.Writer) (n int64, err error)

WriteTo方法实现了io.WriterTo接口。

func main() {s := strings.NewReader("ABCDEFGHIJKLMN")br := bufio.NewReader(s)b := bytes.NewBuffer(make([]byte, 0))br.WriteTo(b)fmt.Printf("%s\n", b)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
ABCDEFGHIJKLMN

type Writer

type Writer struct {err errorbuf []byten   intwr  io.Writer
}

Writer实现了为io.Writer接口对象提供缓冲。如果在向一个Writer类型值写入时遇到了错误,该对象将不再接受任何数据,且所有写操作都会返回该错误。在说有数据都写入后,调用者有义务调用Flush方法以保证所有的数据都交给了下层的io.Writer。

func NewWriter

func NewWriter(w io.Writer) *Writer

NewWriter创建一个具有默认大小缓冲、写入w的*Writer。NewWriter相当于NewWriterSize(wr, 4096)

func NewWriterSize

func NewWriterSize(w io.Writer, size int) *Writer

NewWriterSize创建一个具有最少有size尺寸的缓冲、写入w的Writer。如果参数w已经是一个具有足够大缓冲的Writer类型值,会返回w。

func (*Writer) Reset

func (b *Writer) Reset(w io.Writer)

Reset丢弃缓冲中的数据,清除任何错误,将b重设为将其输出写入w。

package mainimport ("bufio""bytes""fmt"
)func main() {b := bytes.NewBuffer(make([]byte, 0))bw := bufio.NewWriter(b)bw.WriteString("123456789")c := bytes.NewBuffer(make([]byte, 0))bw.Reset(c)bw.WriteString("456")bw.Flush()fmt.Println(b)fmt.Println(c)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"456

func (*Writer) Buffered

func (b *Writer) Buffered() int

Buffered返回缓冲中已使用的字节数。

func (*Writer) Available

func (b *Writer) Available() int

Available返回缓冲中海油多少字节未使用。

func (*Writer) Write

func (b *Writer) Write(p []byte) (nn int, err error)

Write将p的内容写入缓冲。返回写入的字节数。如果返回值nn < len(p),还会返回一个错误说明原因。

func (*Writer) WriteString

func (b *Writer) WriteString(s string) (int, error)

WriteString写入一个字符串。返回写入的字节数。如果返回值m < len(s),还会返回一个错误说明原因。

func (*Writer) WriteByte

func (b *Writer) WriteByte(c byte) error

WriteByte写入单个字节。

func (*Writer) WriterRune

func (b *Writer) WriteRune(r rune) (size int, err error)

WriteRune写入一个unicode码值(的utf-8编码),返回写入的字节数和可能的错误。

func (*Writer) Flush

func (b *Writer) Flush() error

Flush方法将缓冲中的数据写入下层的io.Writer接口。

func (*Writer) ReadFrom

func (b *Writer) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom实现了io.ReaderFrom接口。

package mainimport ("bufio""bytes""fmt"
)func main() {b := bytes.NewBuffer(make([]byte, 0))bw := bufio.NewWriter(b)fmt.Println(bw.Available()) // 4096fmt.Println(bw.Buffered())  // 0bw.WriteString("ABCDEFGHIJKLMN")fmt.Println(bw.Available())fmt.Println(bw.Buffered())fmt.Printf("%q\n", b)bw.Flush()fmt.Println(bw.Available())fmt.Println(bw.Buffered())fmt.Printf("%q\n", b)
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
4096
0
4082
14
""
4096
0
"ABCDEFGHIJKLMN"
package mainimport ("bufio""bytes""fmt""strings"
)func main() {b := bytes.NewBuffer(make([]byte, 0))s := strings.NewReader("Hello 世界!")bw := bufio.NewWriter(b)bw.ReadFrom(s)// bw.Flush() // ReadFrom无需使用Flush,其自己已经写入fmt.Println(b) // Hello 世界!
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
Hello 世界!

type ReadWriter

type ReadWriter struct {*Reader*Writer
}

ReadWriter类型保管了指向Reader和Writer类型的指针,(因此)实现了io.ReadWriter接口。

func NewReadWriter

func NewReadWriter(r *Reader, w *Writer) *ReadWriter

NewReadWriter申请创建一个新的、将读写操作分派给r和w的ReadWriter。

package mainimport ("bufio""bytes""fmt""strings"
)func main() {b := bytes.NewBuffer(make([]byte, 0))bw := bufio.NewWriter(b)s := strings.NewReader("123")br := bufio.NewReader(s)rw := bufio.NewReadWriter(br, bw)p, _ := rw.ReadString('\n')fmt.Println(string(p)) // 123rw.WriteString("asdf")rw.Flush()fmt.Println(b) // asdf
}

运行结果

[Running] go run "d:\SynologyDrive\软件开发\go\golang入门到项目实战\goproject\360duote.com\pro01\test.go"
123
asdf

type SplitFunc

type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

SplitFunc类型代表用于对输出作词法分析的分割函数。

参数data是尚未处理的数据的一个开始部分的切片,参数atEOF表示是否Reader接口不能提供更多的数据。返回值是解析位置前进的字节数,将要返回给调用者的token切片,以及可能遇到的错误。如果数据不足以(保证)生成一个完整的token,例如需要一整行数据但data里没有换行符,SplitFunc可以返回(0, nil, nil)来告诉Scanner读取更多的数据写入切片然后用从同一位置起始、长度更长的切片再试一次(调用SplitFunc类型函数)。

如果返回值err非nil,扫描将终止并将该错误返回给Scanner的调用者。

除非atEOF为真,永远不会使用空切片data调用SplitFunc类型函数。然而,如果atEOF为真,data却可能是非空的、且包含着未处理的文本。

SplitFunc的作用很简单,从data中找出你感兴趣的数据,然后返回并告诉调用者,data中有多少数据你已经处理过了。

func ScanBytes

func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanBytes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每个字节作为一个token返回。

func ScanRunes

func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数将每个utf-8编码的unicode码值作为一个token返回。本函数返回的rune序列和range一个字符串的输出rune序列相同。错误的utf-8编码会翻译为U+FFFD="\xef\xbf\xbd",但只会消耗一个字节。调用者无法区分正确编码的rune和错误编码的rune。

func ScanWords

func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanRunes是用于Scanner类型的分割函数(符合SplitFunc),本函数会将空白(参见unicode.IsSpace)分隔的片段(去掉前后空白后)作为一个token返回。本函数永远不会返回空字符串。用来找出data中的单行数据并返回(包括空行)

func ScanLines

func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error)

ScanLines是用于Scanner类型的分割函数(符合SplitFunc),本函数会将每一行文本去掉末尾的换行标记作为一个token返回。返回的行可以是空字符串。换行标记为一个可选的回车后跟一个必选的换行符。最后一行即使没有换行符也会作为一个token返回。

type Scanner

type Scanner struct {r            io.Reader // The reader provided by the client.split        SplitFunc // The function to split the token.maxTokenSize int       // Maximum size of a token; modified by tests.token        []byte    // Last token returned by split.buf          []byte    // Buffer used an argument to split.start        int       // First non-processed byte in buf.end          int       // End of data in buf.err          error     // Sticky error.
}

Scanner类型提供了方便的读取数据的接口,如从换行符分隔的文本里读取每一行。成功调用的Scan方法会逐步提供文件的token,跳过token之间的字节。token由SplitFunc类型的分割函数指定;默认的分割函数会将输入分割为多个行,并去掉行尾的换行标志。本包预定义的分割函数可以将文件分割为行、字节、unicode码值、空白分隔的word。调用者可以定制自己的分割函数。扫描会在抵达输入流结尾、遇到的第一个I/O错误、token过大不能保存进缓冲时,不可恢复的停止。当扫描停止后,当前读取位置可能会在最后一个获得的token后面。需要更多对错误管理的控制或token很大,或必须从reader连续扫描的程序,应使用buffio.Reader代替。

func NewScanner

func NewScanner(r io.Reader) *Scanner

NewScanner创建并返回一个从r读取数据的Scanner,默认的分割函数时ScanLines。

func (*Scanner) Split

func (s *Scanner) Split(split SplitFunc)

Split设置该Scanner的分割函数。本方法必须在Scan之前调用。

package mainimport ("bufio""fmt""strings"
)func main() {s := strings.NewReader("ABC DEF GHI JKL")bs := bufio.NewScanner(s)bs.Split(bufio.ScanWords)for bs.Scan() {fmt.Println(bs.Text())}}

运行结果

[Running] go run "/Users/guoliang/SynologyDrive/软件开发/go/golang入门到项目实战/goproject/360duote.com/pro01/test.go"
ABC
DEF
GHI
JKL

func (*Scanner) Scan

func (s *Scanner) Scan() bool

Scan方法获取当前位置的token(该token可以通过Bytes或Text方法获得),并让Scanner的扫描位置移动到下一个token。当扫描因为抵达输入流结尾或者遇到错误而停止时,本方法会返回false。在Scan方法返回false后,Err方法将返回扫描时遇到的任何错误;除非是io.EOF,此时Err会返回nil。

package mainimport ("bufio""fmt""strings"
)func main() {s := strings.NewReader("Hello 世界!")bs := bufio.NewScanner(s)bs.Split(bufio.ScanBytes)for bs.Scan() {fmt.Printf("%s", bs.Text())}}

运行结果

[Running] go run "/Users/guoliang/SynologyDrive/软件开发/go/golang入门到项目实战/goproject/360duote.com/pro01/tempCodeRunnerFile.go"
Hello ��界!

func (*Scanner) Bytes

func (s *Scanner) Bytes() []byte

Bytes方法返回最近一次Scan调用生成的token。底层数组指向的数据可能会被下一次Scan的调用重写。

package mainimport ("bufio""fmt""strings"
)func main() {s := strings.NewReader("Hello 世界!")bs := bufio.NewScanner(s)bs.Split(bufio.ScanRunes)for bs.Scan() {fmt.Printf("%s", bs.Text())}}

运行结果

[Running] go run "/Users/guoliang/SynologyDrive/软件开发/go/golang入门到项目实战/goproject/360duote.com/pro01/tempCodeRunnerFile.go"
Hello 世界!

func (*Scanner) Text

func (s *Scanner) Text() string

Bytes方法返回最近一次Scan调用生成的token,会申请创建一个字符串保存token并返回该字符串。

func (*Scanner) Err

func (s *Scanner) Err() error

Err返回Scanner遇到的第一个非EOF的错误。

Go语言自学系列 | golang标准库bufio相关推荐

  1. Go语言自学系列 | golang标准库os模块 - 文件目录相关

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,请移步至知乎网站,谢 ...

  2. Go语言自学系列 | golang标准库io包

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  3. Go语言自学系列 | golang标准库log

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  4. Go语言自学系列 | golang标准库os包进程相关操作

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  5. Go语言自学系列 | golang标准库os模块 - File文件读操作

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  6. Go语言自学系列 | golang标准库os包和环境相关的方法

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  7. Go语言自学系列 | golang标准库bytes

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  8. Go语言自学系列 | golang标准库errors

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

  9. Go语言自学系列 | golang简介

    视频来源:B站<golang入门到项目实战 [2021最新Go语言教程,没有废话,纯干货!持续更新中...]> 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! ...

最新文章

  1. 5.13T1Send 题(send)
  2. WinForm 里面ListBox的问题
  3. euler‘s formula
  4. 22)PHP,数组排序函数
  5. SAP 3D visual enterprise viewer 9.0 的下载方式
  6. android 5.0.1 libdvm.so,Android逆向进阶—— 脱壳的奥义(基ART模式下的dump)
  7. LeetCode 2120. 执行所有后缀指令(模拟)
  8. 在python中创建虚拟环境和Django对数据库的操作(一)
  9. 跨境独立站必备!用 WhatsApp 玩转海外私域流量
  10. linux下python、django框架的配置
  11. 网络工程师_记录的一些真题_2017上半年上午
  12. lt18i android 2.3.4典藏版,索尼LT18i一键ROOT教程工具 2.3.4已亲测成功
  13. 快速实现微信公众号支付功能
  14. leetcode 5230 Check If It Is a Straight Line
  15. 这 5 本数据分析书籍,都是经典中的经典
  16. HAL库开发—基于stm32的智能小家电
  17. 实习生风采 · 贰 | 张倬胜同学:攻关「孟子」轻量化预训练模型
  18. 两个ip是否在同一网段?
  19. 迅为IMX6ULL开发板从零开始编译 buildroot
  20. 100条超搞笑的“雷人”QQ/MSN 签名

热门文章

  1. 什么是 WPS(Wi-Fi Protected Setup)
  2. CPU频率调节模式以及降频方法简介
  3. python主题更改_IDLE怎么将主题修改成Darcula样式?
  4. 这些模具设计要点你要明白
  5. asp.net core mvc 错误处理 ExceptionFilterAttribute
  6. 保存到相册的视频怎么改封面?这个改封面小技巧很简单
  7. POCO C++库学习和分析 -- 序
  8. 前端调用第三方接口跨域问题(淘宝)
  9. PMP/高项 05-项目进度管理
  10. python3 时区 时间戳 指定输入时间为东八区时间、北京时间