您好,登錄后才能下訂單哦!
os 包提供了不依賴平臺的操作系統(tǒng)函數(shù)接口,設(shè)計(jì)像Unix風(fēng)格,但錯(cuò)誤處理是go風(fēng)格,當(dāng)os包使用時(shí),如果失敗后返回錯(cuò)誤類型而不是錯(cuò)誤數(shù)量。
func Hostname() (name string, err error) // Hostname返回內(nèi)核提供的主機(jī)名
func Environ() []string // Environ返回表示環(huán)境變量的格式為”key=value”的字符串的切片拷貝
func Getenv(key string) string // Getenv檢索并返回名為key的環(huán)境變量的值
func Getpid() int // Getpid返回調(diào)用者所在進(jìn)程的進(jìn)程ID
func Exit(code int) // Exit讓當(dāng)前程序以給出的狀態(tài)碼code退出。一般來說,狀態(tài)碼0表示成功,非0表示出錯(cuò)。程序會立刻終止,defer的函數(shù)不會被執(zhí)行
func Stat(name string) (fi FileInfo, err error) // 獲取文件信息
func Getwd() (dir string, err error) // Getwd返回一個(gè)對應(yīng)當(dāng)前工作目錄的根路徑
func Mkdir(name string, perm FileMode) error // 使用指定的權(quán)限和名稱創(chuàng)建一個(gè)目錄
func MkdirAll(path string, perm FileMode) error // 使用指定的權(quán)限和名稱創(chuàng)建一個(gè)目錄,包括任何必要的上級目錄,并返回nil,否則返回錯(cuò)誤
func Remove(name string) error // 刪除name指定的文件或目錄
func TempDir() string // 返回一個(gè)用于保管臨時(shí)文件的默認(rèn)目錄
var Args []string // os.Args返回一個(gè)字符串?dāng)?shù)組,其中第一個(gè)參數(shù)就是執(zhí)行文件本身
os示例:
package main
import (
"fmt"
"os"
)
func main() {
// 預(yù)定義變量, 保存命令行參數(shù)
fmt.Println(os.Args)
// 獲取host name
fmt.Println(os.Hostname())
fmt.Println(os.Getpid())
// 獲取全部環(huán)境變量
env := os.Environ()
for k, v := range env {
fmt.Println(k, v)
}
// 終止程序
// os.Exit(1)
// 獲取一條環(huán)境變量
fmt.Println(os.Getenv("PATH"))
// 獲取當(dāng)前目錄
dir, err := os.Getwd()
fmt.Println(dir, err)
// 創(chuàng)建目錄
err = os.Mkdir(dir+"/new_file", 0755)
fmt.Println(err)
// 創(chuàng)建目錄
err = os.MkdirAll(dir+"/new", 0755)
fmt.Println(err)
// 刪除目錄
err = os.Remove(dir + "/new_file")
err = os.Remove(dir + "/new")
fmt.Println(err)
// 創(chuàng)建臨時(shí)目錄
tmp_dir := os.TempDir()
fmt.Println(tmp_dir)
}
func Create(name string) (file *File, err error) // Create采用模式0666創(chuàng)建一個(gè)名為name的文件,如果文件已存在會截?cái)啵榭瘴募?func Open(name string) (file *File, err error) // Open打開一個(gè)文件用于讀取。如果操作成功,返回的文件對象的方法可用于讀取數(shù)據(jù)
func (f *File) Stat() (fi FileInfo, err error) // Stat返回描述文件f的FileInfo類型值
func (f *File) Readdir(n int) (fi []FileInfo, err error) // Readdir讀取目錄f的內(nèi)容,返回一個(gè)有n個(gè)成員的[]FileInfo
func (f *File) Read(b []byte) (n int, err error) // Read方法從f中讀取最多l(xiāng)en(b)字節(jié)數(shù)據(jù)并寫入b
func (f *File) WriteString(s string) (ret int, err error) // 向文件中寫入字符串
func (f *File) Sync() (err error) // Sync遞交文件的當(dāng)前內(nèi)容進(jìn)行穩(wěn)定的存儲
func (f *File) Close() error // Close關(guān)閉文件f,使文件不能用于讀寫
File示例:
package main
import (
"fmt"
"os"
"time"
)
func main() {
// 獲取當(dāng)前目錄
dir, err := os.Getwd()
fmt.Println(dir, err)
file := dir + "/new"
var fh *os.File
fi, _ := os.Stat(file)
if fi == nil {
fh, _ = os.Create(file) // 文件不存在就創(chuàng)建
} else {
fh, _ = os.OpenFile(file, os.O_RDWR, 0666) // 文件存在就打開
}
w := []byte("hello go language" + time.Now().String())
n, err := fh.Write(w)
fmt.Println(n, err)
// 設(shè)置下次讀寫位置
ret, err := fh.Seek(0, 0)
fmt.Printf("%s %v %v\n","當(dāng)前文件指針位置", ret, err)
b := make([]byte, 128)
n, err = fh.Read(b)
fmt.Printf("%d %v %s\n",n, err, string(b))
fh.Close()
}
FileInfo用來描述一個(gè)文件對象。
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
func Stat(name string) (fi FileInfo, err error)
Stat返回描述文件的FileInfo。如果指定的文件對象是一個(gè)符號鏈接,返回的FileInfo描述該符號鏈接指向的文件的信息,本函數(shù)會嘗試跳轉(zhuǎn)該鏈接func Lstat(name string) (fi FileInfo, err error)
Lstat返回描述文件對象的FileInfo。如果指定的文件對象是一個(gè)符號鏈接,返回的FileInfo描述該符號鏈接的信息,本函數(shù)不會試圖跳轉(zhuǎn)該鏈接。
package main
import (
"os"
)
func main() {
file := "/home/user/hello.go"
fi, _ := os.Stat(file)
if fi == nil {
fh, _ := os.Create(file) // 文件不存在就創(chuàng)建
fh.Write([]byte("package main\nfunc main(){\n}\n"))
} else {
fh, _ := os.OpenFile(file, os.O_RDWR, 0666) // 文件存在就打開
fh.Write([]byte("package main\nfunc main(){\n}\n"))
}
}
bufio模塊通過對io模塊的封裝,提供了數(shù)據(jù)緩沖功能,能夠一定程度減少大塊數(shù)據(jù)讀寫帶來的開銷。
在bufio各個(gè)組件內(nèi)部都維護(hù)了一個(gè)緩沖區(qū),數(shù)據(jù)讀寫操作都直接通過緩存區(qū)進(jìn)行。當(dāng)發(fā)起一次讀寫操作時(shí),會首先嘗試從緩沖區(qū)獲取數(shù)據(jù);只有當(dāng)緩沖區(qū)沒有數(shù)據(jù)時(shí),才會從數(shù)據(jù)源獲取數(shù)據(jù)更新緩沖。
type Reader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int
lastRuneSize int
}
可以通過NewReader函數(shù)創(chuàng)建bufio.Reader對象,函數(shù)接收一個(gè)io.Reader作為參數(shù)。因此,bufio.Reader不能直接使用,需要綁定到某個(gè)io.Reader上。
func NewReader(rd io.Reader) *Reader
func NewReaderSize(rd io.Reader, size int) *Reader // 可以配置緩沖區(qū)的大小
相較于io.Reader,bufio.Reader提供了很多實(shí)用的方法,能夠更有效的對數(shù)據(jù)進(jìn)行讀取。bufio.Reader能夠?qū)eader進(jìn)行細(xì)粒度的操作:
A、Read,讀取n個(gè)byte數(shù)據(jù)
B、Discard,丟棄接下來n個(gè)byte數(shù)據(jù)
C、Peek,獲取當(dāng)前緩沖區(qū)內(nèi)接下來的n個(gè)byte,但不移動指針
D、Reset,清空整個(gè)緩沖區(qū)
func (b *Reader) Read(p []byte) (n int, err error)
func (b *Reader) Discard(n int) (discarded int, err error)
func (b *Reader) Peek(n int) ([]byte, error)
func (b *Reader) Reset(r io.Reader)
bufio.Reader還提供了多個(gè)更高抽象層次的方法對數(shù)據(jù)進(jìn)行簡單的結(jié)構(gòu)化讀取,如下:
A、ReadByte,讀取一個(gè)byte
B、ReadRune,讀取一個(gè)utf-8字符
C、ReadLine,讀取一行數(shù)據(jù),由’\n’分隔
D、ReadBytes,讀取一個(gè)byte列表
E、ReadString,讀取一個(gè)字符串
func (b *Reader) ReadByte() (byte, error)
func (b *Reader) ReadRune() (r rune, size int, err error)
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
func (b *Reader) ReadString(delim byte) (string, error)
bufio.Reader使用示例:
package main
import (
"strings"
"fmt"
"bufio"
)
func main() {
r := strings.NewReader("hello world !")
reader := bufio.NewReader(r)
bytes, _ := reader.Peek(5)
fmt.Printf("%s\n",bytes)
n, _ := reader.Read(bytes)
fmt.Println(n)
reader.Discard(1)
for {
str, err := reader.ReadString(byte(' '))
fmt.Println(str)
if err != nil {
return
}
}
}
// output
// hello
// 5
// world
// !
type Writer struct {
err error
buf []byte
n int
wr io.Writer
}
func NewWriter(w io.Writer) *Writer
func NewWriterSize(w io.Writer, size int) *Writer
創(chuàng)建Writer對象的接口
func (b *Writer) Write(p []byte) (nn int, err error) // 寫入n byte數(shù)據(jù)
func (b *Writer) Reset(w io.Writer) // 重置當(dāng)前緩沖區(qū)
func (b *Writer) Flush() error // 清空當(dāng)前緩沖區(qū),將數(shù)據(jù)寫入輸出
func (b *Writer) WriteByte(c byte) error // 寫入一個(gè)字節(jié)
func (b *Writer) WriteRune(r rune) (size int, err error) // 寫入一個(gè)字符
func (b *Writer) WriteString(s string) (int, error) // 寫入一個(gè)字符串
func (b *Writer) Available() int // 緩存中有多少字節(jié)空間可用
func (b *Writer) Buffered() int // 當(dāng)前緩存已經(jīng)寫入了多少字節(jié)
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) // 實(shí)現(xiàn)io.ReaderFrom
type ReadWriter struct {
*Reader
*Writer
}
ReadWriter實(shí)現(xiàn)了io.ReadWriter。func NewReadWriter(r *Reader, w *Writer) *ReadWriter
ReadWriter對象創(chuàng)建
type Scanner struct {
r io.Reader // The reader provided by the client.
split SplitFunc // The function to split the tokens.
maxTokenSize int // Maximum size of a token; modified by tests.
token []byte // Last token returned by split.
buf []byte // Buffer used as argument to split.
start int // First non-processed byte in buf.
end int // End of data in buf.
err error // Sticky error.
empties int // Count of successive empty tokens.
scanCalled bool // Scan has been called; buffer is in use.
done bool // Scan has finished.
}
工程開發(fā)中推薦使用Scanner對數(shù)據(jù)進(jìn)行讀取,而非直接使用Reader類。Scanner可以通過splitFunc將輸入數(shù)據(jù)拆分為多個(gè)token,然后依次進(jìn)行讀取。func NewScanner(r io.Reader) *Scanner
創(chuàng)建scanner對象func (s *Scanner) Split(split SplitFunc)
設(shè)置scanner的分割函數(shù)。
在使用scanner前還需要設(shè)置splitFunc(默認(rèn)為ScanLines),splitFunc用于將輸入數(shù)據(jù)拆分為多個(gè)token。bufio模塊提供了幾個(gè)默認(rèn)splitFunc,能夠滿足大部分場景的需求,包括:
A、ScanBytes,按照byte進(jìn)行拆分
B、ScanLines,按照行(“\n”)進(jìn)行拆分
C、ScanRunes,按照utf-8字符進(jìn)行拆分
D、ScanWords,按照單詞(” “)進(jìn)行拆分
通過Scanner的Split方法,可以為Scanner指定splitFunc。使用方法如下:
scanner := bufio.NewScanner(os.StdIn)
scanner.split(bufio.ScanWords)
設(shè)置分割方式type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)是輸入數(shù)據(jù),第二個(gè)參數(shù)是一個(gè)標(biāo)識位,用于標(biāo)識當(dāng)前數(shù)據(jù)是否為結(jié)束。函數(shù)返回三個(gè)參數(shù),第一個(gè)是本次split操作的指針偏移;第二個(gè)是當(dāng)前讀取到的token;第三個(gè)是返回的錯(cuò)誤信息。
func (s *Scanner) Scan() bool
func (s *Scanner) Text() string
func (s *Scanner) Bytes() []byte
在完成Scanner初始化后,通過Scan方法可以在輸入中向前讀取一個(gè)token,讀取成功返回True;使用Text和Bytes方法獲取token,Text返回一個(gè)字符串,Bytes返回字節(jié)數(shù)組。
Scanner使用示例:
package main
import (
"strings"
"fmt"
"bufio"
)
func main() {
scanner := bufio.NewScanner(strings.NewReader("hello world !"))
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
// output
// hello
// world
// !
ioutil提供了對io包的封裝函數(shù)。
func ReadAll(r io.Reader) ([]byte, error)
ReadAll讀取r中的所有數(shù)據(jù)
返回讀取的數(shù)據(jù)和讀取過程中遇到的任何錯(cuò)誤。如果讀取成功,則err返回nil,而不是EOF。
s := strings.NewReader("Hello World!")
ra, _ := ioutil.ReadAll(s)
fmt.Printf("%s", ra)
// Hello World!
func ReadFile(filename string) ([]byte, error)
ReadFile讀取文件中的所有數(shù)據(jù),返回讀取的數(shù)據(jù)和讀取過程中遇到的任何錯(cuò)誤。如果讀取成功,則err返回nil,而不是EOF。
content, err := ioutil.ReadFile("/home/user/hello.txt")
if err != nil {
log.Fatal(err)
}
fmt.Printf("File contents: %s", content)
func WriteFile(filename string, data []byte, perm os.FileMode) error
WriteFile向文件filename中寫入數(shù)據(jù)data,如果文件不存在,則以perm權(quán)限創(chuàng)建該文件;如果文件存在,則先清空文件,然后再寫入。返回寫入過程中遇到的任何錯(cuò)誤。
filename := "/home/user/hello.txt"
data := []byte("Hello World!")
ioutil.WriteFile(filename, data, os.ModeAppend)
contents, _ := ioutil.ReadFile(filename)
fmt.Printf("%s", contents)
// Hello World!
func ReadDir(dirname string) ([]os.FileInfo, error)
ReadDir讀取目錄dirmane中的所有目錄和文件(不包括子目錄)
返回讀取到的文件的信息列表和讀取過程中遇到的任何錯(cuò)誤,返回的文件列表是經(jīng)過排序的。
rd, err := ioutil.ReadDir("/home/user")
for _, fi := range rd {
fmt.Println("")
fmt.Println(fi.Name())
fmt.Println(fi.IsDir())
fmt.Println(fi.Size())
fmt.Println(fi.ModTime())
fmt.Println(fi.Mode())
}
fmt.Println("")
fmt.Println(err)
func TempDir(dir, prefix string) (name string, err error)
TempDir功能同TempFile,只不過創(chuàng)建的是目錄,返回值也只返目錄的完整路徑。
content := []byte("temporary file's content")
dir, err := ioutil.TempDir("/home/user", "example")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir) // clean up
tmpfn := filepath.Join(dir, "tmpfile")
if err := ioutil.WriteFile(tmpfn, content, 0666); err != nil {
log.Fatal(err)
}
func TempFile(dir, prefix string) (f *os.File, err error)
TempFile在目錄dir中創(chuàng)建一個(gè)臨時(shí)文件并將其打開,文件名以prefix為前綴
返回創(chuàng)建的文件的對象和創(chuàng)建過程中遇到的任何錯(cuò)誤
如果dir為空,則在系統(tǒng)的臨時(shí)目錄中創(chuàng)建臨時(shí)文件
如果環(huán)境變量中沒有設(shè)置系統(tǒng)臨時(shí)目錄,則在/tmp中創(chuàng)建臨時(shí)文件
調(diào)用者可以通過f.Name()方法獲取臨時(shí)文件的完整路徑
調(diào)用TempFile所創(chuàng)建的臨時(shí)文件,應(yīng)該由調(diào)用者自己移除
content := []byte("temporary file's content")
tmpfile, err := ioutil.TempFile("/home/user", "example")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name()) // clean up
if _, err := tmpfile.Write(content); err != nil {
log.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
log.Fatal(err)
}
var Discard io.Writer = devNull(0)
Discard是一個(gè)io.Writer,對它進(jìn)行的任何Write調(diào)用都將無條件成功。devNull優(yōu)化的實(shí)現(xiàn)ReadFrom,因此io.Copy到ioutil.Discard避免不必要的工作,因此其一定會成功。但是ioutil.Discard不記錄copy得到的數(shù)值。
a := strings.NewReader("hello")
p := make([]byte, 20)
io.Copy(ioutil.Discard, a)
ioutil.Discard.Write(p)
fmt.Println(p)
//[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
func NopCloser(r io.Reader) io.ReadCloser
ReadCloser接口組合了基本的Read和Close方法。NopCloser將提供的 Reader r用空操作Close方法包裝后作為ReadCloser返回。
s := strings.NewReader("hello world!")
r := ioutil.NopCloser(s)
r.Close()
p := make([]byte, 10)
r.Read(p)
fmt.Println(string(p))
//hello worl
bytes包提供了對字節(jié)切片進(jìn)行讀寫操作的一系列函數(shù)。?字節(jié)切片處理的函數(shù)比較多,分為基本處理函數(shù)、比較函數(shù)、后綴檢查函數(shù)、索引函數(shù)、分割函數(shù)、大小寫處理函數(shù)和子切片處理函數(shù)等。
strings與bytes的函數(shù)接口功能基本一致。
func Contains(b,subslice []bytes) bool
檢查字節(jié)切片b是否包含子切片subslice,如果包含返回true,否則返回false。func Count(s,sep []byte) int
計(jì)算字節(jié)切片sep在字節(jié)切片s中非重疊顯示的個(gè)數(shù)。func Repeat(b[]byte,count int) []byte
把切片b復(fù)制count個(gè),然后合成一個(gè)新的字節(jié)切片返回。func Replace(s,old,new []byte,n int) []byte
返回字節(jié)切片s的一個(gè)副本,并把前n個(gè)不重疊的子切片old替換為new;如果n小于0,則不限制替換的數(shù)量。參數(shù)n為替換的次數(shù)。
func Runes(s []byte) []rune
把s轉(zhuǎn)換為UTF-8編碼的字節(jié)序列,并返回對應(yīng)的Unicode切片func Join(s [][]byte,sep[]byte) []byte
用字節(jié)切片sep把s中的每個(gè)字節(jié)切片連成一個(gè)字節(jié)切片并返回。
基本函數(shù)示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//Contains
b := []byte("hello") //字符串強(qiáng)轉(zhuǎn)為byte切片
sublice1 := []byte("h")
sublice2 := []byte("l")
fmt.Println(bytes.Contains(b,sublice1))// true
fmt.Println(bytes.Contains(b,sublice2))// false
//Count
s := []byte("hello world")
sep1 := []byte("ll")
sep2 := []byte("l")
sep3 := []byte("o")
fmt.Println(bytes.Count(s,sep1))// 1
fmt.Println(bytes.Count(s,sep2))// 3
fmt.Println(bytes.Count(s,sep3))// 2
//Repeat
b = []byte("hello world")
fmt.Println(string(bytes.Repeat(b,1)))// hello world
fmt.Println(string(bytes.Repeat(b,2)))// hello worldhello world
//Replace
s = []byte("hello,world")
old := []byte("o")
news := []byte("ee")
fmt.Println(string(bytes.Replace(s,old,news,0)))//hello,world
fmt.Println(string(bytes.Replace(s,old,news,1)))//hellee,world
fmt.Println(string(bytes.Replace(s,old,news,2)))//hellee,weerld
fmt.Println(string(bytes.Replace(s,old,news,-1)))//hellee,weerld
//Runes
s = []byte("你好世界")
r := bytes.Runes(s)
fmt.Println("轉(zhuǎn)換前字符串的長度: ",len(s))//12
fmt.Println("轉(zhuǎn)換后字符串的長度: ",len(r))//4
//Join
ss := [][]byte{[]byte("你好"),[]byte("世界")}
sep4 := []byte(",")
fmt.Println(string(bytes.Join(ss,sep4)))//你好,世界
sep5 := []byte("#")
fmt.Println(string(bytes.Join(ss,sep5)))//你好#世界
}
func Compare(a,b[]byte) int
根據(jù)字節(jié)的值比較字節(jié)切片a和b的大小,如果a=b,返回0,如果a>b返回1,如果a小于b返回-1。func Equal(a,b[]byte) bool
比較2個(gè)字節(jié)切片是否相等,如果參數(shù)為nil,則等同于空的字節(jié)切片,如果a=b,則返回true,否則返回false.區(qū)分大小寫。func EqualFold(s,t[]byte) bool
把s和t轉(zhuǎn)換成UTF-8字符串進(jìn)行比較,并且忽略大小寫,如果s=t,返回true,否則,返回false。
比較函數(shù)示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//Compare
a := []byte("hello,go")
b := []byte("hello,world")
fmt.Println(bytes.Compare(a,b))//-1
b =[]byte("hello,c")
fmt.Println(bytes.Compare(a,b))//1
b =[]byte("hello,World")
fmt.Println(bytes.Compare(a,b))//1 小寫字母大于大寫字母
b =[]byte("b")
fmt.Println(bytes.Compare(a,b))//-1 從第一個(gè)字節(jié)開始比較,如果相同再比較長度
//Equal
a = []byte("abc")
b = []byte("ABC")
fmt.Println(bytes.Equal(a,b))//false
fmt.Println(bytes.Equal(a,nil))//false
b = []byte("abc")
fmt.Println(bytes.Equal(a,b))//true
//EqualFold
a = []byte("abc")
b = []byte("ABC")
fmt.Println(bytes.EqualFold(a,b))//true
}
func HasPrefix(s,prefix[]byte) bool
檢查字節(jié)切片s的前綴是否為prefix,如果是返回true,如果不是返回falsefunc HashSuffix(s,suffix[]byte) bool
檢查字節(jié)切片s的后綴是否為suffix,如果是返回true,否則返回false。
前后綴檢查示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//HasPrefix
s := []byte("test_Hello.txt")
prefix := []byte("test")
fmt.Println(bytes.HasPrefix(s,prefix))//true
prefix = []byte("Test")
fmt.Println(bytes.HasPrefix(s,prefix))//false
//HashSuffix
suffix := []byte("txt")
fmt.Println(bytes.HasSuffix(s,suffix))//true
}
字節(jié)切片位置索引函數(shù)共有8個(gè),Index()、IndexAny()、IndexByte()、IndexFunc()、IndexRune()、LastIndex()、LastIndexAny()和LastIndexFunc()。func Index(s,sep []byte) int
返回sep在s中第一次出現(xiàn)的位置索引(從0開始),如果sep中不在s中則返回-1func IndexAny(s []byte,chars string) int
把s解析為UTF-8編碼的字節(jié)序列,返回chars中任何一個(gè)字符在s中第一次出現(xiàn)的索引位置;如果s中不包含chars中任何一個(gè)字符,則返回-1func IndexByte(s[]byte,c byte) int
檢查字節(jié)c在s中第一次出現(xiàn)的位置索引;如果s中不包含c則返回-1func IndexFunc(s[]byte,f func(r rune)bool) int
把s解析為UTF-8字節(jié)序列,并返回一個(gè)滿足f(c)=true的字符c的位置索引,如果沒有滿足則返回-1func IndexRune(s[]byte,r rune) int
把s解析為UTF-8字節(jié)序列,并返回rune類型的字符r在s中的位置索引,如果s中不包含r則返回-1func LastIndex(s,sep[]byte) int
返回sep在s中最后一次出現(xiàn)的位置索引,如果s中不包含sep,則返回-1func LastIndexAny(s[]byte,chars string) int
把s解析為UTF-8字節(jié)序列,返回chars中任何一個(gè)字符在s中最后
出現(xiàn)的位置索引,如果chars為空或者s中不包含chars中的任意字符,則返回-1func LastIndexFunc(s[]byte,f func(r rune)bool) int
把s解析成UTF-8字節(jié)序列,返回滿足f(s)=true的字符c在s中最后
一次出現(xiàn)的位置索引,如果沒有找到則返回-1
位置索引示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//Index
a := []byte("hello,world")
fmt.Println(bytes.Index(a,[]byte("o")))//4
fmt.Println(bytes.Index(a,[]byte("ll")))//2
fmt.Println(bytes.Index(a,[]byte("w")))//6
//IndexAny
fmt.Println(bytes.IndexAny(a,"h"))//0
fmt.Println(bytes.IndexAny(a,"l"))//2
//IndexByte
s := []byte("hello,world")
var ch byte = 'w'
fmt.Println(bytes.IndexByte(s,ch))//6
//IndexFunc,可以接收匿名函數(shù)
fmt.Println(bytes.IndexFunc(s,func (a rune)bool{
if a == 'o'{
return true
}else{
return false
}
}))//4
//IndexRune
fmt.Println(bytes.IndexRune(s,'e'))//1
fmt.Println(bytes.IndexRune(s,'a'))//-1
//LastIndex
fmt.Println(bytes.LastIndex(s,[]byte("g")))//-1
fmt.Println(bytes.LastIndex(s,[]byte("e")))//1
fmt.Println(bytes.LastIndex(s,[]byte("o")))//7
//LastIndexAny
fmt.Println(bytes.LastIndexAny(s,"world"))//10
fmt.Println(bytes.LastIndexAny(s,"l"))//9
fmt.Println(bytes.LastIndexAny(s,"d"))//10
//LastIndexFunc
fmt.Println(bytes.LastIndexFunc(s,func(r rune)bool{
if r=='d'{
return true
}else {
return false
}
}))//10
}
字節(jié)切片分割函數(shù)共有6個(gè),Fields(),FieldsFunc(),Split(),SplitN(),?
SplitAfter()和SplitAfterN()。func Fields(s[]byte) [][]byte
把字節(jié)切片s按照一個(gè)或者連續(xù)多個(gè)空白字符分割成多個(gè)字節(jié)切片,如果s只包含空白字符則返回空字節(jié)切片,其中參數(shù)s準(zhǔn)備分割的字節(jié)切片func FieldsFunc(s []byte,f func(r rune)bool) [][]byte
把s解析為UTF-8字節(jié)序列,對于每個(gè)Unicode字符c,如果f(c)返回true就把c作為分割字符對s進(jìn)行拆分。如果所有字符都滿足f(c)為true,則返回空切片func Split(s,sep[]byte)[][]byte
把s用sep分割成多個(gè)字節(jié)切片并返回,如果sep為空,Split則把s切分成每個(gè)字節(jié)切片對應(yīng)一個(gè)UTF-8字符,Split()等效于參數(shù)為n的splitN()函數(shù)。func SplitAfter(s,sep[]byte)[][]byte
使用sep作為后綴把s切分成多個(gè)字節(jié)切片并返回。如果sep為空,則把s切分成每個(gè)字節(jié)切片對應(yīng)一個(gè)UTF-8字符。func SplitAfterN(s,sep[]byte,n int)[][]byte
用sep作為后綴把s切分成多個(gè)字節(jié)切片并返回。如果sep為空,則把s切分成每個(gè)字節(jié)切片對應(yīng)一個(gè)UTF-8字符。參數(shù)n決定返回切片的長度:如果n>0,最多返回n個(gè)子字節(jié)切片,子切片可能包含未切分的字節(jié)序列;如果n=0,返回空切片;如果n< 0,返回所有子切片。func SplitN(s,sep []byte,n int)[][]byte
把s用sep分割成多個(gè)字節(jié)切片并返回,如果sep為空,Split則把s切分成每個(gè)字節(jié)切片對應(yīng)一個(gè)UTF-8字符,參數(shù)n決定返回長度,n>0最多返回n個(gè)子切片;n==0返回返回空切片,n小于0返回所有子切片。
分割函數(shù)示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//Fields ,返回的是2維切片
s := []byte("hello world")
for _,v := range bytes.Fields(s){
//遍歷獲取1維切片,再強(qiáng)轉(zhuǎn)為字符串
fmt.Print(string(v)+",") // hello,world,
}
fmt.Println()
//FieldsFunc,返回是2維切片,接收匿名函數(shù)
s = []byte("hello,world")
for _,v := range bytes.FieldsFunc(s,func(r rune)bool{
if r == ','{
return true //按照空白字符分割
}else{
return false
}
}){
fmt.Print(string(v)+",")// hello,world,
}
fmt.Println()
//Split
s = []byte("天山老妖")
for _,v := range bytes.Split(s,[]byte("山")){
fmt.Print(string(v)+",")//天,老妖,
}
fmt.Println()
for _,v := range bytes.Split(s,nil){
fmt.Print(string(v)+",")//天,山,老,妖,
}
fmt.Println()
//SplitAfter
for _,v := range bytes.SplitAfter(s,[]byte("山")){
fmt.Print(string(v)+",")//天山,老妖,
}
fmt.Println()
for _,v := range bytes.SplitAfter(s,nil){
fmt.Print(string(v)+",")//天,山,老,妖,
}
fmt.Println()
//SplitAfterN
s = []byte("hello,world,hello,go")
for _,v := range bytes.SplitAfterN(s,[]byte(","),0){
fmt.Print(string(v)+",") //什么都不輸出
}
fmt.Println()
for _,v := range bytes.SplitAfterN(s,[]byte(","),4){
fmt.Print(string(v))//hello,world,hello,go
}
fmt.Println()
for _,v := range bytes.SplitAfterN(s,[]byte(""),-1){
fmt.Print(string(v))//hello,world,hello,go
}
fmt.Println()
//SplitN
s = []byte("hello,world")
for _,v := range bytes.SplitN(s,[]byte("he"),0){
fmt.Print(string(v)+",") //
}
fmt.Println()
for _,v := range bytes.SplitN(s,[]byte("o"),3){
fmt.Print(string(v) + ",")//hell,,w,rld,
}
fmt.Println()
for _,v := range bytes.SplitN(s,[]byte("ll"),-1){
fmt.Print(string(v)+",")//he,o,world,
}
}
共有7個(gè)函數(shù),Title(),ToTitle(),ToTitleSpecial(),ToLower(),ToLowerSpecial(),ToUpper()?和ToUpperSpecial()。
func Title(s[]byte) []byte
返回一個(gè)s的副本,把s中每個(gè)單詞的首字母改成Unicode字符大寫
func ToTitle(s []byte) []byte
返回s的一個(gè)副本,并把其中所有Unicode字符轉(zhuǎn)為大寫func ToTitleSpecial(_case unicode.SpecialCase,s []byte) []byte
返回s的一個(gè)副本,并把其中所有Unicode字符根據(jù)_case指定的規(guī)則轉(zhuǎn)成大寫func ToLower(s []byte)[]byte
返回s的一個(gè)副本,并把其中的所有Unicode字符轉(zhuǎn)為小寫func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte
返回s的一個(gè)副本,并把其中所有Unicode字符根據(jù)_case定的規(guī)則轉(zhuǎn)換成小寫func ToUpper(s []byte) []byte
返回s的一個(gè)副本,并把其中所有Unicode字符都轉(zhuǎn)為大寫func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte
返回s的一個(gè)副本,并把其中所有Unicode字符都根據(jù)_case
指定的規(guī)則轉(zhuǎn)成大寫
大小寫處理函數(shù)示例:
package main
import (
"fmt"
"bytes"
"unicode"
)
func main() {
s := []byte("hello,go")
fmt.Println(string(bytes.Title(s)))// Hello,Go
fmt.Println(string(bytes.ToTitle(s)))// HELLO,GO
fmt.Println(string(bytes.ToTitleSpecial(unicode.AzeriCase,s)))// HELLO,GO
s = []byte("Hello,Go")
fmt.Println(string(bytes.ToLower(s)))// hello,go
fmt.Println(string(bytes.ToLowerSpecial(unicode.AzeriCase,s)))// hello,go
s = []byte("Hello,Go")
fmt.Println(string(bytes.ToUpper(s)))// HELLO,GO
fmt.Println(string(bytes.ToUpperSpecial(unicode.AzeriCase,s)))// HELLO,GO
}
子字節(jié)切片處理函數(shù)共有9個(gè),Trim(),TrimFunc(),TrimLeft(),TrimLeftFunc(),TrimRight(),TrimRightFunc(),TrimSpace(),TrimPrefix()和TrimSuffix()。func Trim(s []byte, cutset string) []byte
返回s的子字節(jié)切片,cutset中任意出現(xiàn)在s的首部和尾部的連續(xù)字符將被刪除。func TrimFunc(s []byte, f func(r rune) bool) []byte
返回s的子字節(jié)切片,刪除s首部和尾部連接的滿足f(c)=true的字符c。func TrimLeft(s []byte, cutset string) []byte
返回s的子字節(jié)切片,cutset中任意出現(xiàn)在s首部的連續(xù)字符被刪除。func TrimLeftFunc(s []byte, f func(r rune) bool) []byte
返回s的一個(gè)子字節(jié)切片、刪除s首部連續(xù)滿足f(c)=true的字符c。func TrimRight(s []byte, cutset string) []byte
返回s的子字節(jié)切片,cutset中任意出現(xiàn)在s尾部的連續(xù)字符被刪除。func TrimRightFunc(s []byte, f func(r rune) bool) []byte
返回s的一個(gè)子字節(jié)切片、刪除s尾部連續(xù)滿足f(c)=true的字符cfunc TrimSpace(s []byte) []byte
返回s的一個(gè)子字節(jié)切片,并刪除s中開始和結(jié)尾處的連續(xù)的Unicode空白字符。func TrimPrefix(s, prefix []byte) []byte
返回s的一個(gè)子字節(jié)切片,并刪除前綴為prefix的部分func TrimSuffix(s, suffix []byte) []byte
返回s的一個(gè)子字節(jié)切片,并刪除后綴為suffix的部分
子字節(jié)切片處理函數(shù)示例:
package main
import (
"fmt"
"bytes"
)
func main() {
//Trim
s := []byte(" Hello,Go ")
fmt.Println(string(bytes.Trim(s," ")))// Hello,Go
//TrimFunc
s = []byte("hello world")
fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{
if r=='h' || r=='d'{
return true
}else{
return false
}
}))) //ello worl
s = []byte("hello,worldo")
fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{
if r=='h' || r=='o'{
return true
}else{
return false
}
}))) // ello,world
s = []byte("hello,world")
fmt.Println(string(bytes.TrimFunc(s,func(r rune)bool{
if r=='h' && r=='o'{
return true
}else{
return false
}
}))) // hello,world
//TrimLeft
fmt.Println(string(bytes.TrimLeft(s,"h")))// ello,world
fmt.Println(string(bytes.TrimLeft(s,"l")))// hello,world
//TrimLeftFunc
fmt.Println(string(bytes.TrimLeftFunc(s,func(r rune)bool{
if r == 'h' || r=='l'{
return true
}else{
return false
}
}))) // ello,world
//TrimRight
fmt.Println(string(bytes.TrimRight(s,"d")))// hello,worl
//TrimRightFunc
fmt.Println(string(bytes.TrimRightFunc(s,func(r rune)bool{
if r == 'd'{
return true
}else{
return false
}
})))// hello,worl
//TrimSpace
s = []byte(" hello world ")
fmt.Println(string(bytes.TrimSpace(s)))// hello world
//TrimPrefix
s = []byte("test_Go")
fmt.Println(string(bytes.TrimPrefix(s,[]byte("test_"))))// Go
fmt.Println(string(bytes.TrimPrefix(s,[]byte("Test"))))// test_Go
//TrimSuffix
s = []byte("hello.go")
fmt.Println(string(bytes.TrimSuffix(s,[]byte(".go"))))// hello
fmt.Println(string(bytes.TrimSuffix(s,[]byte(".cpp"))))// hello.go
}
path實(shí)現(xiàn)了對斜杠分隔的路徑進(jìn)行操作的函數(shù)。
filepath包實(shí)現(xiàn)了兼容各操作系統(tǒng)的文件路徑操作函數(shù)
func IsAbs(path string) bool
判斷是否是一個(gè)絕對路徑func Split(path string) (dir, file string)
將路徑分割為路徑和文件名func Join(elem ...string) string
將多個(gè)字符串合并為一個(gè)路徑func Ext(path string) string
返回路徑中擴(kuò)展部分func Base(path string) string
返回路徑的最后一個(gè)元素func Dir(path string) string
返回路徑中目錄部分func Clean(path string) string
返回同目錄的最短路徑func Match(pattern, name string) (matched bool, err error)
正則是否匹配路徑(shell文件名匹配)
package main
import (
"fmt"
"path"
)
func main() {
pt := "~/GoLang"
// 判斷是否是一個(gè)絕對路徑
is_abs := path.IsAbs(pt)
fmt.Println(is_abs) // false
// 將路徑分割為路徑和文件名
pf := "/home/user/hello.go"
dir, file := path.Split(pf)
fmt.Println(dir, file) // /home/user/ hello.go
// 將多個(gè)字符串合并為一個(gè)路徑
dir_join := path.Join("usr", "local", "bin")
fmt.Println(dir_join) // usr/local/bin
// 返回路徑中擴(kuò)展
file_ext := path.Ext(pf)
fmt.Println(file_ext) // .go
// 返回路徑的最后一個(gè)元素
dir_base := path.Base(pf)
fmt.Println(dir_base) // hello.go
// 返回路徑中目錄部分
dir = path.Dir(pf)
fmt.Println(dir) // /home/user
// 返回同目錄的最短路徑
dir_a := "/usr/../opt/../home/user"
fmt.Println(path.Clean(dir_a)) // /home/user
// 正則是否匹配路徑
is_match, err := path.Match("*.xml", "a.xml")
fmt.Println(is_match, err) // true <nil>
}
filepath.Separator
預(yù)定義變量,表示路徑分隔符 /filepath.ListSeparator
預(yù)定義變量,表示環(huán)境變量分隔符 :func Abs(path string) (string, error)
返回path相對當(dāng)前路徑的絕對路徑func Clean(path string) string
返path的最短路徑func Rel(basepath, targpath string) (string, error)
返回targpath相對 basepath路徑func EvalSymlinks(path string) (string, error)
返回軟鏈指向的路徑func VolumeName(path string) string
返回路徑最前面的卷名func ToSlash(path string) string
路徑分隔符替換為 /func FromSlash(path string) string
/ 替換為路徑分隔符func SplitList(path string) []string
分隔環(huán)境變量里面的路徑func Walk(root string, walkFn WalkFunc) error
遍歷root目錄下的文件樹,并調(diào)用walkFn
package main
import (
"fmt"
"os"
"path/filepath"
)
// 打印路徑名稱
func pathName(path string, info os.FileInfo, err error) error {
if err != nil {
return err
} else {
fmt.Println(path)
}
return nil
}
func main() {
// 預(yù)定義變量
fmt.Println(string(filepath.Separator), string(filepath.ListSeparator))
// 返回path 相對當(dāng)前路徑的絕對路徑
dir := "/home/user/hello.go"
real_dir, err := filepath.Abs(dir)
fmt.Println(real_dir, err)
// 返回path 的最短路徑
dir = "/usr/../etc/../tmp"
clear_dir := filepath.Clean(dir)
fmt.Println(clear_dir) // /tmp
// 返回targpath 相對 basepath路徑
basepath, targpath := "/usr/local", "/usr/local/go/bin"
rel_dir, err := filepath.Rel(basepath, targpath)
fmt.Println(rel_dir, err) // go/bin <nil>
// 返回軟鏈指向的路徑
symlink := "/usr/local"
real_dir, err = filepath.EvalSymlinks(symlink)
fmt.Println(real_dir, err) // /usr/local <nil>
// 返回路徑最前面的卷名
root := "/usr/local/go"
vol := filepath.VolumeName(root)
fmt.Println(vol) // ''
// 路徑分隔符替換為 `/`
slash_dir := filepath.ToSlash(root)
fmt.Println(slash_dir) // /usr/local/go
// `/` 替換為路徑分隔符
from_slash := filepath.FromSlash(slash_dir)
fmt.Println(from_slash) // /usr/local/go
// 分隔環(huán)境變量里面的路徑
env_path := "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/go/bin"
env_slice := filepath.SplitList(env_path)
for k, v := range env_slice {
fmt.Println(k, v)
}
// 0 /usr/local/bin
// 1 /usr/bin
// 2 /bin
// 3 /usr/sbin
// 4 /sbin
// 5 /opt/X11/bin
// 6 /usr/local/go/bin
// 遍歷 root 目錄下的文件樹,并調(diào)用 walkFn
root_dir, err := os.Getwd()
err = filepath.Walk(root_dir, pathName)
fmt.Println(err)
}
Walk(root stirng, walkFn WalkFunc) error
// 參數(shù)root可以是文件名也可以是目錄名;walkFn是自定義的函數(shù)
func Walk(root string, walkFn WalkFunc) error {
//獲取root的描述信息
info, err := os.Lstat(root)
if err != nil {
//如果獲取描述信息發(fā)生錯(cuò)誤,返回err由定義的walkFn函數(shù)處理
err = walkFn(root, nil, err)
} else {
//調(diào)用walk(root, info, walkFn)函數(shù)進(jìn)行遞歸遍歷root
err = walk(root, info, walkFn)
}
if err == SkipDir {
return nil
}
return err
}
Walk方法會遍歷root下的所有文件(包含root)并對每一個(gè)目錄和文件都調(diào)用walkFunc方法。在訪問文件和目錄時(shí)發(fā)生的錯(cuò)誤都會通過error參數(shù)傳遞給WalkFunc方法。文件是按照詞法順序進(jìn)行遍歷的,通常讓輸出更漂亮,但也會導(dǎo)致處理非常大的目錄時(shí)效率會降低。另外,Walk函數(shù)不會遍歷符號鏈接。type WalkFunc func(path string, info os.FileInfo, err error)?
WalkFunc是一個(gè)方法類型,Walk函數(shù)在遍歷文件或者目錄時(shí)調(diào)用。調(diào)用時(shí)將參數(shù)傳遞給path,將Walk函數(shù)中的root作為前綴。將root + 文件名或者目錄名作為path傳遞給WalkFunc函數(shù)。例如在"dir"目錄下遍歷到"a"文件,則path="dir/a";Info是path所指向文件的文件信息。如果在遍歷過程中出現(xiàn)了問題,傳入?yún)?shù)err會描述這個(gè)問題。WalkFunc函數(shù)可以處理這個(gè)問題,Walk將不會再深入該目錄。如果函數(shù)會返回一個(gè)錯(cuò)誤,Walk函數(shù)會終止執(zhí)行;只有一個(gè)例外,我們也通常用這個(gè)來跳過某些目錄。當(dāng)WalkFunc的返回值是filepaht.SkipDir時(shí),Walk將會跳過這個(gè)目錄,照常執(zhí)行下一個(gè)文件。
func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
//調(diào)用定義的walkFn自定義函數(shù)處理
err := walkFn(path, info, nil)
if err != nil {
//返回錯(cuò)誤,且該目錄可以跳過
if info.IsDir() && err == SkipDir {
return nil
}
return err
}
//如果是文件,則遍歷下一個(gè)
if !info.IsDir() {
return nil
}
//讀取該path下的所有目錄和文件
names, err := readDirNames(path)
if err != nil {
//發(fā)生錯(cuò)誤,調(diào)用自定義函數(shù)處理
return walkFn(path, info, err)
}
//遍歷文件和目錄列表
for _, name := range names {
//路徑path/name
filename := Join(path, name)
//獲取該文件或者目錄信息
fileInfo, err := lstat(filename)
if err != nil {
//發(fā)生錯(cuò)誤,調(diào)用自定義函數(shù)處理
if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
return err
}
} else {
//這里遞歸調(diào)用,獲取root下各級文件和目錄信息,在自定義函數(shù)walkFn里做處理
err = walk(filename, fileInfo, walkFn)
if err != nil {
//遍歷文件發(fā)生錯(cuò)誤或者目錄發(fā)生錯(cuò)誤且不能跳過,則返回err
if !fileInfo.IsDir() || err != SkipDir {
return err
}
}
}
}
return nil
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。