Golang读取二进制文件时遇到EOF问题如何解决

Golang读取二进制文件时遇到EOF问题如何解决 你好,我正在处理一个二进制文件。我试图做的是将一个切片写入文件,然后读取它以检查一切是否正常。然而,在读取文件时,我遇到了一个错误,提示“意外的EOF”。磁盘上的偏移量是正确的,文件尚未到达末尾,但错误仍然发生了。这可能是什么原因呢?

func initializeBMInode(ptrDisk *os.File, numStructs, iniBitmap int64) {
	total := 5 * numStructs
	for i := int64(0); i < total; i++ {
		ctr := '0'
		ptrDisk.Seek(iniBitmap+i, 0)
		var buffer bytes.Buffer
		binary.Write(&buffer, binary.BigEndian, &ctr)
		writeNextBytes(ptrDisk, buffer.Bytes())
	}
	/*
		Test bitmap
	*/
 	bmGen := make([]byte, 5*numStructs)
	ptrDisk.Seek(iniBitmap, 0)
	fmt.Println("InitBitmap")
	fmt.Println(iniBitmap)
	content := readNextBytes(ptrDisk, int64(unsafe.Sizeof(bmGen)))
 	buffer := bytes.NewBuffer(content)
	err := binary.Read(buffer, binary.BigEndian, &bmGen)
	if err != nil {
		log.Fatal(err) // Get error
	}
	fmt.Println(bmGen)
}

更多关于Golang读取二进制文件时遇到EOF问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

非常感谢,现在我明白了。谨致问候。

更多关于Golang读取二进制文件时遇到EOF问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


unsafe.Sizeof(bmGen) 返回的是切片头的大小。

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	// 运行时 - 切片头
	type slice struct {
		array unsafe.Pointer
		len   int
		cap   int
	}
	fmt.Println(int64(unsafe.Sizeof(slice{})))

	// bmGen - 切片头
	var numStructs int64 = 1
	bmGen := make([]byte, 5*numStructs)
	fmt.Println(int64(unsafe.Sizeof(bmGen)))

	// bmGen - 切片元素
	fmt.Println(int64(unsafe.Sizeof(bmGen[0])))
}

https://play.golang.org/p/dSkDhR_wKP-

24
24
1

问题出在 readNextBytes 函数读取的字节数与 bmGen 切片实际大小不匹配。unsafe.Sizeof(bmGen) 返回的是切片描述符的大小(24字节),而不是切片内容的长度。

以下是修正后的代码:

func initializeBMInode(ptrDisk *os.File, numStructs, iniBitmap int64) {
	total := 5 * numStructs
	for i := int64(0); i < total; i++ {
		ctr := '0'
		ptrDisk.Seek(iniBitmap+i, 0)
		var buffer bytes.Buffer
		binary.Write(&buffer, binary.BigEndian, &ctr)
		writeNextBytes(ptrDisk, buffer.Bytes())
	}

	// 修正:直接使用切片长度,而不是unsafe.Sizeof
	bmGen := make([]byte, 5*numStructs)
	ptrDisk.Seek(iniBitmap, 0)
	fmt.Println("InitBitmap")
	fmt.Println(iniBitmap)
	
	// 修正:读取实际需要的字节数
	content := readNextBytes(ptrDisk, int64(len(bmGen)))
	buffer := bytes.NewBuffer(content)
	err := binary.Read(buffer, binary.BigEndian, &bmGen)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(bmGen)
}

如果 readNextBytes 函数是你自定义的,确保它正确处理读取操作:

func readNextBytes(file *os.File, number int64) []byte {
	bytes := make([]byte, number)
	n, err := file.Read(bytes)
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
	if int64(n) < number {
		log.Fatal("读取字节数不足")
	}
	return bytes
}

关键点:

  1. unsafe.Sizeof(slice) 返回的是切片头的大小,而不是底层数组的长度
  2. 使用 len(bmGen) 获取实际需要读取的字节数
  3. 确保 readNextBytes 函数正确处理部分读取和EOF情况
回到顶部