英文:
How to read a text file?
问题
我正在尝试使用Golang读取"file.txt"文件,并将其内容放入一个变量中。以下是我尝试过的代码:
package main
import (
"fmt"
"os"
"log"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
fmt.Print(file)
}
文件成功读取,并且os.Open的返回类型是os.File。
英文:
I'm trying to read "file.txt" and put the contents into a variable using Golang. Here is what I've tried...
package main
import (
"fmt"
"os"
"log"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
fmt.Print(file)
}
The file gets read successfully and the return from os.Open returns a type of *os.File
答案1
得分: 131
这取决于你想要做什么。
file, err := os.Open("file.txt")
fmt.print(file)
它输出&{0xc082016240}
是因为你打印的是文件描述符(*os.File
)的指针值,而不是文件内容。要获取文件内容,你可以从文件描述符中进行读取。
要将文件的所有内容(以字节形式)读取到内存中,可以使用ioutil.ReadAll
。
package main
import (
"fmt"
"io/ioutil"
"os"
"log"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
b, err := ioutil.ReadAll(file)
fmt.Print(b)
}
但是,有时候如果文件大小很大,只读取一部分(缓冲区大小)可能更节省内存,因此你可以使用*os.File
的io.Reader.Read
实现。
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
buf := make([]byte, 32*1024) // 在这里定义你的缓冲区大小。
for {
n, err := file.Read(buf)
if n > 0 {
fmt.Print(buf[:n]) // 你的读取缓冲区。
}
if err == io.EOF {
break
}
if err != nil {
log.Printf("read %d bytes: %v", n, err)
break
}
}
}
另外,你还可以使用标准库bufio
中的Scanner
来处理文件。Scanner
按分隔符将文件读取为标记。
默认情况下,Scanner
使用换行符作为分隔符(当然你可以自定义Scanner
如何将文件分词,可以从这里了解更多信息:bufio测试)。
package main
import (
"fmt"
"os"
"log"
"bufio"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
scanner := bufio.NewScanner(file)
for scanner.Scan() { // 内部根据分隔符推进标记
fmt.Println(scanner.Text()) // 以Unicode字符形式的标记
fmt.Println(scanner.Bytes()) // 以字节形式的标记
}
}
最后,我还想向你推荐这个很棒的网站:Go语言文件速查表。它涵盖了与Go语言文件操作相关的几乎所有内容,希望你会觉得有用。
英文:
It depends on what you are trying to do.
file, err := os.Open("file.txt")
fmt.print(file)
The reason it outputs &{0xc082016240}, is because you are printing the pointer value of a file-descriptor (*os.File
), not file-content. To obtain file-content, you may READ
from a file-descriptor.
To read all file content(in bytes) to memory, ioutil.ReadAll
package main
import (
"fmt"
"io/ioutil"
"os"
"log"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
b, err := ioutil.ReadAll(file)
fmt.Print(b)
}
But sometimes, if the file size is big, it might be more memory-efficient to just read in chunks: buffer-size, hence you could use the implementation of io.Reader.Read
from *os.File
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
buf := make([]byte, 32*1024) // define your buffer size here.
for {
n, err := file.Read(buf)
if n > 0 {
fmt.Print(buf[:n]) // your read buffer.
}
if err == io.EOF {
break
}
if err != nil {
log.Printf("read %d bytes: %v", n, err)
break
}
}
}
Otherwise, you could also use the standard util package: bufio
, try Scanner
. A Scanner
reads your file in tokens: separator.
By default, scanner advances the token by newline (of course you can customise how scanner should tokenise your file, learn from here the bufio test).
package main
import (
"fmt"
"os"
"log"
"bufio"
)
func main() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
scanner := bufio.NewScanner(file)
for scanner.Scan() { // internally, it advances token based on sperator
fmt.Println(scanner.Text()) // token in unicode-char
fmt.Println(scanner.Bytes()) // token in bytes
}
}
Lastly, I would also like to reference you to this awesome site: go-lang file cheatsheet. It encompassed pretty much everything related to working with files in go-lang, hope you'll find it useful.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论