如何在Golang中写入文件

如何在Golang中写入文件

问题描述:

i am trying to write to to a file. i read the whole content of the file and now i want to change the content of the file based on some word that i have got from the file. but when i check, the content of the file, it is still the same and it has not change. this is what i used

if strings.Contains(string(read), sam) {
    fmt.Println("this file contain that word")
    temp := strings.ToUpper(sam)
    fmt.Println(temp)
    err := ioutil.WriteFile(fi.Name(), []byte(temp), 0644)
} else {
    fmt.Println(" the word is not in the file")
}

我正在尝试写入文件。 我读取了文件的全部内容,现在我想根据我从文件中得到的一些单词来更改文件的内容。 但是当我检查文件的内容时,它仍然是相同的,并且没有变化。 这就是我使用的 p>

 如果是strings.Contains(string(read),sam){
 fmt.Println(“此文件包含该单词”)
 temp:  = strings.ToUpper(sam)
 fmt.Println(temp)
 err:= ioutil.WriteFile(fi.Name(),[] byte(temp),0644)
}否则{
 fmt.Println(  “单词不在文件中”)
} 
  code>  pre> 
  div>

Considering that your call to ioutil.WriteFile() is consistent with what is used in "Go by Example: Writing Files", this should work.

But that Go by example article check the err just after the write call.

You check the err outside the scope of your test:

    if matched {
        read, err := ioutil.ReadFile(path)
        //fmt.Println(string(read))
        fmt.Println(" This is the name of the file", fi.Name())
        if strings.Contains(string(read), sam) {
            fmt.Println("this file contain that word")
            Value := strings.ToUpper(sam)
            fmt.Println(Value)
            err = ioutil.WriteFile(fi.Name(), []byte(Value), 0644)
        } else {
            fmt.Println(" the word is not in the file")
        }
        check(err)   <===== too late
    }

The err you are testing is the one you got when reading the file (ioutil.ReadFile), because of blocks and scope.

You need to check the error right after the Write call

            err = ioutil.WriteFile(fi.Name(), []byte(Value), 0644)
            check(err)   <===== too late

Since WriteFile overwrite the all file, you could strings.Replace() to replace your word by its upper case equivalent:

r := string(read)
r = strings.Replace(r, sam, strings.ToUpper(sam), -1)
err := ioutil.WriteFile(fi.Name(), []byte(r), 0644)

For a replace which is case insensitive, use a regexp as in "How do I do a case insensitive regular expression in Go?".
The, use func (*Regexp) ReplaceAllString:

re := regexp.MustCompile("(?i)\\b"+sam+"\\b")
r = re.ReplaceAllString(r, strings.ToUpper(sam))
err := ioutil.WriteFile(fi.Name(), []byte(r), 0644)

Note the \b: word boundary to find the any word starting and ending with sam content (instead of finding substrings containing sam content).
If you want to replace substrings, simply drop the \b:

re := regexp.MustCompile("(?i)"+sam)

It's not clear what you want to do. My best guess is something like this:

package main

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

func UpdateWord(filename string, data, word []byte) (int, error) {
    n := 0
    f, err := os.OpenFile(filename, os.O_WRONLY, 0644)
    if err != nil {
        return n, err
    }
    uWord := bytes.ToUpper(word)
    if len(word) < len(uWord) {
        err := errors.New("Upper case longer than lower case:" + string(word))
        return n, err
    }
    if len(word) > len(uWord) {
        uWord = append(uWord, bytes.Repeat([]byte{' '}, len(word))...)[:len(word)]
    }
    off := int64(0)
    for {
        i := bytes.Index(data[off:], word)
        if i < 0 {
            break
        }
        off += int64(i)
        _, err = f.WriteAt(uWord, off)
        if err != nil {
            return n, err
        }
        n++
        off += int64(len(word))
    }
    f.Close()
    if err != nil {
        return n, err
    }
    return n, nil
}

func main() {
    // Test file
    filename := `ltoucase.txt`

    // Create test file
    lcase := []byte(`update a bc def ghij update klmno pqrstu update vwxyz update`)
    perm := os.FileMode(0644)
    err := ioutil.WriteFile(filename, lcase, perm)
    if err != nil {
        fmt.Println(err)
        return
    }

    // Read test file
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(data))

    // Update word in test file
    word := []byte("update")
    n, err := UpdateWord(filename, data, word)
    if err != nil {
        fmt.Println(n, err)
        return
    }
    fmt.Println(filename, string(word), n)
    data, err = ioutil.ReadFile(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(data))
}

Output:

update a bc def ghij update klmno pqrstu update vwxyz update
ltoucase.txt update 4
UPDATE a bc def ghij UPDATE klmno pqrstu UPDATE vwxyz UPDATE