Ответ 1
io.ReadSeeker
- это интерфейс, который группирует базовые методы Read()
и Seek()
. Определение метода Seek()
:
Seek(offset int64, whence int) (int64, error)
Реализация метода Seek()
требует возможности искать в любом месте источника, что требует, чтобы весь источник был доступен или воспроизводимым. Файл является прекрасным примером, файл постоянно сохраняется на вашем диске, и любая его часть может быть прочитана в любое время.
response.Body
реализуется для чтения из базового TCP-соединения. Чтение из базового TCP-соединения дает вам данные, которые отправляет вам клиент с другой стороны. Данные не кэшируются, и клиент не будет отправлять вам данные по запросу. Поэтому response.Body
не реализует io.Seeker
(и, следовательно, io.ReadSeeker
).
Итак, чтобы получить io.ReadSeeker
от io.Reader
или io.ReadCloser
, вам нужно что-то, что кэширует все данные, так что по запросу он может искать в любом месте.
Этот механизм кэширования может записывать его в файл, как вы упомянули, или вы можете прочитать все в памяти, в []byte
, используя ioutil.ReadAll()
, а затем вы можете использовать bytes.NewReader()
, чтобы получить io.ReadSeeker
от []byte
. Конечно, это имеет свои ограничения: все содержимое должно вписываться в память, а также вы можете не захотеть зарезервировать этот объем памяти для этой операции копирования файлов.
В целом, реализация io.Seeker
или io.ReadSeeker
требует, чтобы все исходные данные были доступны, поэтому лучше всего записать его в файл или для чтения небольших файлов в []byte
и потоковой передачи содержимое этого байтового фрагмента.