英文:
GoLang File Transfer Stops Without Any Error
问题
我正在运行一个简单的文件传输代码,使用go
语言。从服务器端,我尝试每次读取1024字节的数据。从客户端,我使用io.Copy
函数来传输文件。文件传输成功完成的概率为70%。但是在30%的情况下会失败。它在connection.Read
函数上卡住。通过一些实验,我发现只有在之前的Read
操作读取的数据少于1024
字节的情况下才会发生这种情况。
所以根据我的代码,理想情况下,除了最后一个Read
操作,在所有连续的Read
操作中都应该读取1024
字节的数据。但是在某些情况下,如果读取的字节数少于1024
,下一个Read
操作会卡住而不抛出任何错误。以下是我的代码:
- Server.go
fileBuffer := make([]byte, BUFFER_SIZE) // BUFFER_SIZE是一个常量,值为1024
bytesRead := int64(0)
count := 0
for {
if fileSize-bytesRead < int64(BUFFER_SIZE) { // fileSize是文件的字节数,我之前计算得到的
fileBuffer = make([]byte, fileSize-bytesRead)
}
fmt.Println("Reading", BUFFER_SIZE, "bytes of data")
n, err := connection.Read(fileBuffer)
count++
fmt.Println("Completed reading", n, "bytes of data, count=", count)
file.Write(fileBuffer[0:n])
bytesRead += int64(n)
fmt.Println("So far read", bytesRead, "bytes of data")
if err != nil {
fmt.Println(err)
}
if err == io.EOF {
result.Message = "文件传输不完整"
break
}
if bytesRead >= fileSize {
result.Message = "文件传输完成"
break
}
}
- Client.go
n, err := io.Copy(conn, file)
fmt.Println(n, "bytes sent")
对于我的情况,发送的字节数是正确的,接收的字节数在成功传输时也是正确的。问题发生在相同的文件上。
英文:
I've running a simple file transfer code in go
. From the server side I try to read 1024 bytes of data at a time. From client side I'm using the io.Copy
function to transfer the file. The file transfer completes successfully 70% of the time. But in 30% of time it fails. It gets stuck on connection.Read
function. Through some experiments I saw that it happens only on the occasion where previous Read
operation reads less than 1024
bytes of data.
So from my code, ideally it should read 1024
bytes of data on all successive Read
except the very last Read
where the file transfer is complete. But on some occasion if it reads less than 1024
bytes, the next Read
operation gets stuck without throwing any error. Here is my code:
-
Server.go
fileBuffer := make([]byte, BUFFER_SIZE) //BUFFER_SIZE is a constant of 1024 bytesRead := int64(0) count := 0 for { if fileSize-bytesRead < int64(BUFFER_SIZE) { //fileSize is the size of file in bytes, which I calculated earlier. fileBuffer = make([]byte, fileSize-bytesRead) } fmt.Println("Reading ", BUFFER_SIZE, " bytes of data") n, err := connection.Read(fileBuffer) count++ fmt.Println("Completed reading", n, " bytes of data, count=", count) file.Write(fileBuffer[0:n]) bytesRead += int64(n) fmt.Println("So far read", bytesRead, " bytes of data") if err != nil { fmt.Println(err) } if err == io.EOF { result.Message = "File transfer incomplete" break } if bytesRead >= fileSize { result.Message = "File transfer complete" break } }
-
Client.go
n, err := io.Copy(conn, file) fmt.Println(n, " bytes sent")
For my case, number of sent bytes is correct, number of received bytes is also correct on successful transfer. The problem happens for the same file.
答案1
得分: 5
TL;DR: 这是你需要复制文件的全部代码。
if _, err := io.Copy(file, connection); err != nil {
// 处理错误
}
如果你需要在复制过程中分块复制,并在复制之间执行一些逻辑(例如,打印读取的字节数),你可以使用 io.CopyN
。
totalRead := int64(0)
for {
n, err := io.CopyN(outfile, infile, 1024)
totalRead += n
// 打印读取的字节数,后面跟一个回车符
fmt.Printf("读取的字节数:%d\r", totalRead)
if err != nil {
if err == io.EOF {
fmt.Println() // 打印一个换行符
break
}
// 处理错误
}
}
英文:
TL;DR: This should be all you need to copy a file.
if _, err := io.Copy(file, connection); err != nil {
// handle error
}
If you need to copy in chunks while doing some logic in between copies (for example, printing the bytes read), you can use io.CopyN
totalRead := int64(0)
for {
n, err := io.CopyN(outfile, infile, 1024)
totalRead += n
// print bytes read followed by a carriage return
fmt.Printf("Bytes read: %d\r", totalRead)
if err != nil {
if err == io.EOF {
fmt.Println() // print a newline
break
}
// handle error
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论