2ord
@2ord
продвинутый чайник

Как применить множество фильтров на входящий поток?

Есть код, который обрабатывает входной поток stdin и выдает на stdout.
var input io.ReadCloser

	reader := bufio.NewReader(input)
 
	for {
		in, _, err := reader.ReadLine()
		if err != nil && err == io.EOF {
			break
		}
 
		in = append(in, []byte("\n")...)
		if _, err := w.Write(in); err != nil {
			log.Fatalln(err)
		}
	}

Хочу добавить дополнительные фильтры на входящий поток.
Фильтр будет реализовывать интерфейс с функцией Filter(io.Reader, io.Writer) error
Как, имея массив фильтров, обработать входящий поток так, чтобы не было блокировок и в input находился обработанный поток после применения последнего фильтра?
То есть, по аналогии с применением pipe в командной строке.
Желательно, чтобы смог использовать типа функции applyFilters(input io.Reader) (io.Reader, error). Тогда я бы смог написать
filteredInput, err = applyFilters(input)
reader := bufio.NewReader(filteredInput)

Использовать io.Pipe? Если да, то как?
  • Вопрос задан
  • 129 просмотров
Решения вопроса 1
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Еще например вот так можно
type FReader struct {
	reader io.Reader
	filter func([]byte) (int, error)
}
func NewFReader(r io.Reader) *FReader {
	return &FReader{r, func(p []byte) (int, error) { return len(p), nil }}
}
func (fr *FReader) Filter(filter func([]byte) (int, error)) *FReader {
	return &FReader{fr, filter}
}
func (fr *FReader) Read(p []byte) (n int, err error) {
	n, err = fr.reader.Read(p)
	if err == nil && fr.filter != nil {
		n, err = fr.filter(p)
	}
	return
}

тогда можно написать
chainreader := NewFReader(myreader).Filter(myfilter1).Filter(myfilter2).Filter(myfilter3)
https://play.golang.org/p/rakSV5kgqR9
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
имея массив фильтров
Не надо фильтры ложить в массив)

обработать входящий поток так, чтобы не было блокировок и в input находился обработанный поток после применения последнего фильтра?
Каналы вам в помощь.

То есть, по аналогии с применением pipe в командной строке.
Да-да, каналы вам в помощь) Они примерно так и работают.

Вообще в теле твоей функции чтения содержимого файла можно добавить вызовы анонимных функций, в которых будет описана фильтрация, или дёргать другие функции, можно написать метод (в зависимости как собираешься фильтровать), можно пойти "через каналы". По идее блокировок возникнуть не должно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы