来自:
从Golang项目中删除已弃用的ioutil包
Go 1.16之前
在Go 1.16
以前的版本中,如果我们需要开发文件系统、IO等操作,通常会使用到一个名为io/ioutil
的包。
目前很多网络上现存的教程文章,我们能够看到这个包的大量应用场景。
Go 1.16及之后版本
自从到了Go 1.16
发布以后,io/ioutil
就已经被正式弃用。当然,为了兼容性考虑,我们依旧可以正常调用这个包,只不过当我们调用ioutil
里面的方法,最后都是跳转到了io
以及os
包。
你可以尝试将Go版本升级至1.17
以上,然后进入io/ioutil
包的源码,就可以看到里面只有两个go
文件,ioutil.go
和tempfile.go
。
附:io/ioutil/ioutil.go
源码(Go 1.17+
)
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package ioutil implements some I/O utility functions.
//
// Deprecated: As of Go 1.16, the same functionality is now provided
// by package io or package os, and those implementations
// should be preferred in new code.
// See the specific function documentation for details.
package ioutil
import (
"io"
"io/fs"
"os"
"sort"
)
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
// as an error to be reported.
//
// Deprecated: As of Go 1.16, this function simply calls io.ReadAll.
func ReadAll(r io.Reader) ([]byte, error) {
return io.ReadAll(r)
}
// ReadFile reads the file named by filename and returns the contents.
// A successful call returns err == nil, not err == EOF. Because ReadFile
// reads the whole file, it does not treat an EOF from Read as an error
// to be reported.
//
// Deprecated: As of Go 1.16, this function simply calls os.ReadFile.
func ReadFile(filename string) ([]byte, error) {
return os.ReadFile(filename)
}
// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm
// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
//
// Deprecated: As of Go 1.16, this function simply calls os.WriteFile.
func WriteFile(filename string, data []byte, perm fs.FileMode) error {
return os.WriteFile(filename, data, perm)
}
// ReadDir reads the directory named by dirname and returns
// a list of fs.FileInfo for the directory's contents,
// sorted by filename. If an error occurs reading the directory,
// ReadDir returns no directory entries along with the error.
//
// Deprecated: As of Go 1.16, os.ReadDir is a more efficient and correct choice:
// it returns a list of fs.DirEntry instead of fs.FileInfo,
// and it returns partial results in the case of an error
// midway through reading a directory.
//
// If you must continue obtaining a list of fs.FileInfo, you still can:
//
// entries, err := os.ReadDir(dirname)
// if err != nil { ... }
// infos := make([]fs.FileInfo, 0, len(entries))
// for _, entry := range entries {
// info, err := entry.Info()
// if err != nil { ... }
// infos = append(infos, info)
// }
func ReadDir(dirname string) ([]fs.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
list, err := f.Readdir(-1)
f.Close()
if err != nil {
return nil, err
}
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
return list, nil
}
// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
//
// Deprecated: As of Go 1.16, this function simply calls io.NopCloser.
func NopCloser(r io.Reader) io.ReadCloser {
return io.NopCloser(r)
}
// Discard is an io.Writer on which all Write calls succeed
// without doing anything.
//
// Deprecated: As of Go 1.16, this value is simply io.Discard.
var Discard io.Writer = io.Discard
Go 1.17之后(Go 1.17+
)
从Go 1.17开始,io/ioutil/tempfile.go
里面的两个函数TempFile
和TempDir
改为简单地调用os
包
附:io/ioutil/tempfile.go
源码
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ioutil
import (
"os"
)
// TempFile creates a new temporary file in the directory dir,
// opens the file for reading and writing, and returns the resulting *os.File.
// The filename is generated by taking pattern and adding a random
// string to the end. If pattern includes a "*", the random string
// replaces the last "*".
// If dir is the empty string, TempFile uses the default directory
// for temporary files (see os.TempDir).
// Multiple programs calling TempFile simultaneously
// will not choose the same file. The caller can use f.Name()
// to find the pathname of the file. It is the caller's responsibility
// to remove the file when no longer needed.
//
// Deprecated: As of Go 1.17, this function simply calls os.CreateTemp.
func TempFile(dir, pattern string) (f *os.File, err error) {
return os.CreateTemp(dir, pattern)
}
// TempDir creates a new temporary directory in the directory dir.
// The directory name is generated by taking pattern and applying a
// random string to the end. If pattern includes a "*", the random string
// replaces the last "*". TempDir returns the name of the new directory.
// If dir is the empty string, TempDir uses the
// default directory for temporary files (see os.TempDir).
// Multiple programs calling TempDir simultaneously
// will not choose the same directory. It is the caller's responsibility
// to remove the directory when no longer needed.
//
// Deprecated: As of Go 1.17, this function simply calls os.MkdirTemp.
func TempDir(dir, pattern string) (name string, err error) {
return os.MkdirTemp(dir, pattern)
}
总结
io/ioutil
,就像名称中带有 util
的大多数东西一样,已被证明是一个定义不明确且难以理解的东西集合。通常我们不建议在Go项目中使用util
作为包名称。
在Go1.16
之后,官方已经将ioutil
下面的所有函数迁移到io
和os
下面。我们可以在这两个包下面找到新的函数替代以前的ioutil
。
如果我们曾经在项目中使用了io/ioutil
包,那么接下来应该开始使用io
和os
包了。
相关提案:
https://github.com/golang/go/issues/40025
https://github.com/golang/go/issues/42026
参考:https://tehub.com/a/b28Y1oz6AC
标签:1.16,弃用,err,ioutil,Go,directory,io,go,os From: https://www.cnblogs.com/rebrobot/p/18234507