Go : How to read the contents of two files and concatenate to a string

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

Go : How to read the contents of two files and concatenate to a string

问题

我正在尝试修复docker-machine中的一个错误。问题似乎出现在它的vmware-fusion驱动程序中。当尝试通过MAC地址解析机器时,它会查阅vmware dhcp租约文件。不幸的是,当您使用自定义网络(例如私有网络vmnet2)时,最新的dhcp租约将位于文件'vmnet-dhcpd-vmnet2.leases'中。

无论如何,我对go的了解几乎为零。

我想实现类似以下的内容(伪代码):

var allText = ""
for i in "/var/db/vmware/*.leases"
  do read i; allText = allText ++ i
done

现有的代码(fusion_darwin.go)如下所示:

// DHCP lease table for NAT vmnet interface
var dhcpfile = "/var/db/vmware/vmnet-dhcpd-vmnet8.leases"

if vmxfh, err = os.Open(d.vmxPath()); err != nil {
    return "", err
}
defer vmxfh.Close()

if vmxcontent, err = ioutil.ReadAll(vmxfh); err != nil {
    return "", err
}

我已经创建了一个问题等等,但如果可能的话,我想在修复问题的过程中学习更多关于Go的知识,并贡献出我能修复的内容。

有什么想法吗?

英文:

I'm trying to fix a bug in docker-machine. The problem seems to be in it's vmware-fusion driver. When trying to resolve a machine by it's MAC address it consults the vmware dhcp leases file. Unfortunately, when you use a custom network (for example the private network vmnet2) the most recent dhcp lease will be in the file 'vmnet-dhcpd-vmnet2.leases' instead.

Anyhow, my knowledge of go is non-existent.

I'd like to implement something like (pseudocode):

var allText = ""
for i in "/var/db/vmware/*.leases"
  do read i; allText = allText ++ i
done

The existing code (fusion_darwin.go) looks like this:

// DHCP lease table for NAT vmnet interface
var dhcpfile = "/var/db/vmware/vmnet-dhcpd-vmnet8.leases"

if vmxfh, err = os.Open(d.vmxPath()); err != nil {
    return "", err
}
defer vmxfh.Close()

if vmxcontent, err = ioutil.ReadAll(vmxfh); err != nil {
    return "", err
}

I've created an issue etc, but if possible I'd like to learn a little more about Go along the way and contribute back whatever I can fix.

Any ideas?

答案1

得分: 2

在示例代码中,首先使用os.Open打开文件并返回一个io.Reader,然后使用延迟关闭(延迟方法在离开延迟作用域之前被调用),以确保资源被清理。在下一行中,他们调用ioutil.ReadAll,它接受一个io.Reader并返回一个[]byte, error。如果错误不为空,则返回错误和空字符串。要将[]byte转换为字符串,可以使用s := string(myBytes)

因此,要读取目标文件,你可以直接复制上面代码的形式。更好的做法是将其放入一个方法中,并将文件路径传递给它,以便可以重用。值得注意的是,在ioutil包中有一个更简单的方法。我不确定为什么上面的代码没有使用它,而是打开文件并将io.Reader传递给ReadAll,而你可以直接调用ioutil.ReadFile,将路径传递给它,它也会返回一个[]byte, error。在检查错误后,你只需将一个字节切片附加到另一个字节切片,转换为字符串并返回即可。代码看起来会像这样:

vmnetcontent, err := ioutil.ReadFile("/path/to/file.txt")

if err != nil {
    return "", err
}

return string(append(vmxcontent, vmnetcontent)), nil
英文:

In the example code, they first use os.Open to return an io.Reader for the file, they then defer the close (defered methods are invoked just before you leave the defering scope) in order to ensure their resources are cleaned up. In the next line they call ioutil.ReadAll which takes an io.Reader and returns a []byte, error. If the error is non nil they just return it and an empty string. To get a string out of a []byte you can just do s := string(myBytes).

So to read your target file, you could just copy the form of the code above exactly. Better yet you could move it into a method and pass the filepath down to it so you can reuse it. One thing worth noting, there is an easier method to use in the ioutil package. I'm not sure if there is a good reason it wasn't used in the code above but rather than opening the file and passing an io.Reader to ReadAll you can just call ioutil.ReadFile passing it the path and it also returns a []byte, error, after checking for an error you can just append one byte slice to the other, convert to a string and return it. It would look a little like this;

vmnetcontent, err := ioutil.ReadFile("/path/to/file.txt")

if err != nil {
    return "", err
}

return string(append(vmxcontent, vmnetcontent)), nil

huangapple
  • 本文由 发表于 2016年1月9日 02:00:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/34683261.html
匿名

发表评论

匿名网友

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

确定