我有一个名为"DoSomething"的方法.DoSomething将采用二进制源数据对其执行操作,并写出二进制数据.DoSomething必须足够通用,以处理源和目标的[]字节数组或文件句柄.为了实现这一点,我试图声明这样的方法:
func DoSomething(source *io.ReadSeeker, destination *io.WriteSeeker)
我已经实现了ReadSeeker和WriteSeeker来使用缓冲区,使用我自己的自定义,必需的方法(如果有一种方法可以自动完成此操作,我也很乐意听到它).不幸的是,我似乎无法弄清楚如何从文件句柄创建io.ReadSeeker或io.WriteSeeker.我很确定必须有一些预处理的方法来处理它,而不必手动实现它们.这可能吗?
文件已经实现了这两个.你可以这样做:
package main
import (
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("test.txt")
if err != nil {
fmt.Println(err)
}
defer f.Close()
f2, err := os.Create("test2.txt")
if err != nil {
fmt.Println(err)
}
defer f2.Close()
DoSomething(f, f2)
}
func DoSomething(source io.ReadSeeker, destination io.WriteSeeker) {
io.Copy(destination, source)
}
Run Code Online (Sandbox Code Playgroud)
此外,您不需要将指针传递给接口,这使得处理它们变得更容易.
对于需要完成这样的事情的其他人,这就是我的结果。它并不完整,但它足以满足我的需要:
package filebuffer
import (
"bytes"
"errors"
)
type FileBuffer struct {
Buffer bytes.Buffer
Index int64
}
func NewFileBuffer() FileBuffer {
return FileBuffer{}
}
func (fbuffer *FileBuffer) Bytes() []byte {
return fbuffer.Buffer.Bytes()
}
func (fbuffer *FileBuffer) Read(p []byte) (int, error) {
n, err := bytes.NewBuffer(fbuffer.Buffer.Bytes()[fbuffer.Index:]).Read(p)
if err == nil {
if fbuffer.Index+int64(len(p)) < int64(fbuffer.Buffer.Len()) {
fbuffer.Index += int64(len(p))
} else {
fbuffer.Index = int64(fbuffer.Buffer.Len())
}
}
return n, err
}
func (fbuffer *FileBuffer) Write(p []byte) (int, error) {
n, err := fbuffer.Buffer.Write(p)
if err == nil {
fbuffer.Index = int64(fbuffer.Buffer.Len())
}
return n, err
}
func (fbuffer *FileBuffer) Seek(offset int64, whence int) (int64, error) {
var err error
var Index int64 = 0
switch whence {
case 0:
if offset >= int64(fbuffer.Buffer.Len()) || offset < 0 {
err = errors.New("Invalid Offset.")
} else {
fbuffer.Index = offset
Index = offset
}
default:
err = errors.New("Unsupported Seek Method.")
}
return Index, err
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
destination := filebuffer.NewFileBuffer()
source, err := os.Open(pathString)
if err != nil {
return nil, err
}
defer source.Close()
if _, err := encrypter.Decrypt(source, &destination, password); err != nil {
return nil, err
}
Run Code Online (Sandbox Code Playgroud)