Последовательное использование разных считывателей в файле

#csv #go

#csv #Вперед

Вопрос:

Я анализирую файл данных определенного типа, который очень похож на файл csv, за исключением того, что в нем есть несколько дополнительных строк заголовка (что делает его в целом недопустимым csv). Хотя я могу написать приличный синтаксический анализатор, используя bufio.Читатель сканера, я бы очень хотел использовать программу чтения пакетов encoding / csv, как только я закончу сканирование строк заголовка. Моя проблема в том, что я не уверен, какой наилучший способ передать оставшиеся непрочитанные строки в программу чтения csv. В настоящее время я использую ввод-вывод.Канал, подобный этому

 // s is the bufio.Scanner which has finished scanning the header lines
r,w := io.Pipe()
go func() {
    // Flush scanner into pipe
    for s.Scan() {
        fmt.Fprintln(w, s.Text())
    }
    w.Close()
}()
c := csv.NewReader(r)
  

и, похоже, это работает, но мне интересно, есть ли какие-либо проблемы с этим или есть более элегантный способ передать частично прочитанный поток ввода-вывода другому считывателю. Кроме того, я не думаю, что мог бы использовать вышеуказанный метод, если бы мой раздел csv был первым (т. Е. Если бы мне нужно было анализировать строки, отличные от csv, после csv-подобной части), потому что очистка с помощью вызовов csv.Read привела бы к ошибкам.

Комментарии:

1. Единственный риск заключается в том, что вы считываете слишком много данных из считывателя, прежде чем передавать их csv.NewReader . Допустим, вы прочитали 100 байт, и вам нужно только 50 из них, тогда остальные 50 байт, вероятно, содержат csv.Reader необходимые данные. Вы можете исправить это с помощью io.MultiReader : csv.NewReader(io.MutliReader(bytes.NewReader(unusedBytes), r)))

2. Чтобы добавить к комментарию Флимзи, это риск, если вы используете любой считыватель, который использует буфер внутри — т. Е. Ваш собственный код может не читать слишком далеко, но читатель все равно может.

3. Спасибо, это действительно полезно. Кстати, я также обнаружил, что могу в определенной степени манипулировать синтаксическим анализом csv, изменяя переменную FieldsPerRecord в процессе синтаксического анализа файла, так что в данном конкретном случае я мог бы обойтись без использования bufio Scanner для просмотра строк заголовка.