Среди свойств файла есть одиночная позиция чтения, а не одна для сканера, для потока или для каждой процедуры. Когда вы разделяете один os.File
между несколькими объектами сканера (или чем-либо еще), первый, который читает из файла, будет продвигать указатель чтения для любого другого сканера. В вашем примере первая выполняемая программа будет читать строку из файла, а вторая пытается прочитать, но уже находится в конце файла.
Чтобы это работало, вам нужно только одно прочитать этофайл, и вам нужно убедиться, что данные, отправляемые вами в подпрограммы, не передаются (вы не будете многократно читать в один буфер и отправлять этот же буфер везде, где при следующем чтении он будет перезаписан).
Это хорошее время, чтобы подумать о параллелизме, и если это действительно стоит затраченных усилий. Самая медленная часть этой программы, безусловно, будет фактически читать файл с диска, и нетколичество горутин сделает это быстрее. Дополнительная оптимальная копия буфера не требуется в оптимальной однопоточной программе, и синхронизация с обычными процессами также требует больших затрат. Моя интуиция заключается в том, что использование здесь подпрограмм делает программу намного более сложной и потенциально медленной.
Основное изменение, которое я внесу в вашу программу, заключается в том, что только одна вещь читает файл;например, основной цикл в вашей программе. Пакет bufio
включает в себя объект Scanner
, который может одновременно считывать файл и создавать скопированную строку. Я бы однажды запустил пул рабочих подпрограмм, а затем добавил в них строки:
lines := make(chan string)
file, err := os.Open("./strangeness/abc.txt")
if err != nil { ... }
scan := bufio.NewScanner(file)
for scan.Scan() {
lines <- scan.Text()
}
close(lines)
https://play.golang.org/p/o7UwZrgfVy7 имеет более полный пример, который компилируется. Обратите внимание, что структура подпрограммы требует некоторых рассуждений: я запустил отдельную подпрограмму для обработки результатов, и у меня есть отдельный канал для оповещения о его завершении.