在使用Go语言写入文件后,无法读取文件的字节。

huangapple go评论94阅读模式
英文:

cannot read bytes from file with go after writing

问题

所以,我正在尝试在Go语言中创建一个简单的AOT虚拟机,它以字节码文件作为输入。我试图基本上将字节写入文件,然后使用ioutil读取它们,但是我遇到了空指针解引用错误。

这是我用于写入文件的Python代码:

btest = open("test.thief", "w")
bytes_to_write = bytearray([1, 44, 56, 55, 55, 0])

btest.write(bytes_to_write)

btest.close()

这是我用于读取字节的Go文件中的代码:

package main

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

func main() {
  //获取命令行参数
  userArgs := os.Args[1:]

    bytes, err := ioutil.ReadFile(userArgs[0]) // just pass the file name
    if err != nil {
        fmt.Print(err)
    }

     fmt.Println(bytes)
     machine := NewEnv()
     ReadBytes(machine, bytes)

}

这是我得到的错误:

Joshuas-MacBook-Pro-3:thief Josh$ ./bin/Thief test.thief
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x2af3]

goroutine 1 [running]:
main.ReadBytes(0xc82000e390, 0xc82000c480, 0x6, 0x206)
    /Users/Josh/thief/src/Thief/read.go:26 +0x353
main.main()
    /Users/Josh/thief/src/Thief/Main.go:18 +0x1f2

我还尝试使用Python代码以二进制模式打开文件,但是产生了相同的错误。基本上,这个目标是我想能够提取一个字节数组,但也有一种方法可以写入它们。

我是否错误地写入了字节?

这是十六进制转储:

012c 3837 3700

编辑:

这是我的其他go文件

opfuncs.go

package main


//用于机器函数和操作的文件

//打印一些字节的字符串格式
func print(env Env, data []byte) {
    fmt.Println(string(data))
}


var OPERS map[byte]func(Env, []byte)

//0被保留为空终止符
func init(){
    OPERS = map[byte]func(Env, []byte){
        1:print,
    }
}

env.go

package main


//用于env结构的文件



type Env struct {
    items map[string]interface{}
}

func NewEnv() Env {
    return Env{make(map[string]interface{})}
}

//通用getter
func (self *Env) get(key string) interface{} {
    val, has := self.items[key]
    if has {
        return val
    } else {
        return nil
    }
}

//通用setter
func (self *Env) set(key string, value interface{}) {
    self.items[key] = value
}

func (self *Env) contains(key string) bool {
    _, has := self.items[key]
    return has
}

func (self *Env) declare(key string) {
    self.items[key] = Null{}
}

func (self *Env) is_null(key string) bool {
    _, ok := self.items[key].(Null)
    return ok
}

//从存储中删除项目
func (self *Env) del(key string) {
    delete(self.items, key)
}

read.go

package main

//包含VM的读取函数的文件

func ReadBytes(env Env, in []byte) {
    bytes := make([]byte, 1)
    fn := byte(0)
    mode := 0
    for i:=0;i<len(in);i++ {
        switch mode {
        case 0:
            fn = byte(i)
            mode = 1
        case 1:
            if i != len(in)-1 {
                if in[i+1] == 0 {
                    bytes = append(bytes, in[i])
                    mode = 2
                } else {
                    bytes = append(bytes, in[i])
                }
            } else {
                bytes = append(bytes, in[i])
            }
        case 2:
            OPERS[fn](env, bytes)
            mode = 0
            fn = byte(0)
            bytes = make([]byte, 1)
        }
    }
}
英文:

So, i am trying to make a simple AOT virtual machine in golang, that reads a bytecode file as it's input. I am trying to very basically, write bytes to a file then read them with ioutil, however I am encountering a null dereference error.

This is my python code used for writing to the file:

btest = open(&quot;test.thief&quot;, &quot;w&quot;)
bytes_to_write = bytearray([1, 44, 56, 55, 55, 0])

btest.write(bytes_to_write)

btest.close()

This is the code in my go file that I am using to read the bytes

package main

import (
   &quot;fmt&quot;
   &quot;io/ioutil&quot;
   &quot;os&quot;
)

func main() {
  //gets command line args
	userArgs := os.Args[1:]

    bytes, err := ioutil.ReadFile(userArgs[0]) // just pass the file name
    if err != nil {
        fmt.Print(err)
    }

     fmt.Println(bytes)
     machine := NewEnv()
     ReadBytes(machine, bytes)

}

And this is the error i am getting:

Joshuas-MacBook-Pro-3:thief Josh$ ./bin/Thief test.thief
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x2af3]

goroutine 1 [running]:
main.ReadBytes(0xc82000e390, 0xc82000c480, 0x6, 0x206)
    /Users/Josh/thief/src/Thief/read.go:26 +0x353
main.main()
    /Users/Josh/thief/src/Thief/Main.go:18 +0x1f2

I have also tried opening the file in binary mode with the python code, but it produces the same error. Basically the goal of this is that I want to be able to extract an array of bytes but also have a way to write theme.

Am i writing the bytes incorrectly?

Here is the hexdump:

012c 3837 3700

EDIT:

This is the rest of my go files

opfuncs.go

package main


//file for machine functions and operations

//prints string format of some bytes
func print(env Env, data []byte) {
	fmt.Println(string(data))
}


var OPERS map[byte]func(Env, []byte)

//0 is reserved as the null terminator
func init(){
	OPERS = map[byte]func(Env, []byte){
		1:print,
	}
}

env.go

package main


//file for the env struct



type Env struct {
	items map[string]interface{}
}

func NewEnv() Env {
	return Env{make(map[string]interface{})}
}

//general getter
func (self *Env) get(key string) interface{} {
	val, has := self.items[key]
	if has {
		return val
	} else {
		return nil
	}
}

//general setter
func (self *Env) set(key string, value interface{}) {
	self.items[key] = value
}

func (self *Env) contains(key string) bool {
	_, has := self.items[key]
	return has
}

func (self *Env) declare(key string) {
	self.items[key] = Null{}
}

func (self *Env) is_null(key string) bool {
	_, ok := self.items[key].(Null)
	return ok
}

//deletes an item from storage
func (self *Env) del(key string) {
	delete(self.items, key)
}

read.go

package main

//file that contains the reading function for the VM

func ReadBytes(env Env, in []byte) {
	bytes := make([]byte, 1)
	fn := byte(0)
	mode := 0
	for i:=0;i&lt;len(in);i++ {
		switch mode {
		case 0:
			fn = byte(i)
			mode = 1
		case 1:
			if i != len(in)-1 {
				if in[i+1] == 0 {
					bytes = append(bytes, in[i])
					mode = 2
				} else {
					bytes = append(bytes, in[i])
				}
			} else {
				bytes = append(bytes, in[i])
			}
		case 2:
			OPERS[fn](env, bytes)
			mode = 0
			fn = byte(0)
			bytes = make([]byte, 1)
		}
	}
}

答案1

得分: 2

如果你使用Python 3,那么文件必须以二进制模式打开:

btest = open("test.thief", "wb")
英文:

If you use Python 3, the file must be opened in the binary mode:

btest = open(&quot;test.thief&quot;, &quot;wb&quot;)

答案2

得分: 0

看起来你的Python代码中没有将内容写入文件?

我得到了以下错误信息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not bytearray

这个错误出现在你的第三行,这可能解释了为什么Golang找不到文件的内容。

此外,你没有使用bytes,所以你的Golang代码无法编译。你可以尝试以下代码:

package main

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

func main() {
  // 获取命令行参数
    userArgs := os.Args[1:]

    _, err := ioutil.ReadFile(userArgs[0]) // 只需传递文件名
    if err != nil {
        fmt.Print(err)
    }

}
英文:

It looks like you're not writing to the file in your python code?

I get

Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
TypeError: write() argument must be str, not bytearray

After your third line which would explain why golang can't find the file contents.

Also you're not using bytes so your gocode won't compile. Do this instead.

package main

import (
   &quot;fmt&quot;
   &quot;io/ioutil&quot;
   &quot;os&quot;
)

func main() {
  //gets command line args
    userArgs := os.Args[1:]

    _, err := ioutil.ReadFile(userArgs[0]) // just pass the file name
    if err != nil {
        fmt.Print(err)
    }

}

huangapple
  • 本文由 发表于 2017年1月14日 15:35:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/41647802.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定