2015-02-17 3 views
1

Я с помощью интерфейса пакета Перейти: https://github.com/codegangsta/cliЧтение внешний файл с Cli Go пакета

package main 

import (
    "fmt" 
    "github.com/codegangsta/cli" 
    "io/ioutil" 
    "os" 
) 

func main() { 
    app := cli.NewApp() 
    app.Name = "m2k" 
    app.Usage = "convert markdown to kindle" 
    app.Flags = []cli.Flag{ 
     cli.StringFlag{ 
      Name: "file", 
      Value: "english", 
      Usage: "language for the greeting", 
     }, 
    } 

    app.Action = func(c *cli.Context) { 
     file := "default" 

     if len(c.Args()) > 0 { 
      file = c.Args()[0] 
     } 

     //fmt.Println("file %s", file) 
     fmt.Println("file %s", file) 

     b, err := ioutil.ReadFile(file) 
     if err != nil { 
      panic(err) 
     } 

     err = ioutil.WriteFile("output.txt", b, 0644) 
     if err != nil { 
      panic(err) 
     } 
    } 

    app.Run(os.Args) 
} 

Я новичок Go. Поэтому я, вероятно, сделал что-то очень плохое.

Я делаю это в командной строке (у меня есть файл с именем markdown.txt в каталоге):

~/go/io$ go run io.go -file markdown.txt

Но я получаю эту ошибку:

created by runtime.main /usr/lib/go/src/pkg/runtime/proc.c:221 exit status 2

EDIT:

Я написал fmt.Println("file %s", file) до app.Action, но ничего не печатается. Означает ли это что-то о проблеме?

ответ

2

cli.Context.Args возвращает args из текущего контекста. Значение, а не глобальные аргументы. Если вы напечатаете длину c.Args, вы увидите, что она равна нулю.

Вы можете использовать c.String («файл») или удалить флагов app.Flags, предоставить команду в формате go run io.go path/to/file.txt и использовать c.Args.First ()

Пример:

package main 

import (
    "github.com/codegangsta/cli" 

    "io/ioutil" 
    "log" 
    "os" 
    "strings" 
) 

func main() { 
    app := cli.NewApp() 
    app.Name = "m2k" 
    app.Usage = "convert markdown to kindle" 
    app.Action = mainAction 
    app.Run(os.Args) 
} 

func mainAction(c *cli.Context) { 
    var err error 

    // use stdin/stdout by default 
    in := os.Stdin 
    out := os.Stdout 
    defer out.Close() 
    defer in.Close() 

    // replace stdin if given 
    if c.Args().First() != "" { 
     in, err = os.Open(c.Args().First()) 
     if err != nil { 
      log.Fatalln(err) 
     } 
     log.Printf("Using '%s' as source\n", c.Args().First()) 
    } 

    // replace stdout if given 
    if c.Args().Get(1) != "" { 
     out = os.NewFile(0666, c.Args().Get(1)) 
     log.Printf("Writing output to '%s'\n", c.Args().Get(1)) 
    } 

    b, err := ioutil.ReadAll(in) 
    if err != nil { 
     log.Fatalln(err) 
    } 

    out.Write([]byte(strings.Replace(string(b), "in", "out", 1))) 
} 

Результат:

echo "in file content" > in.txt 
go run foo.go in.txt 
// 2015/02/17 11:49:49 Using 'in.txt' as source 
// out file content 
+0

Не могли бы вы предоставить мне пример кода? – alexchenco

+0

Я добавил пример для использования c.Args.Get (n) – kwolfe

Смежные вопросы