使用Go语言的cli包读取外部文件。

huangapple go评论135阅读模式
英文:

Reading an external file with cli Go package

问题

我正在使用cli Go包:https://github.com/codegangsta/cli

package main

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

func main() {
	app := cli.NewApp()
	app.Name = "m2k"
	app.Usage = "将Markdown转换为Kindle"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "file",
			Value: "english",
			Usage: "用于问候语的语言",
		},
	}

	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

编辑:

我在app.Action中写了fmt.Println("file %s", file),但没有打印任何内容。这对问题有什么影响吗?

英文:

I'm using the cli Go package: https://github.com/codegangsta/cli

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)
}

I'm a Go beginner. So I probably did something very wrong.

I do this in the command line (I have a file called markdown.txt in the directory):

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

But I get this error:

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

EDIT:

I wrote fmt.Println("file %s", file) to app.Action but nothing is printed. Does this tell something about the problem?

答案1

得分: 2

cli.Context.Args返回当前上下文中的参数。这意味着它不包括全局参数。如果你打印c.Args的长度,你会发现它是零。

你可以使用c.String("file")或者移除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

    // 默认使用标准输入/输出
    in := os.Stdin
    out := os.Stdout
    defer out.Close()
    defer in.Close()

    // 如果给定了输入文件,则替换标准输入
    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())
    }

    // 如果给定了输出文件,则替换标准输出
    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
英文:

cli.Context.Args returns args form the current context. Meaning, not the global arguments supplied. If you print the length of c.Args you'll see it is zero.

You can either use c.String("file") or remove the app.Flags, supply a command in the format of go run io.go path/to/file.txt and use c.Args.First()

Example:

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)))
}

Result:

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

huangapple
  • 本文由 发表于 2015年2月17日 23:48:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/28565388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定