Go,对文件进行分类的可扩展系统

时间:2017-03-07 15:04:33

标签: go dynamic xml-parsing

我有创建一个"脚本"将走一个目录树来对文件进行分类并采取行动(如果是照片,则上传到Flickr。如果是视频,请移动到文件夹,......)。

我没有Go的知识,但想改变它。文件发现和分类似乎不是最重要的部分。 例程频道似乎足以拥有非阻塞系统。

我主要关心的是采取的行动。我一定会编写一些动作,例如" FlickrUpload"或者" Shell" (适用于mvcp,..)。但我希望有一个可配置的系统,我可以将动作附加到mime类型。我认为一个Xml结构可以很好地配置它,并且看起来很容易解析。

<?xml version="1.0" standalone="yes">
<configuration>
  <file type="image/jpg">
    <action name="FlickrUpload" />
    <action name="Shell">
      mv ${file} /some/absolute/path/
    </action>
    <!-- or -->
    <FlickrUpload /> 
  </file>
</configuration>

但我不知道如何将动作及其参数(从Xml)绑定到action interface(除非你说其他)。

type action interface {
  execute(path string) error
}

1 个答案:

答案 0 :(得分:3)

从XML流或任何其他文本媒体中,您只能获取文本。 因此,您的mv ${file} /some/absolute/path/基本上是文字。

这意味着在实际调用之前,您将不可避免地需要解析它 你解决的任何问题都是真实的行动。

现在你有两个问题:

  1. 知道某个操作后如何调用某些Go代码。
  2. 如何将“动作参数”数据传递给它。
  3. 它们交织在一起 - 取决于你如何决定解决(1)。

    第一种调用Go函数的方法是给出文本“句柄” 只需要有一个这样的函数句柄的映射,如下所示:

    type Action func (...interface{}) error
    
    var actions = map[string]Action {
        "mv": Move,
        "flickr": UploadToFlickr,
    }
    
    func Move(args ...interface{}) error {
        // implement
    }
    
    func UploadToFlickr(args ...interface{}) error {
        // implement
    }
    

    现在你发送你的行为,如

    act, ok := actions[action_name]
    if !ok {
      log.Fatalf("Config error: Unsupported action: %s\n', action_name)
    }
    
    err := act(action_args...)
    if err != nil {
       // Handle
    }
    
      

    注意这些...位:它们实现了可变参数函数   允许将一片值传递给一个可变函数。

    第二种方法是更严格地输入:

    1. 您定义了一个界面:

      type Action interface {
          func Do(fname string) error
      }
      
    2. 您的配置解析代码将生成具体类型的值 比方说,MoveActionFlickrUploadAction

      所有这些类型都必须实现接口Do()的方法Action

      通过这样做,他们自动地实现了所述界面。 这也意味着您的配置解析器可以返回该值 接口 - 像这样:

      func ConfigParser() (map[string]Action, error)
      

      ...其中map[string]Action将映射MIME类型的文件 具体类型的值 - 例如FlickrUploadAction 对于类型为文件的image/pngMoveAction类型的文件 text/plain

    3. 要调用操作,您可以查找由该虚构生成的地图 ConfigParser()函数使用文件的MIME类型并获取值 它实现了Action接口,所以剩下的就是简单 调用其Do()方法传递实际文件的名称。

      TL; DR

      阅读界面 - 它们非常强大且无处不在 在标准库中(查看io.Readerio.Writer s)。