我有许多小文件,不想逐行读取它们。
在Go语言中是否存在将整个文件读入字符串变量的函数?
ioutil
包现已弃用:“弃用:自Go 1.16起,相同功能现在由io包或os包提供,并且应优先选择这些实现来编写新代码。有关详细信息,请参阅特定函数文档。”由于Go的兼容性承诺,ioutil.ReadMe
是安全的,但@openwonk的更新答案对于新代码更好。
ioutil.ReadFile
:func ReadFile(filename string) ([]byte, error)
s := string(buf)
如果您只想获取内容的string
,那么简单的解决方案是使用io/ioutil
包中的ReadFile
函数。此函数返回一个bytes
切片,您可以轻松将其转换为string
。
Go 1.16或更新版本:
对于此示例,请将ioutil
替换为os
。
package main
import (
"fmt"
"os"
)
func main() {
b, err := os.ReadFile("file.txt") // just pass the file name
if err != nil {
fmt.Print(err)
}
fmt.Println(b) // print the content as 'bytes'
str := string(b) // convert content to a 'string'
fmt.Println(str) // print the content as a 'string'
}
Go 1.15或更早版本
package main
import (
"fmt"
"io/ioutil"
)
func main() {
b, err := ioutil.ReadFile("file.txt") // just pass the file name
if err != nil {
fmt.Print(err)
}
fmt.Println(b) // print the content as 'bytes'
str := string(b) // convert content to a 'string'
fmt.Println(str) // print the content as a 'string'
}
os
包更新了答案。 - openwonk我认为,如果你真的担心将所有这些文件连接起来的效率问题,最好的方法是将它们全部复制到同一个字节缓冲区中。
buf := bytes.NewBuffer(nil)
for _, filename := range filenames {
f, _ := os.Open(filename) // Error handling elided for brevity.
io.Copy(buf, f) // Error handling elided for brevity.
f.Close()
}
s := string(buf.Bytes())
这将打开每个文件,将其内容复制到buf中,然后关闭文件。根据您的情况,您可能实际上不需要进行转换,最后一行只是为了显示buf.Bytes()包含您要查找的数据。
这是我完成它的方法:
package main
import (
"fmt"
"os"
"bytes"
"log"
)
func main() {
filerc, err := os.Open("filename")
if err != nil{
log.Fatal(err)
}
defer filerc.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(filerc)
contents := buf.String()
fmt.Print(contents)
}
package main
import (
"io"
"os"
"strings"
)
func main() {
f, err := os.Open("file.txt")
if err != nil {
panic(err)
}
defer f.Close()
b := new(strings.Builder)
io.Copy(b, f)
print(b.String())
}
如果您不介意使用[]byte
,可以使用os.ReadFile:
package main
import "os"
func main() {
b, err := os.ReadFile("file.txt")
if err != nil {
panic(err)
}
os.Stdout.Write(b)
}
io.Copy(b, f)
之前,我们可以使用 fi, _ := f.Stat()
和 b.Grow(int(fi.Size()))
。 - bartolo-otrit我不在电脑旁边,所以我写了一个草稿。你可能明白我在说什么。
func main(){
const dir = "/etc/"
filesInfo, e := ioutil.ReadDir(dir)
var fileNames = make([]string, 0, 10)
for i,v:=range filesInfo{
if !v.IsDir() {
fileNames = append(fileNames, v.Name())
}
}
var fileNumber = len(fileNames)
var contents = make([]string, fileNumber, 10)
wg := sync.WaitGroup{}
wg.Add(fileNumber)
for i,_:=range content {
go func(i int){
defer wg.Done()
buf,e := ioutil.Readfile(fmt.Printf("%s/%s", dir, fileName[i]))
defer file.Close()
content[i] = string(buf)
}(i)
}
wg.Wait()
}