Go 18.0 专业五


05. IO操作

<h1>1. IO操作</h1> <h3>1.1.1. 输入输出的底层原理</h3> <ul> <li>终端其实是一个文件,相关实例如下: <ul> <li><code>os.Stdin</code>:标准输入的文件实例,类型为<code>*File</code></li> <li><code>os.Stdout</code>:标准输出的文件实例,类型为<code>*File</code></li> <li><code>os.Stderr</code>:标准错误输出的文件实例,类型为<code>*File</code></li> </ul></li> </ul> <p>以文件的方式操作终端:</p> <pre><code>package main import "os" func main() { var buf [16]byte os.Stdin.Read(buf[:]) os.Stdin.WriteString(string(buf[:])) }</code></pre> <h3>1.1.2. 文件操作相关API</h3> <ul> <li><code>func Create(name string) (file *File, err Error)</code> <ul> <li>根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666</li> </ul></li> <li><code>func NewFile(fd uintptr, name string) *File</code> <ul> <li>根据文件描述符创建相应的文件,返回一个文件对象</li> </ul></li> <li><code>func Open(name string) (file *File, err Error)</code> <ul> <li>只读方式打开一个名称为name的文件</li> </ul></li> <li><code>func OpenFile(name string, flag int, perm uint32) (file *File, err Error)</code> <ul> <li>打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限</li> </ul></li> <li><code>func (file *File) Write(b []byte) (n int, err Error)</code> <ul> <li>写入byte类型的信息到文件</li> </ul></li> <li><code>func (file *File) WriteAt(b []byte, off int64) (n int, err Error)</code> <ul> <li>在指定位置开始写入byte类型的信息</li> </ul></li> <li><code>func (file *File) WriteString(s string) (ret int, err Error)</code> <ul> <li>写入string信息到文件</li> </ul></li> <li><code>func (file *File) Read(b []byte) (n int, err Error)</code> <ul> <li>读取数据到b中</li> </ul></li> <li><code>func (file *File) ReadAt(b []byte, off int64) (n int, err Error)</code> <ul> <li>从off开始读取数据到b中</li> </ul></li> <li><code>func Remove(name string) Error</code> <ul> <li>删除文件名为name的文件</li> </ul></li> </ul> <h3>1.1.3. 打开和关闭文件</h3> <p><code>os.Open()</code>函数能够打开一个文件,返回一个<code>*File</code>和一个<code>err</code>。对得到的文件实例调用close()方法能够关闭文件。</p> <pre><code>package main import ( "fmt" "os" ) func main() { // 只读方式打开当前目录下的main.go文件 file, err := os.Open("./main.go") if err != nil { fmt.Println("open file failed!, err:", err) return } // 关闭文件 file.Close() }</code></pre> <h3>1.1.4. 写文件</h3> <pre><code>package main import ( "fmt" "os" ) func main() { // 新建文件 file, err := os.Create("./xxx.txt") if err != nil { fmt.Println(err) return } defer file.Close() for i := 0; i &lt; 5; i++ { file.WriteString("ab\n") file.Write([]byte("cd\n")) } }</code></pre> <h3>1.1.5. 读文件</h3> <p>文件读取可以用file.Read()和file.ReadAt(),读到文件末尾会返回io.EOF的错误</p> <pre><code>package main import ( "fmt" "io" "os" ) func main() { // 打开文件 file, err := os.Open("./xxx.txt") if err != nil { fmt.Println("open file err :", err) return } defer file.Close() // 定义接收文件读取的字节数组 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)) }</code></pre> <h3>1.1.6. 拷贝文件</h3> <pre><code>package main import ( "fmt" "io" "os" ) func main() { // 打开源文件 srcFile, err := os.Open("./xxx.txt") if err != nil { fmt.Println(err) return } // 创建新文件 dstFile, err2 := os.Create("./abc2.txt") if err2 != nil { fmt.Println(err2) return } // 缓冲读取 buf := make([]byte, 1024) for { // 从源文件读数据 n, err := srcFile.Read(buf) if err == io.EOF { fmt.Println("读取完毕") break } if err != nil { fmt.Println(err) break } //写出去 dstFile.Write(buf[:n]) } srcFile.Close() dstFile.Close() }</code></pre> <h3>1.1.7. bufio</h3> <ul> <li>bufio包实现了带缓冲区的读写,是对文件读写的封装</li> <li>bufio缓冲写数据</li> </ul> <table> <thead> <tr> <th>模式</th> <th>含义</th> </tr> </thead> <tbody> <tr> <td>os.O_WRONLY</td> <td>只写</td> </tr> <tr> <td>os.O_CREATE</td> <td>创建文件</td> </tr> <tr> <td>os.O_RDONLY</td> <td>只读</td> </tr> <tr> <td>os.O_RDWR</td> <td>读写</td> </tr> <tr> <td>os.O_TRUNC</td> <td>清空</td> </tr> <tr> <td>os.O_APPEND</td> <td>追加</td> </tr> </tbody> </table> <ul> <li> <p>bufio读数据</p> <p>package main</p> <p>import ( &quot;bufio&quot; &quot;fmt&quot; &quot;io&quot; &quot;os&quot; )</p> <p>func wr() { // 参数2:打开模式,所有模式d都在上面 // 参数3是权限控制 // w写 r读 x执行 w 2 r 4 x 1 file, err := os.OpenFile(&quot;./xxx.txt&quot;, os.O_CREATE|os.O_WRONLY, 0666) if err != nil { return } defer file.Close() // 获取writer对象 writer := bufio.NewWriter(file) for i := 0; i &lt; 10; i++ { writer.WriteString(&quot;hello\n&quot;) } // 刷新缓冲区,强制写出 writer.Flush() }</p> <p>func re() { file, err := os.Open(&quot;./xxx.txt&quot;) if err != nil { return } defer file.Close() reader := bufio.NewReader(file) for { line, _, err := reader.ReadLine() if err == io.EOF { break } if err != nil { return } fmt.Println(string(line)) }</p> <p>}</p> <p>func main() { re() }</p> </li> </ul> <h3>1.1.8. ioutil工具包</h3> <ul> <li>工具包写文件</li> <li> <p>工具包读取文件</p> <p>package main</p> <p>import ( &quot;fmt&quot; &quot;io/ioutil&quot; )</p> <p>func wr() { err := ioutil.WriteFile(&quot;./yyy.txt&quot;, []byte(&quot;www.5lmh.com&quot;), 0666) if err != nil { fmt.Println(err) return } }</p> <p>func re() { content, err := ioutil.ReadFile(&quot;./yyy.txt&quot;) if err != nil { fmt.Println(err) return } fmt.Println(string(content)) } func main() { re() }</p> </li> </ul> <h3>1.1.9. 例子</h3> <h4>实现一个cat命令</h4> <p>使用文件操作相关知识,模拟实现linux平台cat命令的功能。</p> <pre><code>package main import ( "bufio" "flag" "fmt" "io" "os" ) // cat命令实现 func cat(r *bufio.Reader) { for { buf, err := r.ReadBytes('\n') //注意是字符 if err == io.EOF { break } fmt.Fprintf(os.Stdout, "%s", buf) } } func main() { flag.Parse() // 解析命令行参数 if flag.NArg() == 0 { // 如果没有参数默认从标准输入读取内容 cat(bufio.NewReader(os.Stdin)) } // 依次读取每个指定文件的内容并打印到终端 for i := 0; i &lt; flag.NArg(); i++ { f, err := os.Open(flag.Arg(i)) if err != nil { fmt.Fprintf(os.Stdout, "reading from %s failed, err:%v\n", flag.Arg(i), err) continue } cat(bufio.NewReader(f)) } }</code></pre>

页面列表

ITEM_HTML