os包结构介绍
-- os 包
--os/exec 包,负责执行外部命令.
--os/signal对输入信息的访问
--os/user 通过名称或ID 查询用户账户
-
• 在os/user中提供了User结构体,表示操作系统用户
-
• Uid 用户id
-
• Gid 所属组id
-
• Username 用户名
-
• Name 所属组名
-
• HomeDir 用户对应文件夹路径
// User represents a user account.
type User struct {
// Uid is the user ID.
// On POSIX systems, this is a decimal number representing the uid.
// On Windows, this is a security identifier (SID) in a string format.
// On Plan 9, this is the contents of /dev/user.
Uid string
// Gid is the primary group ID.
// On POSIX systems, this is a decimal number representing the gid.
// On Windows, this is a SID in a string format.
// On Plan 9, this is the contents of /dev/user.
Gid string
// Username is the login name.
Username string
// Name is the user's real or display name.
// It might be blank.
// On POSIX systems, this is the first (or only) entry in the GECOS field
// list.
// On Windows, this is the user's display name.
// On Plan 9, this is the contents of /dev/user.
Name string
// HomeDir is the path to the user's home directory (if they have one).
HomeDir string
}
-
• 在os/user中的Group表示用户所属组
-
• Gid 组的id
-
• Name 组的名称
// Group represents a grouping of users.
//
// On POSIX systems Gid contains a decimal number representing the group ID.
type Group struct {
Gid string // group ID
Name string // group name
}
-
• 整个os/user包中内容比较少,提供了两个错误类型和获取当前用户,查找用户
type UnknownUserError
func (e UnknownUserError) Error() string
type UnknownUserIdError
func (e UnknownUserIdError) Error() string
type User
func Current() (*User, error)
func Lookup(username string) (*User, error)
func LookupId(uid string) (*User, error)
代码示例
-
• 可以获取当前用户或查找用户后获取用户信息
//获取当前登录用户
//u,_:=user.Current()
/*
Lookup()参数是用户名,按照用户名查找指定用户对象
注意:必须使用完整名称不可以只写zhang
*/
u, _ := user.Lookup(`LAPTOP-APM56maishuren`)
fmt.Println(u.Name)
fmt.Println(u.Gid)
fmt.Println(u.HomeDir)
fmt.Println(u.Uid)
fmt.Println(u.Username)
os包内容介绍
-
• 使用os包中内容进行操作系统文件或目录
-
• File结构体表示操作系统文件(夹)
// File represents an open file descriptor.
type File struct {
*file // os specific
}
// file is the real representation of *File.
// The extra level of indirection ensures that no clients of os
// can overwrite this data, which could cause the finalizer
// to close the wrong file descriptor.
type file struct {
pfd poll.FD
name string
dirinfo *dirInfo // nil unless directory being read
}
-
• 操作系统的文件都是有权限控制的,包含可读,可写等,在os包中FileMode表示文件权限,本质是uint32,可取值都以常量形式提供
// A FileMode represents a file's mode and permission bits.
// The bits have the same definition on all systems, so that
// information about files can be moved from one system
// to another portably. Not all bits apply to all systems.
// The only required bit is ModeDir for directories.
type FileMode uint32
// The defined file mode bits are the most significant bits of the FileMode.
// The nine least-significant bits are the standard Unix rwxrwxrwx permissions.
// The values of these bits should be considered part of the public API and
// may be used in wire protocols or disk representations: they must not be
// changed, although new bits might be added.
const (
// The single letters are the abbreviations
// used by the String method's formatting.
ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory
ModeAppend // a: append-only
ModeExclusive // l: exclusive use
ModeTemporary // T: temporary file; Plan 9 only
ModeSymlink // L: symbolic link
ModeDevice // D: device file
ModeNamedPipe // p: named pipe (FIFO)
ModeSocket // S: Unix domain socket
ModeSetuid // u: setuid
ModeSetgid // g: setgid
ModeCharDevice // c: Unix character device, when ModeDevice is set
ModeSticky // t: sticky
// Mask for the type bits. For regular files, none will be set.
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
ModePerm FileMode = 0777 // Unix permission bits
)
-
• FIleInfo是一个interface表示文件的信息
// A FileInfo describes a file and is returned by Stat and Lstat.
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)
}
资源路径
-
• 在获取系统资源时资源路径分为相对路径和绝对路径
-
• 相对路径:在Go语言中相对路径用于是GOPATH,也就是项目的根目录
-
• 绝对路径:磁盘根目录开始表示资源详细路径的描述
代码示例
-
• Go语言标准库中提供了两种创建文件夹的方式
/*
要求文件夹不存在且父目录必须存在,才能创建
*/
//error := os.Mkdir("D:/godir", os.ModeDir)
//if error != nil {
// fmt.Println("文件夹创建失败",error)
// return
//}
//fmt.Println("文件夹创建成功")
/*
如果文件夹已经存在,不报错,保留原文件夹
如果父目录不存在帮助创建
*/
error := os.MkdirAll("D:/godir/a/b", os.ModeDir)
if error != nil {
fmt.Println("文件夹创建失败",error)
return
}
fmt.Println("文件夹创建成功")
-
• 创建空文件
/*
创建文件时要求文件目录必须已经存在
如果文件已经存在则会创建一个空文件覆盖之前的文件
*/
file, err := os.Create("D:/godir/test.txt")
if err != nil {
fmt.Println("文件创建失败,", err)
return
}
fmt.Println("文件创建成功",file.Name())
-
• 重命名文件或文件夹
/*
第一个参数:原文件夹名称,要求此路径是必须存在的
第二个参数:新文件夹名称
*/
err := os.Rename("D:/godir", "D:/godir1")
if err != nil {
fmt.Println("重命名文件夹失败,", err)
return
}
fmt.Println("文件夹重命名成功")
/*
重命名文件和重命名文件夹用法相同
*/
err = os.Rename("D:/godir1/test.txt", "D:/godir1/test1.txt")
if err != nil {
fmt.Println("重命名文件失败,", err)
return
}
fmt.Println("文件重命名成功")
-
• 获取文件(夹)信息
f, err := os.Open("D:/godir1/test1.txt")
defer f.Close() //文件打开后要关闭,释放资源
if err != nil {
fmt.Println("打开文件失败", err)
return
}
fileInfo, err := f.Stat()
if err != nil {
fmt.Println("获取文件信息失败", err)
return
}
fmt.Println(fileInfo.Name()) //文件名
fmt.Println(fileInfo.IsDir()) //是否是文件夹,返回bool,true表示文件夹,false表示文件
fmt.Println(fileInfo.Mode()) //文件权限
fmt.Println(fileInfo.ModTime()) //修改时间
fmt.Println(fileInfo.Size()) //文件大小
-
• 删除文件或文件夹
/*
删除的内容只能是一个文件或空文件夹且必须存在
*/
//err := os.Remove("D:/godir1/a")
//if err != nil {
// fmt.Println("文件删除失败", err)
// return
//}
//fmt.Println("删除成功")
/*
只要文件夹存在,删除文件夹.
无论文件夹是否有内容都会删除
如果删除目标是文件,则删除文件
*/
err := os.RemoveAll("D:/godir1/a.txt")
if err != nil {
fmt.Println("删除失败", err)
return
}
fmt.Println("删除成功")
输入流
-
• 流(stream)是应用程序和外部资源进行数据交互的纽带
-
• 流分为输入流和输出流,输入和输出都是相对于程序,把外部数据传入到程序中叫做输入,反之叫做输出流
-
• 输入流(Input Stream),输入流(Output Stream) 平时所说的I/O流
-
• 在Go语言标准库中io包下是Reader接口表示输入流,只要实现这个接口就属于输入流
// Reader is the interface that wraps the basic Read method.
//
// Read reads up to len(p) bytes into p. It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered. Even if Read
// returns n < len(p), it may use all of p as scratch space during the call.
// If some data is available but not len(p) bytes, Read conventionally
// returns what is available instead of waiting for more.
//
// When Read encounters an error or end-of-file condition after
// successfully reading n > 0 bytes, it returns the number of
// bytes read. It may return the (non-nil) error from the same call
// or return the error (and n == 0) from a subsequent call.
// An instance of this general case is that a Reader returning
// a non-zero number of bytes at the end of the input stream may
// return either err == EOF or err == nil. The next Read should
// return 0, EOF.
//
// Callers should always process the n > 0 bytes returned before
// considering the error err. Doing so correctly handles I/O errors
// that happen after reading some bytes and also both of the
// allowed EOF behaviors.
//
// Implementations of Read are discouraged from returning a
// zero byte count with a nil error, except when len(p) == 0.
// Callers should treat a return of 0 and nil as indicating that
// nothing happened; in particular it does not indicate EOF.
//
// Implementations must not retain p.
type Reader interface {
Read(p []byte) (n int, err error)
}
代码演示
-
• 可以使用strings包下的NewReader创建字符串流
r := strings.NewReader("hello 世界")
b := make([]byte, r.Size())//创建字节切片,存放流中数据,根据流数据大小创建切片大小
n, err := r.Read(b)//把流中数据读取到切片中
if err != nil {
fmt.Println("读取失败,", err)
return
}
fmt.Println("读取数据长度,", n)
fmt.Println("流中数据",string(b))//以字符串形式输入切片中数据
-
• 最常用的是文件流,把外部文件中数据读取到程序中
f, err := os.Open("D:/go.txt")//打开文件
defer f.Close()
if err != nil {
fmt.Println("文件读取失败,", err)
return
}
fileInfo, err := f.Stat()//获取文件信息
if err != nil {
fmt.Println("文件信息获取失败,", err)
return
}
b := make([]byte, fileInfo.Size())//根据文件中数据大小创建切片
_, err = f.Read(b)//读取数据到切片中
if err != nil {
fmt.Println("文件流读取失败:", err)
return
}
fmt.Println("文件中内容为:", string(b))//以字符串形式输入切片中数据
输入流
-
• 输入流就是把程序中数据写出到外部资源
-
• Go语言标准库中输出流是Writer接口
// Writer is the interface that wraps the basic Write method.
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
// Write must not modify the slice data, even temporarily.
//
// Implementations must not retain p.
type Writer interface {
Write(p []byte) (n int, err error)
}
代码操作
-
• 注意:输入流时不要使用
os.Open()
因为这种方式获取的文件是只读的
fp := "D:/go.txt"
/*
第三个参数表示文件权限
第 1 位在权限中总是为 0
第 2 位为 0 表示文件不可以被读, 为 1 表示可以被读
第 3 位为 0 表示文件不可以被写, 为 1 表示可以被写
第 4 位为 0 表示文件不可以被执行, 为 1 表示可以被执行
整理如下:
0(0000): 不可读写,不能被执行
1(0001): 不可读写,能被执行
2(0010): 可写不可读,不能被执行
3(0011): 可写不可读,能被执行
4(0100): 可读不可写,不能被执行
5(0101): 可读不可写,能被执行
6(0110): 可读写,不能执行
7(0111): 可读写,可执行
0666:
第一个 0 表示这个数是 八进制
第一个 6 表示文件拥有者有读写权限,但没有执行权限
第二个 6 表示文件拥有者同组用户有读写权限,但没有执行权限
第三个 6 表示其它用户有读写权限,但没有执行权限
*/
//第二个参数表示文件内容追加
//第三个参数表示创建文件时文件权限
f, err := os.OpenFile(fp, os.O_APPEND, 0660)
defer f.Close()
if err != nil {
fmt.Println("文件不存在,创建文件")
f, _ = os.Create(fp)
}
/*
内容中识别特殊字符
rn 换行
t 缩进
*/
/*
使用文件对象重写的Writer接口,参数是[]byte
*/
f.Write([]byte("使用Writer接口写数据rn"))
/*
使用stringWriter接口的方法,参数是字符串,使用更方便
*/
f.WriteString("写了t一段rn内容123")
fmt.Println("程序执行结束")
ioutil包
-
• ioutil包下提供了对文件读写的工具函数,通过这些函数快速实现文件的读写操作
-
• ioutil包下提供的函数比较少,但是都是很方便使用的函数
func NopCloser(r io.Reader) io.ReadCloser
func ReadAll(r io.Reader) ([]byte, error)
func ReadFile(filename string) ([]byte, error)
func WriteFile(filename string, data []byte, perm os.FileMode) error
func ReadDir(dirname string) ([]os.FileInfo, error)
func TempDir(dir, prefix string) (name string, err error)
func TempFile(dir, prefix string) (f *os.File, err error)
代码演示
-
• 打开完文件后可以使用ReadAll把文件中所有内容都读取到
f, err := os.Open("D:/go.txt")
defer f.Close()
if err != nil {
fmt.Println(err)
return
}
b, err := ioutil.ReadAll(f)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("文件中内容:n", string(b))
-
• 也可以直接读取文件中内容
b, err := ioutil.ReadFile("D:/go.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(b))
-
• 写文件也很简单,直接使用WriteFile函数即可,但是源码中已经规定此文件只能是可写状态,且不是尾加数据
err := ioutil.WriteFile("D:/abc.txt", []byte("内容123123"), 0666)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("数据写入成功")
-
• 还提供了快速获取某个文件夹中所有文件信息的函数
fs,_:=ioutil.ReadDir("D:/")
for _,n := range fs {
fmt.Println(n.Name())
}
原文始发于微信公众号(杂食的程序员):golang学习十五:文件操作
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/247281.html