15

I would like to run my go file on my input.txt where my go program will read the input.txt file when I type in go run command ie:

go run goFile.go input.txt

I don't want to put input.txt in my goFile.go code since my go file should run on any input name not just input.txt.

I try ioutil.ReadAll(os.Stdin) but I need to change my command to

go run goFile.go < input.txt

I only use package fmt, os, bufio and io/ioutil. Is it possible to do it without any other packages?

icza
  • 389,944
  • 63
  • 907
  • 827
Matt
  • 739
  • 2
  • 6
  • 10

3 Answers3

13

Please take a look at the package documentation of io/ioutil which you are already using.

It has a function exactly for this: ReadFile()

func ReadFile(filename string) ([]byte, error)

Example usage:

func main() {
    // First element in os.Args is always the program name,
    // So we need at least 2 arguments to have a file name argument.
    if len(os.Args) < 2 {
        fmt.Println("Missing parameter, provide file name!")
        return
    }
    data, err := ioutil.ReadFile(os.Args[1])
    if err != nil {
        fmt.Println("Can't read file:", os.Args[1])
        panic(err)
    }
    // data is the file content, you can use it
    fmt.Println("File content is:")
    fmt.Println(string(data))
}
icza
  • 389,944
  • 63
  • 907
  • 827
1

Firs you check for the provided argument. If the first argument satisfy the condition of an input file, then you use the ioutil.ReadFile method, providing parameter the os.Args result.

package main

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

func main() {
    if len(os.Args) < 1 {
        fmt.Println("Usage : " + os.Args[0] + " file name")
        os.Exit(1)
    }

    file, err := ioutil.ReadFile(os.Args[1])
    if err != nil {
        fmt.Println("Cannot read the file")
        os.Exit(1)
    }
    // do something with the file
    fmt.Print(string(file))
}

Another possibility is to use:

f, err := os.Open(os.Args[0])

but for this you need to provide the bytes lenght to read:

b := make([]byte, 5) // 5 is the length
n, err := f.Read(b)
fmt.Printf("%d bytes: %s\n", n, string(b))
Endre Simo
  • 11,330
  • 2
  • 40
  • 49
0

For running .go file from command-line by input parameter like file (for example abc.txt).We need use mainly os, io/ioutil, fmt packages. Additionally for reading command line parameters we use os.Args Here is example code

package main
 import (
  "fmt"
  "os"
  "io/ioutil"
)
func main()  {
fmt.Println(" Hi guys  ('-') ")
input_files := os.Args[1:]
//input_files2 := os.Args[0];
//fmt.Println("if2 : ",input_files2)
if len(input_files) < 1{
fmt.Println("Not detected files.")
}else{
fmt.Println("File_name is : ",input_files[0])
content, err := ioutil.ReadFile(input_files[0])
if err != nil {
fmt.Println("Can't read file :", input_files[0],"Error : ",err)
}else {
fmt.Println("Output file content is(like string type) : \n",string(content))//string Output
fmt.Println("Output file content is(like byte type) : \n",content)//bytes Output
}
}
}

Args holds command line arguments, including the command as Args[0]. If the Args field is empty or nil, Run uses {Path}. In typical use, both Path and Args are set by calling Command. Args []string function. This function return back array on string type https://golang.org/pkg/os/exec/.Args hold the command-line arguments, starting with the program name. In this case short way to take filename from command-line is this functions os.Args[1:] . And here is output

elshan_abd$ go run main.go abc.txt
Hi guys  ('-')
File_name is :  abc.txt
Output file content is(like string type) : 
aaa
bbb
ccc
1234
Output file content is(like byte type) : 
[97 97 97 10 98 98 98 10 99 99 99 10 49 50 51 52 10] 

Finally we need for reading content file this function func ReadFile(filename string) ([]byte, error) source is https://golang.org/pkg/io/ioutil/#ReadFile

Thomas Smyth - Treliant
  • 4,993
  • 6
  • 25
  • 36