How to write to a file in golang

huangapple go评论82阅读模式
英文:

How to write to a file in golang

问题

我正在尝试写入文件。我已经读取了文件的全部内容,现在我想根据文件中获取的某个单词来更改文件的内容。但是当我检查文件的内容时,它仍然是相同的,没有发生变化。这是我使用的代码:

if strings.Contains(string(read), sam) {
    fmt.Println("文件包含该单词")
    temp := strings.ToUpper(sam)
    fmt.Println(temp)
    err := ioutil.WriteFile(fi.Name(), []byte(temp), 0644)
} else {
    fmt.Println("文件中没有该单词")
}

请注意,这只是代码的翻译部分,不包括任何其他内容。

英文:

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

答案1

得分: 26

考虑到你对ioutil.WriteFile()的调用与“Go by Example: Writing Files”中使用的方式一致,这应该可以工作。

但是,Go by example文章在写入调用之后立即检查错误。

你在测试范围之外检查错误:

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)   // <===== 太晚了
}

你测试的错误是在读取文件(ioutil.ReadFile)时得到的错误,这是因为块和作用域的原因。

你需要在写入调用之后立即检查错误:

err = ioutil.WriteFile(fi.Name(), []byte(Value), 0644)
check(err)   // <===== 太晚了

由于WriteFile会覆盖整个文件,你可以使用strings.Replace()将单词替换为其大写形式:

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

如果要进行不区分大小写的替换,可以像“How do I do a case insensitive regular expression in 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内容开头和结尾的任何单词(而不是查找包含sam内容的子字符串)。如果要替换子字符串,只需去掉\b

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

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(&quot; This is the name of the file&quot;, fi.Name())
		if strings.Contains(string(read), sam) {
			fmt.Println(&quot;this file contain that word&quot;)
			Value := strings.ToUpper(sam)
			fmt.Println(Value)
			err = ioutil.WriteFile(fi.Name(), []byte(Value), 0644)
		} else {
			fmt.Println(&quot; the word is not in the file&quot;)
		}
		check(err)   &lt;===== 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)   &lt;===== 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(&quot;(?i)\\b&quot;+sam+&quot;\\b&quot;)
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(&quot;(?i)&quot;+sam)

答案2

得分: 2

这是一个用Go语言编写的程序,它的功能是在文件中将指定的单词转换为大写。以下是翻译好的代码:

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("大写字母比小写字母长:" + 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() {
	// 测试文件
	filename := `ltoucase.txt`

	// 创建测试文件
	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
	}

	// 读取测试文件
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(data))

	// 更新测试文件中的单词
	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
英文:

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

package main
import (
&quot;bytes&quot;
&quot;errors&quot;
&quot;fmt&quot;
&quot;io/ioutil&quot;
&quot;os&quot;
)
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) &lt; len(uWord) {
err := errors.New(&quot;Upper case longer than lower case:&quot; + string(word))
return n, err
}
if len(word) &gt; len(uWord) {
uWord = append(uWord, bytes.Repeat([]byte{&#39; &#39;}, len(word))...)[:len(word)]
}
off := int64(0)
for {
i := bytes.Index(data[off:], word)
if i &lt; 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(&quot;update&quot;)
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

huangapple
  • 本文由 发表于 2014年7月18日 03:19:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/24811770.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定