1. 概述

os 包提供了操作系统函数的不依赖平台的接口。失败的调用会返回错误值而非错误码。通常错误值里包含更多信息。例如,如果某个使用一个文件名的调用(如Open、Stat)失败了,打印错误时会包含该文件名,错误类型将为 *PathError ,其内部可以解包获得更多信息。

type PathError struct {Op   stringPath stringErr  error
}

PathError 记录一个错误,以及导致错误的路径。

func (e *PathError) Error() string

2. type FileInfo

type FileInfo interface {Name() string       // 文件的名字(不含扩展名)Size() int64        // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同Mode() FileMode     // 文件的模式位ModTime() time.Time // 文件的修改时间IsDir() bool        // 等价于Mode().IsDir()Sys() interface{}   // 底层数据来源(可以返回nil)
}

FileInfo 用来描述一个文件对象。

func Stat(name string) (fi FileInfo, err error)

Stat 返回一个描述 name 指定的文件对象的 FileInfo 。如果指定的文件对象是一个符号链接,返回的 FileInfo 描述该符号链接指向的文件的信息,本函数会尝试跳转该链接。如果出错,返回的错误值为 *PathError 类型。

代码示例:

package mainimport ("fmt""os"
)func main() {// Stat 返回一个描述 name 指定的文件对象的 FileInfofi, err := os.Stat("./test.txt")if err != nil {fmt.Println(err)}fileName := fi.Name()fileSize := fi.Size()fileMode := fi.Mode()fileModTime := fi.ModTime()isDir := fi.IsDir()fileSys := fi.Sys()fmt.Printf("fileName is %#v\n", fileName)fmt.Printf("fileSize is %#v\n", fileSize)fmt.Printf("fileMode is %#v\n", fileMode)fmt.Printf("fileModTime is %#v\n", fileModTime)fmt.Printf("isDir is %#v\n", isDir)fmt.Printf("fileSys is %#v\n", fileSys)
}

3. type FileMode

FileModel 的方法主要用来进行判断和输出权限。

type FileMode uint32

FileMode 代表文件的模式和权限位。这些字位在所有的操作系统都有相同的含义,因此文件的信息可以在不同的操作系统之间安全的移植。不是所有的位都能用于所有的系统,唯一共有的是用于表示目录的 ModeDir 位。

函数定义 函数说明
func (m FileMode) IsDir() bool IsDir报告m是否是一个目录
func (m FileMode) IsRegular() bool IsRegular报告m是否是一个普通文件
func (m FileMode) Perm() FileMode Perm方法返回m的Unix权限位
func (m FileMode) String() string 返回m的字符串表示

使用示例:

func main() {// Stat 返回一个描述 name 指定的文件对象的 FileInfofi, err := os.Stat("./test.log")if err != nil {fmt.Println(err)}fm := fi.Mode()   // 返回 FileMode fmt.Println(fm.IsDir())     // falsefmt.Println(fm.IsRegular()) // truefmt.Println(fm.Perm())      // -rw-rw----fmt.Println(fm.String())    // -rw-rw----
}

实际文件显示:

wohu@wohu:~/GoCode/src/task$ ll
total 20
-rw-rw-r--  1 wohu wohu  250 5月  20 09:40 main.go
-rw-rw----  1 wohu wohu    0 5月  15 10:54 test.log

4. 主要函数

4.1 os.Hostname、Exit、Getpid、Getppid、

函数定义 函数说明
func Hostname() (name string, err error) Hostname返回内核提供的主机名。
func Environ() []string Environ返回表示环境变量的格式为"key=value"的字符串的切片拷贝
func ExpandEnv(s string) string 根据当前环境变量的值替换字符串中的 ${var} 或 $var。对未定义变量的引用将被空字符串替换
func Getenv(key string) string Getenv检索并返回名为key的环境变量的值。如果不存在该环境变量会返回空字符串,要区分空值和未设置值,请使用 LookupEnv
func LookupEnv(key string) (string, bool) 检索 key 这个键对应的环境变量的值,如果该环境变量存在,则返回对应的值(可能为空),并且布尔值为 true,否则,返回值将为空,布尔值将为 false
func Setenv(key, value string) error Setenv设置名为key的环境变量。如果出错会返回该错误
func Unsetenv(key string) error 取消设置单个环境变量
func Clearenv() Clearenv删除所有环境变量(谨慎使用)
func Exit(code int) Exit让当前程序以给出的状态码code退出。一般来说,状态码0表示成功,非0表示出错。 程序会立刻终止,defer的函数不会被执行
func Getuid() int Getuid返回调用者的用户ID
func Geteuid() int Geteuid返回调用者的有效用户ID
func Getgid() int Getgid返回调用者的组ID
func Getegid() int Getegid返回调用者的有效组ID
func Getgroups() ([]int, error) Getgroups返回调用者所属的所有用户组的组ID
func Getpid() int Getpid返回调用者所在进程的进程ID
func Getppid() int Getppid返回调用者所在进程的父进程的进程ID

使用示例:

func main() {hostname, err := os.Hostname()if err != nil {fmt.Println(err)}env := os.Environ()goroot := os.Getenv("GOROOT")name := os.Getenv("NAME")fmt.Println("name is:", name)pid := os.Getpid()ppid := os.Getppid()os.Exit(0)fmt.Println(hostname)fmt.Println(env)fmt.Println(goroot)fmt.Println(pid)fmt.Println(ppid)
}

执行:

$ NAME=wohu go run main.go
name is: wohu

示例

host := os.ExpandEnv("127.0.0.1:$PORT")
fmt.Println(host)

它会将 $PORT 替换为 os.Getenv("PORT") 的值。

4.2 os.IsExist

func IsExist(err error) bool

返回一个布尔值说明该错误是否表示一个文件或目录已经存在。 ErrExist 和一些系统调用错误会使它返回真。

4.3 os.IsNotExist

func IsNotExist(err error) bool

返回一个布尔值说明该错误是否表示一个文件或目录不存在。 ErrNotExist 和一些系统调用错误会使它返回真。

4.4 os.IsPermission

func IsPermission(err error) bool

返回一个布尔值说明该错误是否表示因权限不足要求被拒绝。 ErrPermission 和一些系统调用错误会使它返回真

4.5 os.Getwd

func Getwd() (dir string, err error)

返回一个对应当前工作目录的根路径。如果当前目录可以经过多条路径抵达(因为硬链接), Getwd 会返回其中一个。

4.5 os.Chdir

func Chdir(dir string) error

将当前工作目录修改为 dir 指定的目录。如果出错,会返回 *PathError 底层类型的错误。

代码示例如下:

func main() {_, err := os.Stat("./test.log")if os.IsExist(err) {fmt.Println("test.log do not exist")}if os.IsNotExist(err) {fmt.Println("test.log exist")}curDir, err := os.Getwd()if err != nil {fmt.Println(err)}fmt.Println(curDir) // /home/wohu/GoCode/src/taskerr = os.Chdir("/opt/")if err != nil {fmt.Println(err)}chDir, err := os.Getwd()if err != nil {fmt.Println(err)}fmt.Println(chDir) // opt
}

4.6 os.Chmod

func Chmod(name string, mode FileMode) error

修改 name 指定的文件对象的 mode 。如果 name 指定的文件是一个符号链接,它会修改该链接的目的地文件的 mode 。如果出错,会返回 *PathError 底层类型的错误。

代码示例:

func main() {// Stat 返回一个描述 name 指定的文件对象的 FileInfofi, err := os.Stat("./test.log")if err != nil {fmt.Println(err)}fm := fi.Mode() // 返回 FileModefilePerm := fm.Perm()fmt.Println(filePerm) // 修改前权限为  -rw-rw----err = os.Chmod("./test.log", 0755)if err != nil {fmt.Println(err)}fi, err = os.Stat("./test.log")if err != nil {fmt.Println(err)}filePerm = fm.Perm()fmt.Println(filePerm) // 修改后权限为  -rwxr-xr-x
}

4.7 os.Chown

func Chown(name string, uid, gid int) error

修改 name 指定的文件对象的用户 id 和组 id 。如果 name 指定的文件是一个符号链接,它会修改该链接的目的地文件的用户 id 和组 id 。如果出错,会返回 *PathError 底层类型的错误。

4.8 os.Getgroups

func Getgroups() ([]int, error) 返回调用者属于的 group ,其和 chown 配合使用,改变文件属于的 group

代码示例:

func main() {fmt.Println(os.Getgroups())                //获取调用者属于的组  [4 24 27 30 46 108 124 1000]fmt.Println(os.Getgid())                   //获取调用者当前所在的组 1000fmt.Println(os.Chown("tmp.txt", 1000, 46)) //更改文件所在的组
}

4.9 os.Mkdir

func Mkdir(name string, perm FileMode) error

使用指定的权限和名称创建一个目录,仅适用于创建父目录存在且要创建的目录不存在的情况。如果要创建的目录已经存在,则会报错,如果出错,会返回 *PathError 底层类型的错误。

4.10 os.MkdirAll

func MkdirAll(path string, perm FileMode) error

使用指定的权限和名称创建一个目录,包括任何必要的上级目录,并返回 nil ,否则返回错误。权限位 perm 会应用在每一个被本函数创建的目录上。如果 path 指定了一个已经存在的目录, MkdirAll 不做任何操作并返回 nil

代码示例:

func main() {errMsg := os.Mkdir("./testDir", 0775)if errMsg != nil {fmt.Println("创建目录失败", errMsg)return}errMsg2 := os.MkdirAll("./a/b", 0775)if errMsg2 != nil {fmt.Println("创建目录失败", errMsg2)return}
}

4.11 os.Rename

func Rename(oldpath, newpath string) error

修改一个文件的名字,移动一个文件。可能会有一些个操作系统特定的限制。

4.12 os.Remove

func Remove(name string) error

删除 name 指定的文件或目录。如果是目录的话必须要求该目录为空才能删除,否则会报错,会返回 *PathError 底层类型的错误。

4.13 os.RemoveAll

func RemoveAll(path string) error

删除 path 指定的文件,或目录及它包含的任何下级对象。它会尝试删除所有东西,除非遇到错误并返回。如果 path 指定的对象不存在, RemoveAll 会返回 nil 而不返回错误。

示例代码如下:

func main() {err := os.Rename("a", "b")if err != nil {fmt.Println(err)}err = os.Remove("./b")if err != nil {fmt.Println(err)}err = os.RemoveAll("./b")if err != nil {fmt.Println(err)}
}

5. type file

type File struct {// 内含隐藏或非导出字段
}

File 代表一个打开的文件对象。

5.1 返回文件对象的函数

5.1.1 os.Create

func Create(name string) (file *File, err error)

Create 采用模式 0666(任何人都可读写,不可执行)创建一个名为 name 的文件,如果文件已存在会截断它(为空文件)。如果成功,返回的文件对象可用于 I/O ;对应的文件描述符具有 O_RDWR 模式。如果出错,错误底层类型是 *PathError

5.1.2 os.Open

func Open(name string) (file *File, err error)

Open 打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有 O_RDONLY 模式。如果出错,错误底层类型是 *PathError

该函数只能以只读模式打开文件。换句话说,我们只能从该函数返回的File值中读取内容,而不能向它写入任何内容。

5.1.3 os.OpenFile

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

OpenFile 是一个更一般性的文件打开函数,大多数调用者都应用 OpenCreate 代替本函数。它会使用指定的选项(如 O_RDONLY 等)、指定的模式(如 0666 等)打开指定名称的文件。如果操作成功,返回的文件对象可用于 I/O 。如果出错,错误底层类型是 *PathError

这个函数其实是 os.Create 函数和 os.Open 函数的底层支持,它最为灵活。这个函数有 3 个参数,分别名为 nameflagperm 。其中的 name 指代的就是文件的路径。而 flag 参数指的则是需要施加在文件描述符之上的模式,我在前面提到的只读模式就是这里的一个可选项。在 Go 语言中,这个只读模式由常量 os.O_RDONLY 代表,它是 int 类型的。当然了,这里除了只读模式之外,还有几个别的模式可选。

5.1.4 os.NewFile

func NewFile(fd uintptr, name string) *File

NewFile 使用给出的 Unix 文件描述符和名称创建一个文件。该函数在被调用的时候,需要接受一个代表文件描述符的、uintptr 类型的值,以及一个用于表示文件名的字符串值。

注意,不要被这个函数的名称误导了,它的功能并不是创建一个新的文件,而是依据一个已经存在的文件的描述符,来新建一个包装了该文件的 File 值。

eg:像这样拿到一个包装了标准错误输出的 File值。

file3 := os.NewFile(uintptr(syscall.Stderr), "/dev/stderr")if file3 != nil {defer file3.Close()file3.WriteString("The Go language program writes the contents into stderr.\n")
}


图片来源: https://time.geekbang.org/column/article/68779

5.2 文件对象的方法

func (f *File) Name() string

Name 方法返回(提供给 Open/Create 等方法的)文件名称。

func (f *File) Stat() (fi FileInfo, err error)

Stat 返回描述文件 fFileInfo 类型值。如果出错,错误底层类型是 *PathError

func (f *File) Fd() uintptr

Fd 返回与文件 f 对应的整数类型的 Unix 文件描述符。

func (f *File) Chdir() error

Chdir 将当前工作目录修改为 ff 必须是一个目录。如果出错,错误底层类型是 *PathError

func (f *File) Chmod(mode FileMode) error

Chmod 修改文件的模式。如果出错,错误底层类型是 *PathError

func (f *File) Chown(uid, gid int) error

Chown 修改文件的用户 ID 和组 ID 。如果出错,错误底层类型是 *PathError

func (f *File) Readdir(n int) (fi []FileInfo, err error)

Readdir 读取目录 f 的内容,返回一个有 n 个成员的 []FileInfo ,这些 FileInfo 是被 Lstat 返回的,采用目录顺序。对本函数的下一次调用会返回上一次调用剩余未读取的内容的信息。

如果 n>0Readdir 函数会返回一个最多 n 个成员的切片。这时,如果 Readdir 返回一个空切片,它会返回一个非 nil 的错误说明原因。如果到达了目录 f 的结尾,返回值 err 会是 io.EOF

如果 n<=0Readdir 函数返回目录中剩余所有文件对象的 FileInfo 构成的切片。此时,如果 Readdir 调用成功(读取所有内容直到结尾),它会返回该切片和 nil 的错误值。如果在到达结尾前遇到错误,会返回之前成功读取的 FileInfo 构成的切片和该错误。

func (f *File) Readdirnames(n int) (names []string, err error)

Readdirnames 读取并返回目录 f 里面的文件的名字切片。

如果 n>0Readdirnames 返回最多 n 个名字。在这种情况下,如果 Readdirnames 返回一个空的切片,它会返回一个非空的错误来解释原因。在目录的结尾,错误为 EOF

如果 n<0Readdirnames 返回目录下所有的文件的名字,用一个切片表示。在这种情况下,如果用一个切片表示成功(读取直到目录结尾),它返回切片和一个空的错误。如果在目录结尾之前遇到了一个错误, Readdirnames 返回直到当前所读到的 names 和一个非空的错误。

func (f *File) Truncate(size int64) error

Truncate 改变文件的大小,它不会改变 I/O 的当前位置。 如果截断文件,多出的部分就会被丢弃。如果出错,错误底层类型是 *PathError

func (f *File) Read(b []byte) (n int, err error)

Read 方法从 f 中读取最多 len(b) 字节数据并写入 b 。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取 0 个字节且返回值 errio.EOF

func (f *File) ReadAt(b []byte, off int64) (n int, err error)

ReadAt 从指定的位置(相对于文件开始位置)读取 len(b) 字节数据并写入 b 。它返回读取的字节数和可能遇到的任何错误。当 n<len(b) 时,本方法总是会返回错误;如果是因为到达文件结尾,返回值 err 会是 io.EOF

func (f *File) Write(b []byte) (n int, err error)

Write 向文件中写入 len(b) 字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值 n!=len(b) ,本方法会返回一个非 nil 的错误。

func (f *File) WriteString(s string) (ret int, err error)

WriteString 类似 Write ,但接受一个字符串参数。

func (f *File) WriteAt(b []byte, off int64) (n int, err error)

WriteAt 在指定的位置(相对于文件开始位置)写入 len(b) 字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值 n!=len(b) ,本方法会返回一个非 nil 的错误。

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

Seek 设置下一次读/写的位置。

6. 用于File值的操作模式

针对 File 值的操作模式主要有只读模式、只写模式和读写模式。这些模式分别由常量 os.O_RDONLYos.O_WRONLYos.O_RDWR 代表。

在我们新建或打开一个文件的时候,必须把这三个模式中的一个设定为此文件的操作模式。除此之外,我们还可以为这里的文件设置额外的操作模式,可选项如下所示。

  • os.O_APPEND 当向文件中写入内容时,把新内容追加到现有内容的后边。
  • os.O_CREATE 当给定路径上的文件不存在时,创建一个新文件。
  • os.O_EXCL 需要与 os.O_CREATE 一同使用,表示在给定的路径上不能有已存在的文件。
  • os.O_SYNC 在打开的文件之上实施同步 I/O。它会保证读写的内容总会与硬盘上的数据保持同步。
  • os.O_TRUNC 如果文件已存在,并且是常规的文件,那么就先清空其中已经存在的任何内容。

对于以上操作模式的使用,os.Create 函数和 os.Open 函数都是现成的例子。

func Create(name string) (*File, error) { return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

os.Create 函数在调用 os.OpenFile 函数的时候,给予的操作模式是 os.O_RDWRos.O_CREATEos.O_TRUNC 的组合。

这就基本上决定了前者的行为,即:如果参数 name 代表路径之上的文件不存在,那么就新建一个,否则,先清空现存文件中的全部内容。并且,它返回的 File 值的读取方法和写入方法都是可用的。

这里需要注意,多个操作模式是通过按位或操作符|组合起来的。

func Open(name string) (*File, error) {return OpenFile(name, O_RDONLY, 0)
}

os.Open 函数的功能是:以只读模式打开已经存在的文件。其根源就是它在调用 os.OpenFile 函数的时候,只提供了一个单一的操作模式 os.O_RDONLY

7. 设定常规文件的访问权限

我们已经知道,os.OpenFile 函数的第三个参数 perm 代表的是权限模式,其类型是 os.FileMode

但实际上,os.FileMode 类型能够代表的,可远不只权限模式,它还可以代表文件模式(也可以称之为文件种类)。

由于 os.FileMode 是基于 uint32 类型的再定义类型,所以它的每个值都包含了 32 个比特位。在这 32 个比特位当中,每个比特位都有其特定的含义。

比如,如果在其最高比特位上的二进制数是1,那么该值表示的文件模式就等同于 os.ModeDir ,也就是说,相应的文件代表的是一个目录。又比如,如果其中的第 26 个比特位上的是1,那么相应的值表示的文件模式就等同于 os.ModeNamedPipe ,也就是说,那个文件代表的是一个命名管道。

实际上,在一个 os.FileMode 类型的值(以下简称 FileMode 值)中,只有最低的 9 个比特位才用于表示文件的权限。当我们拿到一个此类型的值时,可以把它和 os.ModePerm 常量的值做按位与操作。这个常量的值是0777,是一个八进制的无符号整数,其最低的 9 个比特位上都是1,而更高的 23 个比特位上都是0。所以,经过这样的按位与操作之后,我们即可得到这个 FileMode 值中所有用于表示文件权限的比特位,也就是该值所表示的权限模式。

这将会与我们调用 FileMode 值的 Perm 方法所得到的结果值是一致。在这 9 个用于表示文件权限的比特位中,每 3 个比特位为一组,共可分为 3 组。从高到低,这 3 组分别表示的是文件所有者(也就是创建这个文件的那个用户)、文件所有者所属的用户组,以及其他用户对该文件的访问权限。而对于每个组,其中的 3 个比特位从高到低分别表示读权限、写权限和执行权限。如果在其中的某个比特位上的是1,那么就意味着相应的权限开启,否则,就表示相应的权限关闭。

因此,八进制整数 0777 就表示:操作系统中的所有用户都对当前的文件有读、写和执行的权限,而八进制整数 0666 则表示:所有用户都对当前文件有读和写的权限,但都没有执行的权限。我们在调用 os.OpenFile 函数的时候,可以根据以上说明设置它的第三个参数。

但要注意,只有在新建文件的时候,这里的第三个参数值才是有效的。在其他情况下,即使我们设置了此参数,也不会对目标文件产生任何的影响。

8. os 中关于进程的操作

参考:

https://studygolang.com/pkgdoc
https://www.cnblogs.com/sunailong/p/7554013.html
https://blog.csdn.net/weiyuefei/article/details/77892871

Go 学习笔记(44)— Go 标准库之 os(获取文件状态、获取/修改文件权限、创建、删除目录和文件、获取进程ID、设置获取环境变量)相关推荐

  1. python基础教程_学习笔记14:标准库:一些最爱——re

    标准库:一些最爱 re re模块包括对正則表達式的支持,由于以前系统学习过正則表達式,所以基础内容略过,直接看python对于正則表達式的支持. 正則表達式的学习,见<Mastering Reg ...

  2. python基础课程_学习笔记13:标准库:有些收藏夹——sys

    标准库:有些收藏夹 sys sys这个模块可以让你访问和python解释器联系紧密的变量和函数. sys模块中一些重要的函数和变量 函数/变量 描写叙述 argv 命令行參数,包含脚本名称 exit( ...

  3. Python学习笔记: Python 标准库概览二

    本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...

  4. Python学习笔记: Python 标准库概览

    本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...

  5. python标准库os.path中_Python零基础入门学习19:常用标准库之os.path子库

    注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性. 本文阅读时间约为3~5分钟. os库是Python标准库,包含几百个函数.它能处理与系统相关的常用路径操作.进程管理.环境参数等 ...

  6. Python学习笔记17:标准库之数学相关(math包,random包)

    前面几节看得真心累.如今先来点简单easy理解的内容. 一 math包 math包主要处理数学相关的运算. 常数 math.e   # 自然常数e math.pi  # 圆周率pi 运算函数 math ...

  7. Python学习笔记14:标准库之信号量(signal包)

    signal包负责在Python程序内部处理信号.典型的操作包含预设信号处理函数,暂停并等待信号,以及定时发出SIGALRM等. 要注意,signal包主要是针对UNIX平台(比方Linux, MAC ...

  8. Javaweb学习笔记(JSP标准标签库)

    Javaweb学习笔记(JSP标准标签库) JSTL入门 安装和测试JSTL JSTL中的Core标签库 < c:out>标签 标签 标签 < c:catch>标签 标签 标签 ...

  9. STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料

    STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料 微雪课堂:http://www.waveshare.net/study/article-629-1.html 之前的正点原 ...

最新文章

  1. Windows 10 开发日记(五)-- 当Binding遇到异步 -- 解决方案
  2. 农业物联网技术在温室大棚种植中的应用
  3. 高级mysql优化知识_MySQL高级第三篇(索引优化分析)
  4. 跟我一起数据挖掘(10)——HP Vertica
  5. 基于DM642的X264开源代码实现的研究
  6. 产品运行所需的信息检索失败_为服务业注入新活力,华北工控推出服务机器人专用计算机产品方案...
  7. OpenStack_I版 1.准备过程
  8. excel实战应用案例100讲(五)-excel实现南丁格尔玫瑰图制作
  9. 【POJ】2065 SETI
  10. 管理软件实施(2)——开发包括哪些成本
  11. Contoso 大学 - 3 - 排序、过滤及分页
  12. 【递归】n个数的全排列
  13. disruptor小结--消费者
  14. 1007. 素数对猜想 (20)-PAT乙级真题
  15. AutoCAD .Net 创建Ribbon界面(一)
  16. 项目开发中DEV、QAS、PRD是什么意思
  17. Latex之页边距设置
  18. C语言Dialogbox添加图片,dialogbox_传奇服务端CloseBigDialogBox是什么意思
  19. 跨专业保研上交计算机,新闻学到经济学,跨专业保研血泪史
  20. Android获取系统信息

热门文章

  1. 2022-2028年全球与中国氢碘化物市场智研瞻分析报告
  2. 2022-2028年中国机制砂石行业投资分析及前景预测报告
  3. 2022-2028年中国轻型输送带行业市场发展规模及市场分析预测报告
  4. Python gRPC 安装
  5. dataframe,python,numpy 问题索引2
  6. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)
  7. OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)?
  8. 代码生成codegen
  9. TinyML-TVM是如何驯服Tiny的(下)
  10. YOLOV4各个创新功能模块技术分析(一)