os 包提供了不依賴平臺的操做系統函數接口,設計像Unix風格,但錯誤處理是go風格,當os包使用時,若是失敗後返回錯誤類型而不是錯誤數量。shell
func Hostname() (name string, err error) // Hostname返回內核提供的主機名 func Environ() []string // Environ返回表示環境變量的格式爲」key=value」的字符串的切片拷貝 func Getenv(key string) string // Getenv檢索並返回名爲key的環境變量的值 func Getpid() int // Getpid返回調用者所在進程的進程ID func Exit(code int) // Exit讓當前程序以給出的狀態碼code退出。通常來講,狀態碼0表示成功,非0表示出錯。程序會馬上終止,defer的函數不會被執行 func Stat(name string) (fi FileInfo, err error) // 獲取文件信息 func Getwd() (dir string, err error) // Getwd返回一個對應當前工做目錄的根路徑 func Mkdir(name string, perm FileMode) error // 使用指定的權限和名稱建立一個目錄 func MkdirAll(path string, perm FileMode) error // 使用指定的權限和名稱建立一個目錄,包括任何須要的上級目錄,並返回nil,不然返回錯誤 func Remove(name string) error // 刪除name指定的文件或目錄 func TempDir() string // 返回一個用於保管臨時文件的默認目錄 var Args []string // os.Args返回一個字符串數組,其中第一個參數就是執行文件自己
os示例:數組
package main import ( "fmt" "os" ) func main() { // 預約義變量, 保存命令行參數 fmt.Println(os.Args) // 獲取host name fmt.Println(os.Hostname()) fmt.Println(os.Getpid()) // 獲取所有環境變量 env := os.Environ() for k, v := range env { fmt.Println(k, v) } // 終止程序 // os.Exit(1) // 獲取一條環境變量 fmt.Println(os.Getenv("PATH")) // 獲取當前目錄 dir, err := os.Getwd() fmt.Println(dir, err) // 建立目錄 err = os.Mkdir(dir+"/new_file", 0755) fmt.Println(err) // 建立目錄 err = os.MkdirAll(dir+"/new", 0755) fmt.Println(err) // 刪除目錄 err = os.Remove(dir + "/new_file") err = os.Remove(dir + "/new") fmt.Println(err) // 建立臨時目錄 tmp_dir := os.TempDir() fmt.Println(tmp_dir) }
func Create(name string) (file *File, err error) // Create採用模式0666建立一個名爲name的文件,若是文件已存在會截斷(爲空文件) func Open(name string) (file *File, err error) // Open打開一個文件用於讀取。若是操做成功,返回的文件對象的方法可用於讀取數據 func (f *File) Stat() (fi FileInfo, err error) // Stat返回描述文件f的FileInfo類型值 func (f *File) Readdir(n int) (fi []FileInfo, err error) // Readdir讀取目錄f的內容,返回一個有n個成員的[]FileInfo func (f *File) Read(b []byte) (n int, err error) // Read方法從f中讀取最多len(b)字節數據並寫入b func (f *File) WriteString(s string) (ret int, err error) // 向文件中寫入字符串 func (f *File) Sync() (err error) // Sync遞交文件的當前內容進行穩定的存儲 func (f *File) Close() error // Close關閉文件f,使文件不能用於讀寫
File示例:緩存
package main import ( "fmt" "os" "time" ) func main() { // 獲取當前目錄 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) // 文件不存在就建立 } 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) // 設置下次讀寫位置 ret, err := fh.Seek(0, 0) fmt.Printf("%s %v %v\n","當前文件指針位置", ret, err) b := make([]byte, 128) n, err = fh.Read(b) fmt.Printf("%d %v %s\n",n, err, string(b)) fh.Close() }
FileInfo用來描述一個文件對象。ide
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。若是指定的文件對象是一個符號連接,返回的FileInfo描述該符號連接指向的文件的信息,本函數會嘗試跳轉該連接func Lstat(name string) (fi FileInfo, err error)
Lstat返回描述文件對象的FileInfo。若是指定的文件對象是一個符號連接,返回的FileInfo描述該符號連接的信息,本函數不會試圖跳轉該連接。函數
package main import ( "os" ) func main() { file := "/home/user/hello.go" fi, _ := os.Stat(file) if fi == nil { fh, _ := os.Create(file) // 文件不存在就建立 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模塊的封裝,提供了數據緩衝功能,可以必定程度減小大塊數據讀寫帶來的開銷。
在bufio各個組件內部都維護了一個緩衝區,數據讀寫操做都直接經過緩存區進行。當發起一次讀寫操做時,會首先嚐試從緩衝區獲取數據;只有當緩衝區沒有數據時,纔會從數據源獲取數據更新緩衝。優化
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函數建立bufio.Reader對象,函數接收一個io.Reader做爲參數。所以,bufio.Reader不能直接使用,須要綁定到某個io.Reader上。編碼
func NewReader(rd io.Reader) *Reader func NewReaderSize(rd io.Reader, size int) *Reader // 能夠配置緩衝區的大小
相較於io.Reader,bufio.Reader提供了不少實用的方法,可以更有效的對數據進行讀取。bufio.Reader可以對Reader進行細粒度的操做:
A、Read,讀取n個byte數據
B、Discard,丟棄接下來n個byte數據
C、Peek,獲取當前緩衝區內接下來的n個byte,但不移動指針
D、Reset,清空整個緩衝區操作系統
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還提供了多個更高抽象層次的方法對數據進行簡單的結構化讀取,以下:
A、ReadByte,讀取一個byte
B、ReadRune,讀取一個utf-8字符
C、ReadLine,讀取一行數據,由’\n’分隔
D、ReadBytes,讀取一個byte列表
E、ReadString,讀取一個字符串命令行
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
建立Writer對象的接口
func (b *Writer) Write(p []byte) (nn int, err error) // 寫入n byte數據 func (b *Writer) Reset(w io.Writer) // 重置當前緩衝區 func (b *Writer) Flush() error // 清空當前緩衝區,將數據寫入輸出 func (b *Writer) WriteByte(c byte) error // 寫入一個字節 func (b *Writer) WriteRune(r rune) (size int, err error) // 寫入一個字符 func (b *Writer) WriteString(s string) (int, error) // 寫入一個字符串 func (b *Writer) Available() int // 緩存中有多少字節空間可用 func (b *Writer) Buffered() int // 當前緩存已經寫入了多少字節 func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) // 實現io.ReaderFrom
type ReadWriter struct { *Reader *Writer }
ReadWriter實現了io.ReadWriter。func NewReadWriter(r *Reader, w *Writer) *ReadWriter
ReadWriter對象建立
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. }
工程開發中推薦使用Scanner對數據進行讀取,而非直接使用Reader類。Scanner能夠經過splitFunc將輸入數據拆分爲多個token,而後依次進行讀取。func NewScanner(r io.Reader) *Scanner
建立scanner對象func (s *Scanner) Split(split SplitFunc)
設置scanner的分割函數。
在使用scanner前還須要設置splitFunc(默認爲ScanLines),splitFunc用於將輸入數據拆分爲多個token。bufio模塊提供了幾個默認splitFunc,可以知足大部分場景的需求,包括:
A、ScanBytes,按照byte進行拆分
B、ScanLines,按照行(「\n」)進行拆分
C、ScanRunes,按照utf-8字符進行拆分
D、ScanWords,按照單詞(」 「)進行拆分
經過Scanner的Split方法,能夠爲Scanner指定splitFunc。使用方法以下:
scanner := bufio.NewScanner(os.StdIn) scanner.split(bufio.ScanWords)
設置分割方式type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
函數接收兩個參數,第一個參數是輸入數據,第二個參數是一個標識位,用於標識當前數據是否爲結束。函數返回三個參數,第一個是本次split操做的指針偏移;第二個是當前讀取到的token;第三個是返回的錯誤信息。
func (s *Scanner) Scan() bool func (s *Scanner) Text() string func (s *Scanner) Bytes() []byte
在完成Scanner初始化後,經過Scan方法能夠在輸入中向前讀取一個token,讀取成功返回True;使用Text和Bytes方法獲取token,Text返回一個字符串,Bytes返回字節數組。
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包的封裝函數。
func ReadAll(r io.Reader) ([]byte, error)
ReadAll讀取r中的全部數據
返回讀取的數據和讀取過程當中遇到的任何錯誤。若是讀取成功,則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讀取文件中的全部數據,返回讀取的數據和讀取過程當中遇到的任何錯誤。若是讀取成功,則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中寫入數據data,若是文件不存在,則以perm權限建立該文件;若是文件存在,則先清空文件,而後再寫入。返回寫入過程當中遇到的任何錯誤。
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中的全部目錄和文件(不包括子目錄)
返回讀取到的文件的信息列表和讀取過程當中遇到的任何錯誤,返回的文件列表是通過排序的。
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,只不過建立的是目錄,返回值也只返目錄的完整路徑。
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中建立一個臨時文件並將其打開,文件名以prefix爲前綴
返回建立的文件的對象和建立過程當中遇到的任何錯誤
若是dir爲空,則在系統的臨時目錄中建立臨時文件
若是環境變量中沒有設置系統臨時目錄,則在/tmp中建立臨時文件
調用者能夠經過f.Name()方法獲取臨時文件的完整路徑
調用TempFile所建立的臨時文件,應該由調用者本身移除
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是一個io.Writer,對它進行的任何Write調用都將無條件成功。devNull優化的實現ReadFrom,所以io.Copy到ioutil.Discard避免沒必要要的工做,所以其必定會成功。可是ioutil.Discard不記錄copy獲得的數值。
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包提供了對字節切片進行讀寫操做的一系列函數。 字節切片處理的函數比較多,分爲基本處理函數、比較函數、後綴檢查函數、索引函數、分割函數、大小寫處理函數和子切片處理函數等。
strings與bytes的函數接口功能基本一致。
func Contains(b,subslice []bytes) bool
檢查字節切片b是否包含子切片subslice,若是包含返回true,不然返回false。func Count(s,sep []byte) int
計算字節切片sep在字節切片s中非重疊顯示的個數。func Repeat(b[]byte,count int) []byte
把切片b複製count個,而後合成一個新的字節切片返回。func Replace(s,old,new []byte,n int) []byte
返回字節切片s的一個副本,並把前n個不重疊的子切片old替換爲new;若是n小於0,則不限制替換的數量。參數n爲替換的次數。
func Runes(s []byte) []rune
把s轉換爲UTF-8編碼的字節序列,並返回對應的Unicode切片func Join(s [][]byte,sep[]byte) []byte
用字節切片sep把s中的每一個字節切片連成一個字節切片並返回。
基本函數示例:
package main import ( "fmt" "bytes" ) func main() { //Contains b := []byte("hello") //字符串強轉爲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("轉換前字符串的長度: ",len(s))//12 fmt.Println("轉換後字符串的長度: ",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
根據字節的值比較字節切片a和b的大小,若是a=b,返回0,若是a>b返回1,若是a小於b返回-1。func Equal(a,b[]byte) bool
比較2個字節切片是否相等,若是參數爲nil,則等同於空的字節切片,若是a=b,則返回true,不然返回false.區分大小寫。func EqualFold(s,t[]byte) bool
把s和t轉換成UTF-8字符串進行比較,而且忽略大小寫,若是s=t,返回true,不然,返回false。
比較函數示例:
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 從第一個字節開始比較,若是相同再比較長度 //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
檢查字節切片s的前綴是否爲prefix,若是是返回true,若是不是返回falsefunc HashSuffix(s,suffix[]byte) bool
檢查字節切片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 }
字節切片位置索引函數共有8個,Index()、IndexAny()、IndexByte()、IndexFunc()、IndexRune()、LastIndex()、LastIndexAny()和LastIndexFunc()。func Index(s,sep []byte) int
返回sep在s中第一次出現的位置索引(從0開始),若是sep中不在s中則返回-1func IndexAny(s []byte,chars string) int
把s解析爲UTF-8編碼的字節序列,返回chars中任何一個字符在s中第一次出現的索引位置;若是s中不包含chars中任何一個字符,則返回-1func IndexByte(s[]byte,c byte) int
檢查字節c在s中第一次出現的位置索引;若是s中不包含c則返回-1func IndexFunc(s[]byte,f func(r rune)bool) int
把s解析爲UTF-8字節序列,並返回一個知足f(c)=true的字符c的位置索引,若是沒有知足則返回-1func IndexRune(s[]byte,r rune) int
把s解析爲UTF-8字節序列,並返回rune類型的字符r在s中的位置索引,若是s中不包含r則返回-1func LastIndex(s,sep[]byte) int
返回sep在s中最後一次出現的位置索引,若是s中不包含sep,則返回-1func LastIndexAny(s[]byte,chars string) int
把s解析爲UTF-8字節序列,返回chars中任何一個字符在s中最後
出現的位置索引,若是chars爲空或者s中不包含chars中的任意字符,則返回-1func LastIndexFunc(s[]byte,f func(r rune)bool) int
把s解析成UTF-8字節序列,返回知足f(s)=true的字符c在s中最後
一次出現的位置索引,若是沒有找到則返回-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,能夠接收匿名函數 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 }
字節切片分割函數共有6個,Fields(),FieldsFunc(),Split(),SplitN(),
SplitAfter()和SplitAfterN()。func Fields(s[]byte) [][]byte
把字節切片s按照一個或者連續多個空白字符分割成多個字節切片,若是s只包含空白字符則返回空字節切片,其中參數s準備分割的字節切片func FieldsFunc(s []byte,f func(r rune)bool) [][]byte
把s解析爲UTF-8字節序列,對於每一個Unicode字符c,若是f(c)返回true就把c做爲分割字符對s進行拆分。若是全部字符都知足f(c)爲true,則返回空切片func Split(s,sep[]byte)[][]byte
把s用sep分割成多個字節切片並返回,若是sep爲空,Split則把s切分紅每一個字節切片對應一個UTF-8字符,Split()等效於參數爲n的splitN()函數。func SplitAfter(s,sep[]byte)[][]byte
使用sep做爲後綴把s切分紅多個字節切片並返回。若是sep爲空,則把s切分紅每一個字節切片對應一個UTF-8字符。func SplitAfterN(s,sep[]byte,n int)[][]byte
用sep做爲後綴把s切分紅多個字節切片並返回。若是sep爲空,則把s切分紅每一個字節切片對應一個UTF-8字符。參數n決定返回切片的長度:若是n>0,最多返回n個子字節切片,子切片可能包含未切分的字節序列;若是n=0,返回空切片;若是n< 0,返回全部子切片。func SplitN(s,sep []byte,n int)[][]byte
把s用sep分割成多個字節切片並返回,若是sep爲空,Split則把s切分紅每一個字節切片對應一個UTF-8字符,參數n決定返回長度,n>0最多返回n個子切片;n==0返回返回空切片,n小於0返回全部子切片。
分割函數示例:
package main import ( "fmt" "bytes" ) func main() { //Fields ,返回的是2維切片 s := []byte("hello world") for _,v := range bytes.Fields(s){ //遍歷獲取1維切片,再強轉爲字符串 fmt.Print(string(v)+",") // hello,world, } fmt.Println() //FieldsFunc,返回是2維切片,接收匿名函數 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個函數,Title(),ToTitle(),ToTitleSpecial(),ToLower(),ToLowerSpecial(),ToUpper() 和ToUpperSpecial()。
func Title(s[]byte) []byte
返回一個s的副本,把s中每一個單詞的首字母改爲Unicode字符大寫
func ToTitle(s []byte) []byte
返回s的一個副本,並把其中全部Unicode字符轉爲大寫func ToTitleSpecial(_case unicode.SpecialCase,s []byte) []byte
返回s的一個副本,並把其中全部Unicode字符根據_case指定的規則轉成大寫func ToLower(s []byte)[]byte
返回s的一個副本,並把其中的全部Unicode字符轉爲小寫func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte
返回s的一個副本,並把其中全部Unicode字符根據_case定的規則轉換成小寫func ToUpper(s []byte) []byte
返回s的一個副本,並把其中全部Unicode字符都轉爲大寫func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte
返回s的一個副本,並把其中全部Unicode字符都根據_case
指定的規則轉成大寫
大小寫處理函數示例:
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 }
子字節切片處理函數共有9個,Trim(),TrimFunc(),TrimLeft(),TrimLeftFunc(),TrimRight(),TrimRightFunc(),TrimSpace(),TrimPrefix()和TrimSuffix()。func Trim(s []byte, cutset string) []byte
返回s的子字節切片,cutset中任意出如今s的首部和尾部的連續字符將被刪除。func TrimFunc(s []byte, f func(r rune) bool) []byte
返回s的子字節切片,刪除s首部和尾部鏈接的知足f(c)=true的字符c。func TrimLeft(s []byte, cutset string) []byte
返回s的子字節切片,cutset中任意出如今s首部的連續字符被刪除。func TrimLeftFunc(s []byte, f func(r rune) bool) []byte
返回s的一個子字節切片、刪除s首部連續知足f(c)=true的字符c。func TrimRight(s []byte, cutset string) []byte
返回s的子字節切片,cutset中任意出如今s尾部的連續字符被刪除。func TrimRightFunc(s []byte, f func(r rune) bool) []byte
返回s的一個子字節切片、刪除s尾部連續知足f(c)=true的字符cfunc TrimSpace(s []byte) []byte
返回s的一個子字節切片,並刪除s中開始和結尾處的連續的Unicode空白字符。func TrimPrefix(s, prefix []byte) []byte
返回s的一個子字節切片,並刪除前綴爲prefix的部分func TrimSuffix(s, suffix []byte) []byte
返回s的一個子字節切片,並刪除後綴爲suffix的部分
子字節切片處理函數示例:
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實現了對斜槓分隔的路徑進行操做的函數。
filepath包實現了兼容各操做系統的文件路徑操做函數
func IsAbs(path string) bool
判斷是不是一個絕對路徑func Split(path string) (dir, file string)
將路徑分割爲路徑和文件名func Join(elem ...string) string
將多個字符串合併爲一個路徑func Ext(path string) string
返回路徑中擴展部分func Base(path string) string
返回路徑的最後一個元素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" // 判斷是不是一個絕對路徑 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 // 將多個字符串合併爲一個路徑 dir_join := path.Join("usr", "local", "bin") fmt.Println(dir_join) // usr/local/bin // 返回路徑中擴展 file_ext := path.Ext(pf) fmt.Println(file_ext) // .go // 返回路徑的最後一個元素 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
預約義變量,表示路徑分隔符 /filepath.ListSeparator
預約義變量,表示環境變量分隔符 :func Abs(path string) (string, error)
返回path相對當前路徑的絕對路徑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
分隔環境變量裏面的路徑func Walk(root string, walkFn WalkFunc) error
遍歷root目錄下的文件樹,並調用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() { // 預約義變量 fmt.Println(string(filepath.Separator), string(filepath.ListSeparator)) // 返回path 相對當前路徑的絕對路徑 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 // 分隔環境變量裏面的路徑 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 目錄下的文件樹,並調用 walkFn root_dir, err := os.Getwd() err = filepath.Walk(root_dir, pathName) fmt.Println(err) }
Walk(root stirng, walkFn WalkFunc) error
// 參數root能夠是文件名也能夠是目錄名;walkFn是自定義的函數
func Walk(root string, walkFn WalkFunc) error { //獲取root的描述信息 info, err := os.Lstat(root) if err != nil { //若是獲取描述信息發生錯誤,返回err由定義的walkFn函數處理 err = walkFn(root, nil, err) } else { //調用walk(root, info, walkFn)函數進行遞歸遍歷root err = walk(root, info, walkFn) } if err == SkipDir { return nil } return err }
Walk方法會遍歷root下的全部文件(包含root)並對每個目錄和文件都調用walkFunc方法。在訪問文件和目錄時發生的錯誤都會經過error參數傳遞給WalkFunc方法。文件是按照詞法順序進行遍歷的,一般讓輸出更漂亮,但也會致使處理很是大的目錄時效率會下降。另外,Walk函數不會遍歷符號連接。type WalkFunc func(path string, info os.FileInfo, err error)
WalkFunc是一個方法類型,Walk函數在遍歷文件或者目錄時調用。調用時將參數傳遞給path,將Walk函數中的root做爲前綴。將root + 文件名或者目錄名做爲path傳遞給WalkFunc函數。例如在"dir"目錄下遍歷到"a"文件,則path="dir/a";Info是path所指向文件的文件信息。若是在遍歷過程當中出現了問題,傳入參數err會描述這個問題。WalkFunc函數能夠處理這個問題,Walk將不會再深刻該目錄。若是函數會返回一個錯誤,Walk函數會終止執行;只有一個例外,咱們也一般用這個來跳過某些目錄。當WalkFunc的返回值是filepaht.SkipDir時,Walk將會跳過這個目錄,照常執行下一個文件。
func walk(path string, info os.FileInfo, walkFn WalkFunc) error { //調用定義的walkFn自定義函數處理 err := walkFn(path, info, nil) if err != nil { //返回錯誤,且該目錄能夠跳過 if info.IsDir() && err == SkipDir { return nil } return err } //若是是文件,則遍歷下一個 if !info.IsDir() { return nil } //讀取該path下的全部目錄和文件 names, err := readDirNames(path) if err != nil { //發生錯誤,調用自定義函數處理 return walkFn(path, info, err) } //遍歷文件和目錄列表 for _, name := range names { //路徑path/name filename := Join(path, name) //獲取該文件或者目錄信息 fileInfo, err := lstat(filename) if err != nil { //發生錯誤,調用自定義函數處理 if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir { return err } } else { //這裏遞歸調用,獲取root下各級文件和目錄信息,在自定義函數walkFn裏作處理 err = walk(filename, fileInfo, walkFn) if err != nil { //遍歷文件發生錯誤或者目錄發生錯誤且不能跳過,則返回err if !fileInfo.IsDir() || err != SkipDir { return err } } } } return nil }