ioutil是否使用过多的文件描述符/泄漏?

安松

我正在浏览文件列表,并将其中的xml数据解组为结构数组rArray我打算处理大约18000个文件。当我处理了大约1300个文件时,程序感到恐慌,并说打开了太多文件。如果我将处理的文件数量限制为1000个安全数量,则该程序不会崩溃。

如下所示,我正在ioutil.ReadFile读取文件数据。

for _, f := range files {

    func() {
        data, err := ioutil.ReadFile("./" + recordDir + "/" + f.Name())
        if err != nil {
            fmt.Println("error reading %v", err)
            return
        } else {
            if (strings.Contains(filepath.Ext(f.Name()), "xml")) {

                //unmarshal data and put into struct array
                err = xml.Unmarshal([]byte(data), &rArray[a])
                if err != nil {
                    fmt.Println("error decoding %v: %v",f.Name(), err)
                    return
                }
            }
        }
    }()
}

我不确定Go使用的文件描述符过多还是没有足够快地关闭文件。

阅读https://groups.google.com/forum/#!topic/golang-nuts/7yXXjgcOikM并查看http://golang.org/src/pkg/io/ioutil/ioutil.go中ioutil代码后,用于显示它用于关闭文件。返回调用函数并且是调用函数时运行。我的理解正确吗?我也尝试将代码一部分包装在一个函数中,但这没什么区别。ioutil.ReadFiledeferdeferReadFile()ioutil.ReadFile

ulimit的设置为无限制。

更新:我认为在我的Unzip函数期间实际上发生了太多文件的错误。

func Unzip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }

    for _, f := range r.File {
        rc, err := f.Open()
        if err != nil {
            panic(err)
        }

        path := filepath.Join(dest, f.Name)
        if f.FileInfo().IsDir() {
            os.MkdirAll(path, f.Mode())
        } else {
            f, err := os.OpenFile(
                path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
            if err != nil {
                panic(err)
            }

            _, err = io.Copy(f, rc)
            if err != nil {
                panic(err)
            }
            f.Close()
        }
        rc.Close()
    }
    r.Close()
    return nil
}

我最初是Unziphttps://gist.github.com/hnaohiro/4572580获得该函数的,但经过进一步检查,defer要点作者功能中的使用似乎是错误的,因为只有在该Unzip()函数返回后才关闭文件,这太晚了因为将打开18000个文件描述符。;)

如上所述Close用显式替换了deferred Close(),但是仍然遇到相同的“打开文件太多”错误。我修改后的解压缩功能是否存在问题?

更新#2糟糕,我一直在Heroku上运行此代码,并且整个过程都在将我的更改推送到错误的应用程序。获得的经验教训:在heroku工具栏中验证目标应用程序。

从解压码https://gist.github.com/hnaohiro/4572580没有因为它没有关闭的文件,直到所有的文件处理工作。

我上面显式关闭的解压缩代码有效,@ peterSO的答案中的延迟版本也有效。

彼得

我可以将https://gist.github.com/hnaohiro/4572580的Unzip功能修改为以下内容:

package main

import (
    "archive/zip"
    "io"
    "log"
    "os"
    "path/filepath"
)

func unzipFile(f *zip.File, dest string) error {
    rc, err := f.Open()
    if err != nil {
        return err
    }
    defer rc.Close()

    path := filepath.Join(dest, f.Name)
    if f.FileInfo().IsDir() {
        err := os.MkdirAll(path, f.Mode())
        if err != nil {
            return err
        }
    } else {
        f, err := os.OpenFile(
            path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
        if err != nil {
            return err
        }
        defer f.Close()

        _, err = io.Copy(f, rc)
        if err != nil {
            return err
        }
    }
    return nil
}

func Unzip(src, dest string) error {
    r, err := zip.OpenReader(src)
    if err != nil {
        return err
    }
    defer r.Close()

    for _, f := range r.File {
        err := unzipFile(f, dest)
        if err != nil {
            return err
        }
    }

    return nil
}

func main() {
    err := Unzip("./sample.zip", "./out")
    if err != nil {
        log.Fatal(err)
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

泄漏文件描述符

来自分类Dev

exec是否保留文件描述符

来自分类Dev

确定文件描述符是否关闭

来自分类Dev

日志记录模块:打开文件描述符过多

来自分类Dev

Windows中的select()python中的文件描述符过多

来自分类Dev

调试Mac / Cocoa文件描述符泄漏

来自分类Dev

Android Service示例代码泄漏文件描述符

来自分类Dev

Apache HttpAsyncClient中的文件描述符泄漏

来自分类Dev

帮助解决难以捉摸的文件描述符泄漏

来自分类Dev

关闭原始文件描述符后,重复的描述符文件是否会关闭?

来自分类Dev

文件描述符是否优化了对文件的写入?

来自分类Dev

是否可以将事件文件描述符与中断驱动的输入结合使用?

来自分类Dev

将文件描述符读取为NULL是否合法?

来自分类Dev

如果fclose失败,文件描述符是否仍然打开?

来自分类Dev

如果fclose失败,文件描述符是否仍然打开?

来自分类Dev

如果fclose失败,文件描述符是否仍然打开?

来自分类Dev

是否需要关闭接受返回文件描述符

来自分类Dev

测试文件描述符是否有效

来自分类Dev

重载epoll线程的文件描述符是否安全?

来自分类Dev

是否可以倒退nodejs中的文件描述符游标?

来自分类Dev

文件描述符是否永远不会打开?

来自分类Dev

如何检查文件描述符/内存是否可以映射?

来自分类Dev

Linux:检查文件描述符是否可读取

来自分类Dev

文件描述符位置

来自分类Dev

文件描述符0

来自分类Dev

文件描述符重复

来自分类Dev

读取文件描述符

来自分类Dev

关闭文件描述符

来自分类Dev

exec的文件描述符