Q1mi / BlogComments

9 stars 0 forks source link

Go语言文件操作 | 李文周的博客 #17

Closed Q1mi closed 1 week ago

Q1mi commented 5 years ago

https://www.liwenzhou.com/posts/Go/go_file/

李文周的Blog Go语言文件读写 file操作

adeljck commented 5 years ago

package main

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

func readfile(filename string) { content, err := ioutil.ReadFile(filename) if err != nil { fmt.Println(err) } else { fmt.Println(string(content)) } } func getFilename() (filename string) { args := os.Args if len(args) > 1 { filename = args[1] } else { fmt.Println("no input file") } return filename } func main() { filename := getFilename() readfile(filename) }

zeusYi commented 4 years ago

bufio读取文件 代码中 “defer fileObj.Close()” 的位置应该从第17行 放到第13行吧,因为如果 line 13-- line16 中间的代码如果err!=nil,会直接return,并不会执行line 17的 defer fileObj.Close()

Q1mi commented 4 years ago

@zeusYi bufio读取文件 代码中 “defer fileObj.Close()” 的位置应该从第17行 放到第13行吧,因为如果 line 13-- line16 中间的代码如果err!=nil,会直接return,并不会执行line 17的 defer fileObj.Close()

不是的,一定要先判断错误。通常只有当err!=nil的时候,返回的file才是有效的,就像你不能对一个nil调用Close方法。

zeusYi commented 4 years ago

@Q1mi

@zeusYi bufio读取文件 代码中 “defer fileObj.Close()” 的位置应该从第17行 放到第13行吧,因为如果 line 13-- line16 中间的代码如果err!=nil,会直接return,并不会执行line 17的 defer fileObj.Close()

不是的,一定要先判断错误。通常只有当err!=nil的时候,返回的file才是有效的,就像你不能对一个nil调用Close方法。

就是说 file, err := os.Open("./xx.txt") 这个地方如果err!=nil,只有一种err ,就是文件不存在,这个时候也就没必要再对不存在的文件进行 file.Close() 了,对吧老师?

baduiy commented 4 years ago

请问,循环读取文件和上一个读法有什么区别,谢谢解答!

Q1mi commented 4 years ago

@baduiy 请问,循环读取文件和上一个读法有什么区别,谢谢解答!

循环读取文件是读多次,它上一个是读一次呀。

glassy-sky-lisong commented 4 years ago

package fileoperation

import ( "fmt" "io" "os" )

func GetFile(path string) *os.File { file, err := os.Open(path) if err != nil { fmt.Println("can not get this file,err:", err) } return file }

func ReadFile(file *os.File, cap int, speed int) (content []byte) { if file != nil { content = make([]byte, cap) for { temp := make([]byte, speed) c, err := file.Read(temp) if err == io.EOF { fmt.Println("已经读完") break } if err != nil { fmt.Println("read is fail err:", err) } content = append(content, temp[:c]...) } defer file.Close() return content } return []byte{} }

func Decode(source []byte) string { return string(source) }

func Encode(source string) (res []byte) { res = []byte(source) return res }

latteStudio commented 3 years ago

cat命令实现这段,在读取的文件最后一行不是空行的情况下,最后一行有内容的行,会无法读取 文本内容: shuai qi asdfasdf

sdf sadf

sdf

测试结果: latteplus@LAPTOP-00EFC09V MINGW64 /d/myCode/Go/src/learngo/basic_grammar/cat (master) $ ./cat.exe /d/myCode/Go/src/learngo/basic_grammar/13file/3.txt shuai qi asdfasdf

sdf sadf

Q1mi commented 3 years ago

@latteplus cat命令实现这段,在读取的文件最后一行不是空行的情况下,最后一行有内容的行,会无法读取 文本内容: shuai qi asdfasdf

sdf sadf

sdf

测试结果: latteplus@LAPTOP-00EFC09V MINGW64 /d/myCode/Go/src/learngo/basic_grammar/cat (master) $ ./cat.exe /d/myCode/Go/src/learngo/basic_grammar/13file/3.txt shuai qi asdfasdf

sdf sadf

感谢反馈,现已修正。

127161782 commented 3 years ago

bufio和ioutils在mac上不好使呀?

lxdzh commented 3 years ago

实现cat

package main

//通过cobra 实现cat
import (
    "bufio"
    "fmt"
    "io"
    "os"

    "github.com/spf13/cobra"
)

func Openfilebufio(filename string, arg int) {
    file, err := os.Open(filename)
    if err != nil {
        fmt.Printf("open file is failed %s\n", err)
        return
    }
    defer file.Close()

    //创建新的文件对象

    readerfile := bufio.NewReader(file)
    for i := 0; i < arg; i++ {
        line, err := readerfile.ReadString('\n')
        if err == io.EOF {
            return
        }
        if err != nil {
            fmt.Printf("bufio reader file is failed %s\n", err)
        }
        fmt.Print(line)
    }
}

func main() {
    var myflag int

    var cat = &cobra.Command{
        Use:   "cat [OPTION]... [FILE]...",
        Short: "cat line ",
        Long:  "cat file line",
        Args:  cobra.MinimumNArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
            for _, v := range args {
                fmt.Printf("cat file is %v\n", v)
                Openfilebufio(v, myflag)

            }

        },
    }
    cat.Flags().IntVarP(&myflag, "test", "n", 10, "cat line ")
    cat.Execute()

}
lanmo97 commented 3 years ago

@127161782 bufio和ioutils在mac上不好使呀?

可以的啊。这是内置函数和操作系统无关叭 :)

hanhanhanxu commented 2 years ago
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func CopyFile(src, desc string) error {
    fileSrc, err := os.Open(src)
    if err != nil {
        fmt.Printf("open file[%v] error:%v", src, err)
        return err
    }
    fileDesc, err := os.OpenFile(desc, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Printf("open file[%v] error:%v", desc, err)
        return err
    }
    defer func() {
        fileSrc.Close()
        fileDesc.Close()
    }()

    reader := bufio.NewReader(fileSrc)
    writer := bufio.NewWriter(fileDesc)

    bytes := make([]byte, 128)

    for {
        //读
        nRead, err := reader.Read(bytes)
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Printf("read file[%v] error:%v", src, err)
            return err
        }
        //写
        _, err = writer.Write(bytes[:nRead])
        if err != nil {
            fmt.Printf("write file[%v] error:%v", desc, err)
            return err
        }
    }
    writer.Flush()
    return nil
}

func main() {
    err := CopyFile("/Users/xu.han/Pictures/gin生命周期.png", "gin_copy.png")
    if err != nil {
        fmt.Println("copy file error:", err)
        return
    }
}
toki-plus commented 2 years ago

file.Read() 基本使用 的例子中的

if err == io.EOF {
    fmt.Println("文件读完了")
    return
}

应该是没有一种情况会进去的,因为它不是 循环读取

如果设定的容量读取完了文件内容,err为nil;

如果设定的容量没读取完文件内容,err也为nil;

如果是读取错误,err也不是io.EOF。

所有用 io.EOF 来判断是否读完仅适用于 循环读取,是这样吗七米老师?