Лучше не полагаться на конкретные типы (например, os.File
), а использовать вместо этого интерфейсы, описывающие функциональные возможности, для которых вы хотите использовать файл.
Например, еслиу вас есть функция, которая принимает файл, потому что он хочет прочитать из него, вместо этого используйте io.Reader
:
func process(r io.Reader) error {
// ...
}
Аналогично, если вы хотите записать в файл, используйте io.Writer
, или если вы хотите сделать оба, используйте io.ReadWriter
или io.ReadWriteCloser
.Вы можете передать значение *os.File
этим функциям, потому что *os.File
реализует эти интерфейсы.
Преимущество этого состоит в том, что вы можете вызывать эти функции с любыми значениями, которые реализуют интерфейс.Если вы хотите протестировать эти функции, вы можете передать в память bytes.Buffer
, который реализует io.Reader
и io.Writer
, и чей контент вы можете создать вручную, во время выполнения, например:
buf := &bytes.Buffer{}
buf.Write([]byte{1, 2, 3})
buf.WriteString("Hello")
Здесь buf
будет содержать байты 1
, 2
, 3
и строку "Hello"
.После этого вы можете передать buf
там, где требуется читатель или писатель, например:
process(buf)
См. Похожие / связанные вопросы и примеры:
Заполните os.Stdin для функциикоторый читает из него
Пример кода для тестирования файловой системы в Golang