gpt4 book ai didi

go - 模拟 bufio.Scanner 输入

转载 作者:IT王子 更新时间:2023-10-29 02:07:53 24 4
gpt4 key购买 nike

在测试期间,我在定义接口(interface)和替换模拟方面取得了很多成功,但我在模拟 bufio.Scanner 输入时遇到了问题:

file := &mockFile{
ReadFunc: func(p []byte) (int, error) {
reader := bufio.NewReader(bytes.NewReader([]byte(consulPropertiesFile)))
return reader.Read(p)
},
CloseFunc: func() error {
return nil
},
}

fs := &mockFileSystem{
OpenFunc: func(name string) (File, error) {
return file, nil
},
}

properties, err := readConsulPropertiesFile(fs)

虽然这似乎可行,但一旦扫描器到达我的字符串末尾,它似乎就回到了开头,并且读取了太多(这次它似乎读取了不止一行)。这就像我需要在适当的时间在我的 ReadFunc 中手动返回 EOF 错误,但我不确定如何确定何时应该这样做...

扫描器代码(从 here 提取):

f, err := file.Open("/run/secrets/consul-web4.properties")
if err != nil {
return nil, err
}
defer f.Close()

properties := map[string]string{}

scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if equal := strings.Index(line, "="); equal >= 0 {
if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
value := ""
if len(line) > equal {
value = strings.TrimSpace(line[equal+1:])
}
properties[key] = value
}
}
}

我还没有重构上面的...

我在我的测试字符串上尝试了以下变体:

const input = `key=value
key=value
key=value
`
const input = "key=value\nkey=value\nkey=value\n"

我已经尝试过 bufio.Reader 和 io.Reader 的实现。

感谢任何帮助/见解!

最佳答案

感谢@Adrian:

我在回家的路上意识到这可能是由于每次调用该方法时都会实例化一个新的阅读器。将读取器实例化从我的 ReadFunc 中移出效果非常好!

感谢@Thundercat 提供的strings.NewReader() 提示,更新代码:

reader := ioutil.NopCloser(strings.NewReader(consulPropertiesFile))

file := &mockFile{
ReadFunc: func(p []byte) (int, error) {
return reader.Read(p)
},
CloseFunc: func() error {
return nil
},
}

对于看到这篇文章并寻找有关如何模拟文件系统等信息的人:

用于打开和统计文件的接口(interface),以及使用 os 包的具体实现:

// FileSystem - interface to the filesystem
type FileSystem interface {
Open(name string) (File, error)
Stat(name string) (os.FileInfo, error)
}

// OsFS - filesystem backed by default os package
type OsFS struct {
}

// Open - open a file
func (o *OsFS) Open(name string) (File, error) {
return os.Open(name)
}

// Stat - get file status
func (o *OsFS) Stat(name string) (os.FileInfo, error) {
return os.Stat(name)
}

上面提到的文件接口(interface):

// File - file interface
type File interface {
io.Closer
io.Reader
io.ReaderAt
io.Seeker
Stat() (os.FileInfo, error)
}

模拟您希望文件系统返回的文件(实现您的代码将使用的方法):

type mockFile struct {
CloseFunc func() error
ReadFunc func(p []byte) (int, error)
ReadAtFunc func(p []byte, off int64) (int, error)
SeekFunc func(offset int64, whence int) (int64, error)
StatFunc func() (os.FileInfo, error)
}

func (m *mockFile) Close() error {
return m.CloseFunc()
}

func (m *mockFile) Read(p []byte) (int, error) {
return m.ReadFunc(p)
}

func (m *mockFile) ReadAt(p []byte, off int64) (int, error) {
return m.ReadAtFunc(p, off)
}

func (m *mockFile) Seek(offset int64, whence int) (int64, error) {
return m.SeekFunc(offset, whence)
}

func (m *mockFile) Stat() (os.FileInfo, error) {
return m.StatFunc()
}

---

reader := ioutil.NopCloser(strings.NewReader("some string, replace with bytes etc"))

file := &mockFile{
ReadFunc: func(p []byte) (int, error) {
return reader.Read(p)
},
CloseFunc: func() error {
return nil
},
}

然后通过 mockFileSystem 返回你的 mockFile:

fs := &mockFileSystem{
OpenFunc: func(name string) (File, error) {
return file, nil
},
}

关于go - 模拟 bufio.Scanner 输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54406712/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com