Golang按字节读取文件的实现方法

Golang按字节读取文件的实现方法 我正在尝试使用以下代码读取两个文件,并从顶部和底部移除一些行,但看起来在读取文件时遇到了问题。 我的代码如下:

//file: clean.go
package main

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

func clean(files ...string) {
	for _, fn := range files {
		var f *os.File
		if f, err := os.OpenFile(fn, os.O_RDWR, 0); err != nil {
			log.Fatal("error", err)
		}
		defer func(f *os.File) {
			if err := f.Close(); err == nil {
				log.Fatal("error", err)
			}
		}(f)

		if fileBytes, err := ioutil.ReadAll(f); err != nil {
			log.Fatal("error", err)
		} else {
			lines := strings.Split(string(fileBytes), "\n")
			if fn == "currentInvenory.csv" {
				lines = lines[12 : len(lines)-5]
			} else {
				lines = lines[12 : len(lines)-6]
			}
			fmt.Println(fn, "has a total of", len(lines), "lines")
		}
	}
}

func main() {
	files := []string{"currentInvenory.csv", "currentTransactions.csv"}
	clean(files...)
}

但出现了这个错误:

.\clean.go:14:6: f declared but not used

更多关于Golang按字节读取文件的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你在下一行中再次声明了 f,

if f, err := os.OpenFile(fn, os.O_RDWR, 0); err != nil {

请按如下方式更新你的代码

var f *os.File
var err error
if f, err = os.OpenFile(fn, os.O_RDWR, 0); err != nil {
    log.Fatal("error", err)
}

更多关于Golang按字节读取文件的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


hyousef:

var f *os.File if f, err := os.OpenFile(fn, os.O_RDWR, 0); err != nil { log.Fatal(“error”, err) }

	for _, fn := range files {
		f, err := os.OpenFile(fn, os.O_RDWR, 0)
		if  err != nil {
			log.Fatal("error", err)
		}
		defer func(f *os.File) {
			if err := f.Close(); err == nil {
				log.Fatal("error", err)
			}
		}(f)

 		fileBytes, err := ioutil.ReadAll(f)
		if err != nil {
			log.Fatal("error", err)
		} 

		lines := strings.Split(string(fileBytes), "\n")
		if fn == "currentInvenory.csv" {
			lines = lines[12 : len(lines)-5]
		} else {
			lines = lines[12 : len(lines)-6]
		}
		fmt.Println(fn, "has a total of", len(lines), "lines")
		
	}

错误是由于变量作用域冲突导致的。在第14行,你使用短变量声明f, err := os.OpenFile(...)创建了一个新的局部变量f,这覆盖了第13行声明的f变量,导致第13行的f未被使用。

以下是修正后的代码:

package main

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

func clean(files ...string) {
	for _, fn := range files {
		f, err := os.OpenFile(fn, os.O_RDWR, 0)
		if err != nil {
			log.Fatal("error", err)
		}
		
		defer func(f *os.File) {
			if err := f.Close(); err != nil {
				log.Fatal("error", err)
			}
		}(f)

		fileBytes, err := ioutil.ReadAll(f)
		if err != nil {
			log.Fatal("error", err)
		}
		
		lines := strings.Split(string(fileBytes), "\n")
		if fn == "currentInvenory.csv" {
			lines = lines[12 : len(lines)-5]
		} else {
			lines = lines[12 : len(lines)-6]
		}
		fmt.Println(fn, "has a total of", len(lines), "lines")
	}
}

func main() {
	files := []string{"currentInvenory.csv", "currentTransactions.csv"}
	clean(files...)
}

主要修改:

  1. 移除了第13行的var f *os.File声明
  2. 将第14行的短变量声明改为直接赋值给ferr
  3. 修正了defer函数中的错误处理逻辑(原代码在err == nil时调用log.Fatal

如果你需要按字节读取文件而不是一次性读取整个文件,可以使用bufio.Reader

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func readByBytes(filename string, chunkSize int) {
	file, err := os.Open(filename)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	reader := bufio.NewReader(file)
	buffer := make([]byte, chunkSize)

	for {
		n, err := reader.Read(buffer)
		if err != nil && err.Error() != "EOF" {
			log.Fatal(err)
		}
		
		if n == 0 {
			break
		}
		
		// 处理读取到的字节
		fmt.Printf("Read %d bytes: %s\n", n, string(buffer[:n]))
	}
}

func main() {
	readByBytes("currentInvenory.csv", 1024)
}
回到顶部