尝试在Golang中将键盘输入写入文件

7

我想从键盘输入数据并将其存储在文本文件中,但是我对如何实际操作有些困惑。

目前我的代码如下:

// reads the file txt.txt 
bs, err := ioutil.ReadFile("text.txt")
if err != nil {
      panic(err)
}

// Prints out content
textInFile := string(bs)
fmt.Println(textInFile)

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

//Now I want to write input back to file text.txt
//func WriteFile(filename string, data []byte, perm os.FileMode) error

inputData := make([]byte, len(userInput))

err := ioutil.WriteFile("text.txt", inputData, )

"os"和"io"包中有很多函数。我不确定应该使用哪一个来实现这个目的。

我对WriteFile函数中第三个参数也感到困惑。文档中写的是"perm os.FileMode"类型,但由于我刚开始学习编程和Go语言,我有点茫然。

有没有任何提示可以告诉我该怎么做呢? 谢谢, 玛丽


2
您想将新用户输入附加到文件末尾,还是用新输入替换旧文件? - matthias
将其添加到文件末尾。 - miner
3
这个链接可以帮助理解某些函数所需的权限。例如,0666表示(八进制形式)文件必须可读可写,任何人都可以访问(用户本身、他的组和其他人)。 - Denys Séguret
3个回答

3
例如,
package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    fname := "text.txt"

    // print text file
    textin, err := ioutil.ReadFile(fname)
    if err == nil {
        fmt.Println(string(textin))
    }

    // append text to file
    f, err := os.OpenFile(fname, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
    if err != nil {
        panic(err)
    }
    var textout string
    fmt.Scanln(&textout)
    _, err = f.Write([]byte(textout))
    if err != nil {
        panic(err)
    }
    f.Close()

    // print text file
    textin, err = ioutil.ReadFile(fname)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(textin))
}

2
我认为解释0666会对楼主有所帮助。 - Denys Séguret
2
你是来解释、回答还是解决问题的?等等,不要回答!我已经看出来了。 - Kissaki

3
// reads the file txt.txt 
bs, err := ioutil.ReadFile("text.txt")
if err != nil { //may want logic to create the file if it doesn't exist
      panic(err)
}

var userInput []string

var err error = nil
var n int
//read in multiple lines from user input
//until user enters the EOF char
for ln := ""; err == nil; n, err = fmt.Scanln(ln) {
    if n > 0 {  //we actually read something into the string
        userInput = append(userInput, ln)
    } //if we didn't read anything, err is probably set
}

//open the file to append to it
//0666 corresponds to unix perms rw-rw-rw-,
//which means anyone can read or write it
out, err := os.OpenFile("text.txt", os.O_APPEND, 0666)
defer out.Close() //we'll close this file as we leave scope, no matter what

if err != nil { //assuming the file didn't somehow break
    //write each of the user input lines followed by a newline
    for _, outLn := range userInput {
        io.WriteString(out, outLn+"\n")
    }
}

我已经确保这份代码在play.golang.org上可以编译和运行,但是由于我不在开发机器旁边,所以无法验证它是否正确地与标准输入和文件交互。不过这份代码至少能帮助你入门。


3
如果您只是想将用户的输入附加到文本文件中,您可以像以前一样读取输入并使用,就像您已经尝试过的那样。所以您已经有了正确的想法。
为了让您的方式行得通,简化的解决方案如下:
// Read old text
current, err := ioutil.ReadFile("text.txt")

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

// Append the new input to the old using builtin `append`
newContent := append(current, []byte(userInput)...)

// Now write the input back to file text.txt
err = ioutil.WriteFile("text.txt", newContent, 0666)
WriteFile 的最后一个参数是一个标志位,它指定文件的各种选项。较高位的选项包括文件类型(例如 os.ModeDir),而较低位则代表 UNIX 文件权限(以八进制格式表示的 0666 代表用户 rw、组 rw 和其他人 rw)。有关更多详情,请参阅文档
现在您的代码已经可用,我们可以改进它。例如,通过保持文件打开而不是两次打开文件:
// Open the file for read and write (O_RDRW), append to it if it has
// content, create it if it does not exit, use 0666 for permissions
// on creation.
file, err := os.OpenFile("text.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)

// Close the file when the surrounding function exists
defer file.Close()

// Read old content
current, err := ioutil.ReadAll(file)

// Do something with that old content, for example, print it
fmt.Println(string(current))

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

// Now write the input back to file text.txt
_, err = file.WriteString(userInput)

这里的妙处在于,打开文件时使用了 os.O_APPEND 标志,使得 file.WriteString() 实现追加写入。注意,在打开文件后需要关闭它,我们使用 defer 关键字在函数结束后实现。

感谢您提供的代码示例,它们确实帮助我理解了这个问题以及如何解决它。 - miner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接