Golang重定向fmt.Scanf以从文件而不是os.Stdin读取

时间:2017-09-25 07:06:41

标签: redirect go stdin

通常当我们在Golang中调用fmt.Scanf()时,程序将从标准输入流中读取,即os.stdin

我想通过Golang代码让fmt.Scanf()从文件流中读取 - 与technique in Python here类似。

请注意,我们在命令行级别有管道解决方法;在这里,我正在寻找in-Golang代码解决方案。

如果您知道如何到达那里,请分享。

P.S。

我想这需要我们

  • 从文件流中读取并存储在字符串变量bytes
  • bytes分配给os.stdin

虽然我是Golang的新手,而我google search的帮助不大,所以我在这里问过。

1 个答案:

答案 0 :(得分:4)

将文件设置为os.Stdin

如果这真的是你想要的:os.Stdin是一个变量(类型为*os.File),您可以根据自己的喜好进行修改,可以为其指定一个新值。打开文件并将其分配给os.Stdinfmt.Scanf()将直接从该文件中读取。有关详细信息,请参阅Fill os.Stdin for function that reads from it

这是一个完整的示例,它打开一个名为a.txt的文件,将其设置为os.Stdin,然后调用fmt.Scanf()string读取os.Stdin值(间接来自a.txt文件。下面的代码还处理保存和恢复os.Stdin的原始值。这里不需要它,但它可以作为一个例子,恢复你暂时修改的全局内容也是一个好习惯。

f, err := os.Open("a.txt")
if err != nil {
    panic(err)
}
defer f.Close()

oldStdin := os.Stdin
defer func() { os.Stdin = oldStdin }()

os.Stdin = f

var s string
if _, err := fmt.Scanf("%s", &s); err != nil {
    fmt.Printf("Error reading: %v", err)
}
fmt.Println("Read:", s)

请注意,您还可以将os.Stdout重定向到以下文件:

f2, err := os.Create("out.txt")
if err != nil {
    panic(err)
}
defer f2.Close()

oldStdout := os.Stdout
defer func() { os.Stdout = oldStdout }()

os.Stdout = f2

fmt.Printf("This will be written to the file: %s", f2.Name())

使用fmt.Fscanf()

更简单,更好的替代方法是使用与fmt.Scanf()类似的fmt.Fscanf(),但在这里您也可以传递io.Reader来读取和os.File实现io.Reader,因此您可以直接将文件传递给它。

将文件重定向到应用的标准输入

另一种选择是在启动应用时将文件重定向到您的应用作为其标准输入。例如:

go run myapp.go < a.txt

此命令将启动您的应用,将a.txt文件的内容流式传输到您应用的标准输入。因此fmt.Scanf()将读取a.txt文件的内容。