【问题标题】:What does the os.Stdin store and what does it mean?os.Stdin 存储是什么,它是什么意思?
【发布时间】:2022-01-25 13:23:18
【问题描述】:

当我在 golang 中运行 fmt.Println(*os.Stdin) 时,输出是这个内存地址 {0xc000182000} 这个地址是什么意思?阅读是如何工作的?

【问题讨论】:

  • 这并不意味着什么。通过调用 read 方法从 os.Stdin 读取。你不会从 fmt.Prinln 的东西中学习。
  • 程序显示os.File的字段。有关如何实现 os.File 的信息,请参阅 source code。 Go 程序员很少能窥探到这些细节。

标签: go pointers operating-system stdin


【解决方案1】:

找出正在发生的事情的最佳方法是查看标准库中的代码。最简单的方法就是用谷歌搜索:

https://www.google.com/search?q=os.Stdin

前几个链接中有一个网址

pkg.go.dev/os

在那里你可以找到标准输入的定义:

Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")

那么 NewFile 生成什么函数呢?

https://pkg.go.dev/os#NewFile

NewFile 返回具有给定文件描述符和名称的新文件。如果 fd 不是有效的文件描述符,则返回值将为 nil。在 Unix 系统上,如果文件描述符处于非阻塞模式,NewFile 将尝试返回一个可轮询文件(SetDeadline 方法适用的文件)。 将其传递给 NewFile 后,fd 可能会在 Fd 方法的 cmets 中描述的相同条件下变得无效,并且适用相同的约束。

这意味着 NewFile 将返回指向表示文件的结构的指针。

// File represents an open file descriptor.
type File struct {
    *file // os specific
}

好的,这意味着 os.Stdin 代表一个文件。但是我们可以用那个 File 结构上的指针做什么呢?如果我们将其用作 fmt.Println 的参数,我们将获得该指针存储在内存中的地址。但是该结构具有 Read 方法。我们可以在 os/file.go 文件中找到为该 File 结构实现的所有方法。

https://cs.opensource.google/go/go/+/refs/tags/go1.17.5:src/os/file.go;l=112;drc=a25c58462992704dbb6819769f530b6cc6a8ebe3

有一个 Read 方法可以将底层文件中的字节读取到作为方法参数提供的字节数组中。

package main

import (
    "fmt"
    "io"
    "log"
    "os"
)

func main() {
    byteSlice := []byte{}

    b1 := make([]byte, 1)
    for {
        _, err := os.Stdin.Read(b1)
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Printf("Unknown error: %+v ", err.Error())
            os.Exit(1)
        }
        byteSlice = append(byteSlice, b1...)
    }

    fmt.Printf("we read: %s \n", string(byteSlice))
}

此代码效率极低,应仅用于演示目的。但我希望您了解如何从 os.Stdin 中读取以及 stdin 代表什么。

【讨论】:

    猜你喜欢
    • 2011-04-21
    • 1970-01-01
    • 2011-08-12
    • 2017-06-11
    • 2018-03-05
    • 2023-03-27
    • 2011-07-05
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多