我目前正在学习Go,并且正在尝试使用Go的net软件包通过纯TCP连接将目录的内容发送到另一台计算机。
它适用于单个文件和较小的文件夹,但是如果该文件夹包含许多子文件夹和较大的文件,则会遇到问题。我正在使用filepath.Walk
函数遍历给定目录中的所有文件。对于我发送的每个文件或目录,我还会发送一个标头,该标头为接收者提供文件名,文件大小,isDir属性,因此我知道读取内容时需要读取多长时间。 我遇到的问题是,读取标题一段时间后,即使我已经从连接中读取了该文件,我仍在读取前一个文件的实际文件内容
在这里是作家方面。我只是遍历目录。
func transferDir(session *Session, dir string) error {
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header := Header{Name: info.Name(), Size: info.Size(), Path: path}
if info.IsDir() {
header.SetDirBit()
session.WriteHeader(header)
return nil // nothing more to write
}
// content is a file. write the file now byte by byte
file, err := os.Open(path)
inf, err := file.Stat()
header.Size = inf.Size() // get the true size of the file
session.WriteHeader(header)
defer file.Close()
if err != nil {
return err
}
buf := make([]byte, BUF_SIZE)
for {
n, err := file.Read(buf)
if err != nil {
if err == io.EOF {
session.Write(buf[:n])
session.Flush()
break
} else {
log.Println(err)
return err
}
}
session.Write(buf[:n])
session.Flush()
}
return nil
})
这是读者部分
func (c *Clone) readFile(h Header) error {
file, err := os.Create(h.Path)
defer file.Close()
if err != nil {
return err
}
var receivedByts int64
fmt.Printf("Reading File: %s Size: %d\n", h.Name, h.Size)
for {
if (h.Size - receivedByts) < BUF_SIZE {
n, err := io.CopyN(file, c.sesh, (h.Size - receivedByts))
fmt.Println("Written: %d err: %s\n", n, err)
break
}
n, err := io.CopyN(file, c.sesh, BUF_SIZE)
fmt.Println("Written: %d err: %s\n", n, err)
receivedByts += BUF_SIZE
fmt.Println("Bytes Read: ", receivedByts)
}
return nil
}
现在奇怪的是,当我查看打印语句时,会看到类似以下内容的内容: 读取文件:test.txt大小:14024
书面1024无
读取的字节数1024
...这一直持续到break语句
并且读取的字节总数等于实际文件大小。但是,后续读取标头将返回test.txt文件中的内容。几乎就像缓冲区中还有东西,但我想我已经读过了。...