【问题标题】:Get directory entries for "slow protocols" asynchronously异步获取“慢速协议”的目录条目
【发布时间】:2019-07-29 22:22:20
【问题描述】:

我想要一个在 Linux 上获取目录条目的函数。我使用ioutil.ReadDir,通常它很快。 但是如果我想在/run/user/1000/gvfs/ 上读取一些挂载的虚拟文件系统,这个功能就会变慢。如果目录有很多文件项我需要等待很长时间。

我可以在终端中使用ls 命令,结果是一样的。 当我尝试ls -U -a -p -1 时,我立即得到了逐行输出。 我尝试在 Go 中使用 exec.Command 运行它,但它不能异步工作。 Go 正在等待完整的程序输出。我做错了什么?

m.cmd = exec.Command("ls", "-U", "-a", "-p", "-1")
// for example some "slow" directory:
m.cmd.Dir = "/run/user/1000/gvfs/dav:host=webdav.yandex.ru,ssl=true,user=...../" 
reader, _ := m.cmd.StdoutPipe()
bufReader := bufio.NewReader(reader)
go func() {
  m.cmd.Start()
  for {
    line, _, err := bufReader.ReadLine()
    if err != nil {
      break
    }
    linestr := string(line)
    if linestr != "./" && linestr != "../" {
      fmt.Println(linestr)
    }
  }
}()

我需要立即在 Go 中逐行打印。

【问题讨论】:

    标签: linux go exec ls gvfs


    【解决方案1】:

    尝试ls -U -a -p 1 | cat 看看你是否得到逐行输出。

    Go 无法控制ls;如果 ls 选择这样做,ls 会逐行写入,而当输出是管道时,ls 会选择 not 这样做。您可以分配一个 pty 对并使用它,但这样做是错误的。

    ioutil.ReadDir 首先读取整个目录(通过调用Readdir(-1)),然后对文件名进行排序。如果您使用os.Open 打开目录,然后调用ReaddirReaddirnames 函数并使用一个小(但不是负数)数字,您应该会得到更多您喜欢的东西。

    【讨论】:

    • 这解决了我的问题: f, err0 := os.Open(path) if err0 == nil { for { files, err1 := f.Readdir(10) /* any number >=1 */ if err1 == nil { if files[j].IsDir() { Prln(files[j].Name()+"/") } else { Prln(files[j].Name()) } } else { 中断 } } f.Close() }
    猜你喜欢
    • 2014-11-13
    • 2020-04-15
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多