我只是在读取/proc/diskstats文件。我的代码是:
func ReadFromFile(filepath string)(string){
defer func() {
if err1 := recover(); err1 != nil {
fmt.Println("!!!!!!!!!!!!!!!!Panic Occured and Recovered in readFromFile(), Error Info: ", err1)
}
}()
strData := ""
data, err := ioutil.ReadFile(filepath)
if err != nil{
fmt.Println("File read error: ", err)
return ""
}
strData = string(data)
return strData
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
File read error: open /proc/diskstats: too many open files
Run Code Online (Sandbox Code Playgroud)
不仅对于此文件,对于其他一些文件,我也遇到相同的错误。
我还运行了以下命令:
root@golang:~# lsof|wc -l
785
Run Code Online (Sandbox Code Playgroud)
请指导我。
我遇到了相同的问题(可能是不同的情况或设置),并以不同的方式解决了它。我创建了一个简单的示例:
func some_func(file_name []string) {
for _, file_name := range file_names {
f, _ := os.Create(file_name)
// defer f.Close() // bad idea
_, _ = f.Write("some text")
f.Close() // better idea
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个坏主意,因为defer将被执行,何时some_func返回,这可能需要一段时间-取决于循环大小。
OP 不提供最小的、可重现的示例。有问题的错误是由未发布的代码引起的。一个简单的方法来证明这是简单地运行在一个小例子,所提供的代码(没有其他活动),并看到它并没有失败。
ioutil.ReadFile当然,函数关闭文件。在这种情况下,它被牵连,仅仅是因为它试图在已经达到资源限制时打开一个新文件。
Go 中的一个常见问题是无法关闭隐式打开的流。这种情况的一个特殊情况是在使用http库的客户端函数时打开了一个流。
客户端必须在完成后关闭响应主体:
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
Run Code Online (Sandbox Code Playgroud)
此类请求应始终包括对 的调用Close,使用如上所示的形式。
可能还有其他类似的隐式流被打开的情况......
这是一个特别棘手的问题,因为对于琐碎的程序,您永远不会知道其中的区别。直到您通过数百或数千次迭代运行它,您才会知道存在问题。然后,错误可能经常表现为一些不相关的函数调用失败——正如 OP 所证明的那样。
基本上在UNIX平台上,OS限制了进程在任何给定时间可能具有的打开文件描述符的数量。由于您已达到当前打开的文件(和/或管道或套接字)的限制,并且尝试打开新文件(和/或管道或套接字),因此引发了
错误too many open files。
为避免此问题,您必须在使用Close()函数完成使用打开文件的操作后关闭文件
| 归档时间: |
|
| 查看次数: |
10676 次 |
| 最近记录: |