跳转到主要内容
eLearner.app
模块 8 · 第 3 课(共 5)课程中的38/50~14 min
模块课程(3/5)

`io` 和 `os`:文件和流

Reading and writing files and streams in Go revolves around two complementary packages: os (opening, creation, metadata, processes) and io (the Reader/Writer interfaces that abstract any byte source).

Reading and writing files: the shortcuts

For small or configuration files, a single call is enough:

Go
data, err := os.ReadFile("input.txt")        // returns []byte
if err != nil {
    return err
}
fmt.Println(string(data))

err = os.WriteFile("out.txt", []byte("ciao"), 0644)

os.ReadFile opens, reads everything into memory and closes. Perfect up to a few MB; beyond that, streaming is better.

Opening files for streaming

For large files or incremental access, open the file and close it with defer:

Go
f, err := os.Open("big.txt")        // read-only
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 4096)
for {
    n, err := f.Read(buf)
    if n > 0 {
        process(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

os.Open opens in read-only. To write use os.Create (truncates if it exists) or os.OpenFile(path, flag, perm) with flags like os.O_APPEND | os.O_CREATE | os.O_WRONLY.

io.Reader and io.Writer: the universal interfaces

Go
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }

Wherever the standard library accepts an io.Reader you can pass a file (*os.File), a string (strings.NewReader), a *bytes.Buffer, an HTTP response (resp.Body), a decompressor... The same goes for io.Writer.

Go
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)

io.Copy is the workhorse for byte pipelines: it handles buffering and EOF correctly. io.ReadAll(r) reads everything until EOF into a []byte.

os.Args: CLI arguments

os.Args is a slice of strings: index 0 is the program name, from 1 on the actual arguments:

Go
func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "uso: prog <nome>")
        os.Exit(1)
    }
    fmt.Println("ciao", os.Args[1])
}

For more structured parsing (flags, defaults, help) use the flag package from the stdlib or external libraries like cobra.

os.Stdin, os.Stdout, os.Stderr

These are three global *os.Files: wherever an io.Reader or io.Writer is accepted you can pass them.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

Exercises

锻炼#go.m8.l3.e1
尝试:0加载中...

Print the first command-line argument (os.Args[1]). If it is missing, print 'manca argomento' and return.

正在加载编辑器...

3 次尝试后可用的解决方案

锻炼#go.m8.l3.e2
尝试:0加载中...

Write the string 'ciao' to the file 'out.txt' with os.WriteFile (permissions 0644). Handle the error.

正在加载编辑器...

3 次尝试后可用的解决方案

Quiz#go.m8.l3.e3
准备好

What is the index of the PROGRAM NAME in os.Args?

Go
fmt.Println(os.Args[???])
答案选项