英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论