輸入輸出的底層原理
終端其實是一個文件,相關實例如下
- os.Stdin:標准輸入的文件實例,類型為*File
- os.Stdout:標准輸出的文件實例,類型為*File
- os.Stderr:標准錯誤輸出的文件實例,類型為*File
以文件的方式操作終端
package main
import (
"os"
)
func main() {
var buf [16]byte
// 終端輸入
os.Stdin.Read(buf[:])
// 標准輸出
os.Stdout.WriteString(string(buf[:]))
}
文件操作相關 API
- 根據提供的文件名創建新的文件,返回一個文件對象,默認權限是 0666
func Create(name string) (file *File, err Error)
- 根據文件描述符創建相應的文件,返回一個文件對象
func NewFile(fd uintptr, name string) *File
- 只讀方式打開一個名稱為 name 的文件
func Open(name string) (file *File, err Error)
- 打開名稱為 name 的文件,flag 是打開的方式,只讀、讀寫等,perm 是權限
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
- 寫入 byte 類型的信息到文件
func (file *File) Write(b []byte) (n int, err Error)
- 在指定位置開始寫入 byte 類型的信息
func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
- 寫入 string 信息到文件
func (file *File) WriteString(s string) (ret int, err Error)
- 讀取數據到 b 中
func (file *File) Read(b []byte) (n int, err Error)
- 從 off 開始讀取數據到 b 中
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
- 刪除文件名為 name 的文件
func Remove(name string) Error
寫文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("./test.txt")
if err != nil {
fmt.Println("create file error: ", err)
return
}
defer file.Close()
for i:=0;i<5;i++ {
file.WriteString("hello\n")
file.Write([]byte("world\n"))
}
}
讀文件
文件讀取可以使用file.Read()
和file.ReadAt()
方法, 讀到文件末尾會返回io.EOF
的錯誤
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./test.txt")
if err != nil {
fmt.Println("open file err: ", err)
return
}
// 讀取文件緩沖區
var buf [128]byte
// 文件內容字節數組
var content []byte
for {
n, err := file.Read(buf[:])
if err == io.EOF {
// 文件讀取完畢
break
}
if err != nil {
fmt.Println("read file err: ", err)
return
}
content = append(content, buf[:n]...)
}
fmt.Println(string(content))
}
文件拷貝
流程是將源文件讀取出來,再將內容寫入到一個新文件中
package main
import (
"errors"
"fmt"
"io"
"os"
)
// 文件拷貝
func readFile(filename string) (fileBodyByte []byte, err error) {
file, err := os.Open(filename)
if err != nil {
return
}
defer file.Close()
var buf [128]byte
for {
n, err := file.Read(buf[:])
if err == io.EOF {
break
}
if err != nil {
err = errors.New("讀取文件失敗")
}
fileBodyByte = append(fileBodyByte, buf[:n]...)
}
return
}
func writeFile(filename string, context []byte) (status bool, err error) {
file, err := os.Create(filename)
if err != nil {
return
}
defer file.Close()
_, err = file.Write(context)
if err != nil {
return
}
return true, err
}
func copyFile(src string, dest string) (status bool, err error) {
fileBodyByte, err := readFile(src)
if err != nil {
return
}
status, err = writeFile(dest, fileBodyByte)
if err != nil {
return
}
return
}
func main() {
status, err := copyFile("./test.txt", "./hello.txt")
if err != nil {
fmt.Println(err)
}
if status {
fmt.Println("文件拷貝成功")
}
}
bufio
-
bufio 包實現了帶緩沖區的讀寫,是對文件讀寫的封裝
-
bufio 緩沖寫數據
- os.O_WRONLY:只寫
- os.O_CREATE:創建文件
- os.O_RDONLY:只讀
- os.O_RDWR:讀寫
- os.O_TRUNC:清空
- os.O_APPEND:追加
-
bufio 讀寫數據
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func wr() {
file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
bufWriter := bufio.NewWriter(file)
for i :=0; i<10; i++ {
bufWriter.Write([]byte("123\n"))
// 刷新緩沖區,強制寫出
bufWriter.Flush()
}
}
func re() {
file, err := os.Open("./test.txt")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
readBufio := bufio.NewReader(file)
for {
line, _, err := readBufio.ReadLine()
if err == io.EOF {
break
}
if err != nil {
fmt.Println(err)
return
}
fmt.Print(string(line))
}
}
func main() {
//wr()
re()
}
ioutil 工具包
這個工具包提供了非常方便的文件讀寫方法
package main
import (
"fmt"
"io/ioutil"
)
func wr() {
err := ioutil.WriteFile("./test123", []byte("hello world\n"), 0666)
if err != nil {
fmt.Println(err)
return
}
}
func re() {
content, err := ioutil.ReadFile("./test123")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(content))
}
func main() {
//wr()
re()
}