我想运行一堆goroutine来将大量的.csv文件插入到postgres数据库中。我将.csv文件读取到一个对象,然后尝试将对象分成10个部分。当文件数量可以精确地分割为10时,这种方法非常有效,但是当它不是panic: runtime error: slice bounds out of range
时。
如果i + len(fis)/gophers
返回浮点数,那将是明智的,但事实并非如此。当我使用Goland-IDE的debgging模式时,i
和i + len(fis)/gophers
的结果都是完整的整数。
有关此错误发生原因的任何线索提示?我最感兴趣的原因是为什么会发生这种情况,但如果有人能提出除%
- 运算符之外的其他解决方案,我也会感到好奇。
提前致谢!
编辑:我的印象是第一次迭代时返回错误(此时,根据调试器,i
和i + len(fis)/gophers
都在len(fis)
的范围内。目录中的文件数量是2568.事实证明错误发生在最后一次迭代上。感谢Berry指出这一点。
//Read files from download-folder
f, _ := os.Open(dlFolder)
fis, _ := f.Readdir(-1)
f.Close()
var wg sync.WaitGroup
gophers := 10
//Split slice of files into 10 chunks and run a goroutine for each of them
for i := 0; i < len(fis) ; i = i + len(fis)/gophers{
wg.Add(1)
xFiles := fis[i:i + len(fis)/gophers]
go csvTSql(xFiles)
}
wg.Wait()
答案 0 :(得分:3)
再次检查。如果i + len(fis)/gophers
无法被len(fis)
整除,gophers
将不会受到约束。它将超过最后一次迭代的界限。
有很多方法可以解决此问题,例如检查i + len(fis)/gophers > len(fis) - 1
是否重置,如果是,则重置值。您也可以使用math.Min
来电。
chunk := int(math.Min(float64(i+len(fis)/gophers), float64(len(fis))))
xFiles := fis[i:chunk]