转到:如何读取两个文件的内容并连接为字符串

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?

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