简体   繁体   中英

Opening a go file inside another go program

I am learning Go using "The Go Programming Language" book. First chapter introduced os.Open module for reading files. I tried opening a go file like below.

  f, err = os.Open("helloworld.go")

I got following error:

   # command-line-arguments
.\helloworld.go:6:6: main redeclared in this block
        previous declaration at .\dup2.go:10:6

I want to understand why go behaved as if it's trying to compile the file instead of reading like other languages ( Python, Java or C) do.

What is the correct way of opening a file?

The error you got indicate that you have 2 main() function in the same package.
A package can have many files. When you have multiple .go files in the same directory that you run go build command in, the compiler will build the main package. In this case, it detected duplicated main() function hence the build failed.

What you want to do is specify which file you want to build:

go build helloworld.go

With the file specified, go build will only build with the file(s) you have listed.

For more information on go build you can refer to Golang Documentation .

Though you shouldn't do it but technically you can read a '.go' file with main() from another.go file. Your case is failing as you are building a package having multiple files defining main.

Again clarifying, it is discouraged to have multiple files with main in the same package, and it will fail when you build the package. This is so, as there should be just one entry point (main() function) in the package.

Coming to technicality, you can read a go file from another in same package, but in this case you need to build just the file (not the whole package). Alternately you can issue go run

$ cat main1.go 
package main

import "fmt"

func main() {
        fmt.Println("Hello")
}
$
$ cat readinfolder.go 
package main

import (
        "bufio"
        "fmt"
        "os"
)

func main() {
        filehandle, err := os.Open("main1.go")
        if err != nil {
                panic(err)
        }
        defer filehandle.Close()
        scanner := bufio.NewScanner(filehandle)
        for scanner.Scan() {
                fmt.Println(scanner.Text())
        }
}
$
$
$ go build readinfolder.go 
$ ./readinfolder 
package main

import "fmt"

func main() {
        fmt.Println("Hello")
}
$ 


I'll show you how I've read files into a Directory.

1: You should make the package and import tools:
2: Make new structs for Files and Directories.
3: Make some functions to read new files.
4: Execute your tasks in main function
5: Use ioutil.ReadFile function to read some file

Directory tree

.
|____main.go
|____files
| |____example2.txt
| |____example1.txt

Example code:

package main

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

// Define Directory struct
type Directory struct {
    Path  string
    Files []File
}

// Define File struct
type File struct {
    Name string
}

// Function to return path
func (this Directory) getPath() string {
    return this.Path
}

// Function to set a path
func (this Directory) setPath(path string) string {
    this.Path = path
    return this.Path
}

// Function to get fies into a directory
func (this Directory) getFiles(path string) []File {

    directory, err := ioutil.ReadDir(path)

    if err != nil {
        log.Fatal(err)
    }

    for _, f := range directory {
        this.Files = append(this.Files, File{Name: f.Name()})
    }
    return this.Files
}


//Main function
func main() {
    // Set variables 
    dir := new(Directory)
    path := dir.setPath("/home/your_user/your_project_folder/files/")
    files := dir.getFiles(path)
    firstFiles := dir.getFiles(path)[0].Name

    //Read File
    f, err := ioutil.ReadFile("/home/your_user/your_project_folder/files/" + firstFiles)
    if err != nil {
        log.Fatal(err)
    }

    // Print results
    fmt.Println(files)
    fmt.Println(firstFiles)
    fmt.Println(string(f))
}

output:

[{example1.txt} {example2.txt}]
example1.txt
some text in file!

Finally: You should do go build , to build the project as a binary.

I hope this example may help you to understand better how golang works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM