2012-09-13 9 views
6

Estoy tratando de tomar la entrada desde el teclado y luego almacenarla en un archivo de texto, pero estoy un poco confundido sobre cómo hacerlo realmente.Intentar escribir entrada desde el teclado en un archivo en Golang

Mi código actual es la siguiente en la actualidad

// 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,) 

Hay tantas funciones en el "OS" y paquetes "io". Estoy muy confundido sobre cuál debería usar para este propósito.

También estoy confundido sobre cuál debería ser el tercer argumento en la función WriteFile. En la documentación se dice de tipo "perm os.FileMode", pero como soy nuevo en la programación y voy, estoy un poco despistado.

¿Alguien tiene algún consejo sobre cómo proceder? Gracias de antemano, Marie

+1

¿Desea agregar la nueva entrada de usuario al final del archivo o reemplazar el archivo anterior con la nueva entrada? – matthias

+0

Agréguelo al final del archivo. – miner

+3

[this] (http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions) podría ayudar a comprender cuáles son los permisos requeridos por algunas funciones. 0666 por ejemplo significa (en forma octal) que un archivo debe ser legible y escribible por todos (el usuario, su grupo, el mundo). –

Respuesta

2
// 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") 
    } 
} 

me he asegurado de esta compila y se ejecuta en play.golang.org, pero no estoy en mi máquina dev, entonces no puedo verificar que esté interactuando con Stdin y el archivo completamente correctamente. Sin embargo, esto debería hacerte comenzar.

+0

Gracias, ¡Realmente me ayudó! – miner

3

Por ejemplo,

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

Creo que explicar el '0666' ayudaría a OP. –

+2

¿Estás aquí para explicar, para responder o para resolver? Espera, no respondas! Ya puedo verlo – Kissaki

2

Si simplemente desea agregar la entrada del usuario a un archivo de texto, puede simplemente leer la entrada como ya lo hizo y usar ioutil.WriteFile, como lo ha intentado hacer. Así que ya tienes la idea correcta.

Para hacer su camino ir, la solución simplificada sería la siguiente:

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

El último parámetro de WriteFile es una bandera que especifica las distintas opciones para archivos. Los bits más altos son opciones como tipo de archivo (os.ModeDir, por ejemplo) y los bits inferiores representan los permisos en forma de permisos UNIX (0666, en formato octal, representa el usuario rw, grupo rw, otros rw). Ver the documentation para más detalles.

Ahora que su código funciona, podemos mejorarlo. Por ejemplo, manteniendo el archivo abierto en lugar de abrirlo en dos ocasiones:

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

La magia aquí es, que utiliza el indicador de os.O_APPEND al abrir el archivo, lo que hace que file.WriteString() anexión. Tenga en cuenta que debe cerrar el archivo después de abriéndolo, lo que hacemos después de que la función existe utilizando la palabra clave defer.

+0

Gracias por los ejemplos de código, realmente me ayudó a entender este problema y cómo resolverlo. – miner

Cuestiones relacionadas