2012-09-13 9 views
6

Próbuję wprowadzić dane wejściowe z klawiatury, a następnie zapisać je w pliku tekstowym, ale jestem trochę zdezorientowany, jak to zrobić.Próbujesz zapisać dane wejściowe z klawiatury do pliku w Golang

Mój obecny kod jest jak postępować w tej chwili:

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

Jest tak wiele funkcji w „OS” i „IO” pakietów. Jestem bardzo zdezorientowany, który z nich powinienem użyć w tym celu.

Jestem również zdezorientowany tym, jaki powinien być trzeci argument funkcji WriteFile. W dokumentacji mówi się o typie "perm os.FileMode", ale ponieważ jestem nowy w programowaniu i Go, jestem trochę nieświadomy.

Czy ktoś ma jakieś wskazówki dotyczące postępowania? Dzięki z góry, Marie

+1

Czy chcesz dodać nowe dane wejściowe użytkownika na końcu pliku, czy zastąpić stary plik nowymi danymi wejściowymi? – matthias

+0

Dodaj go na końcu pliku. – miner

+3

[this] (http://en.wikipedia.org/wiki/Filesystem_permissions#Traditional_Unix_permissions) może pomóc zrozumieć, jakie są uprawnienia wymagane przez niektóre funkcje. 0666 na przykład oznacza (w formie ósemkowej), że plik musi być czytelny i zapisywalny dla wszystkich (użytkownik, jego grupa, świat). –

Odpowiedz

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

Zrobiłem pewien, że to kompiluje i działa na play.golang.org, ale nie jestem w moim komputerze dev, więc nie mogę zweryfikować, czy interakcja ze Stdinem i plikiem jest całkowicie poprawna. To powinno cię jednak zacząć.

+0

Dziękuję, naprawdę mi pomogło! – miner

3

Na przykład,

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

Myślę, że wyjaśnienie '0666' pomoże OP. –

+2

Czy jesteś tutaj, aby wyjaśnić, odpowiedzieć lub rozwiązać? Zaczekaj, nie odpowiadaj! Już to widzę. – Kissaki

2

Jeśli chcesz po prostu dołączyć dane użytkownika do pliku tekstowego, możesz po prostu przeczytać dane wejściowe , tak jak już zrobiłeś, i używać ioutil.WriteFile. Masz już dobry pomysł.

aby się udać, uproszczone rozwiązanie byłoby to:

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

Ostatnim parametrem WriteFile jest flaga, która określa różne opcje plików. Wyższe bity to opcje takie jak typ pliku (na przykład os.ModeDir), a niższe bity reprezentują uprawnienia w postaci uprawnień UNIX (0666, w formacie ósemkowym, oznacza użytkownika rw, grupa rw, inne rw). Aby uzyskać więcej informacji, patrz the documentation.

Teraz twój kod działa, możemy go poprawić. Na przykład poprzez utrzymywanie otwarty plik zamiast otwierania go dwukrotnie:

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

Magia o to, że należy użyć flagi os.O_APPEND podczas otwierania pliku, co sprawia file.WriteString() dopisywania. Zauważ, że musisz zamknąć plik po otwarciu go przez , co robimy po tym, jak funkcja istnieje, używając słowa kluczowego defer.

+0

Dziękuję za przykłady kodu, to naprawdę pomogło mi zrozumieć ten problem i jak go rozwiązać. – miner

Powiązane problemy