Попытка записать ввод с клавиатуры в файл в Golang

Я пытаюсь взять ввод с клавиатуры, а затем сохранить его в текстовом файле, но я немного смущен тем, как это сделать.

мой текущий код выглядит следующим образом:

// 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. В документации говорится о тип " Пермская ОС.FileMode", но поскольку я новичок в программировании и Go, я немного невежествен.

есть ли у кого-нибудь советы о том, как proced? Спасибо заранее, Мари!--2-->

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, но я не на своей машине dev, поэтому я не могу проверить, что он взаимодействует с Stdin и файлом полностью правильно. Это должно помочь тебе начать.


например,

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))
}

если вы просто хотите добавить ввод пользователя в текстовый файл, вы можете просто прочитать введите, как вы уже сделали, и используйте ioutil.WriteFile, Как вы пытались сделать. Так у тебя уже есть правильная идея.

чтобы сделать свой путь, упрощенное решение будет следующим:

// 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). См.документация для получения более подробной информации.

теперь, когда ваш код работает, мы можем улучшить его. Например, сохраняя файл открытым вместо того чтобы открыть его дважды:--10-->

// 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 ключевое слово.