Как написать файл в golang

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

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

Ответ 1

Учитывая, что ваш вызов ioutil.WriteFile() соответствует тому, что используется в Перейти по примеру: Написание файлов ", это должно работать.

Но это Go в примере статьи проверяет ошибку сразу после вызова записи.

Вы проверяете ошибку вне области вашего теста:

    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
    }

Ошибка, которую вы тестируете, - это тот, который вы получили при чтении файла (ioutil.ReadFile), из-за блоков и области.

Вам нужно проверить ошибку сразу после вызова

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

Так как WriteFile перезаписывает весь файл, вы можете strings.Replace() заменить свое слово на его верхний регистр:

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

Для замены, которая нечувствительна к регистру, используйте регулярное выражение, как в Как сделать независимое от регистра регулярное выражение в Go? ".
Используйте 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)

Обратите внимание на \b: граница слова, чтобы найти любое слово, начинающееся и заканчивающееся sam content (вместо того, чтобы находить подстроки, содержащие контент sam).
Если вы хотите заменить подстроки, просто отпустите \b:

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

Ответ 2

Не понятно, что вы хотите сделать. Мое лучшее предположение - это что-то вроде этого:

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

Вывод:

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