英文:
Troubles with Golang append() and for loop
问题
我正在尝试使用缓冲区从conn接收数据。我在reader.Read周围有一个for循环,并且当reader返回一个标明EOF的err时,我将跳出循环。然而,似乎循环外的所有内容都不再定义。
我遇到的第二个问题是我无法追加两个切片。我尝试使用dataFile = append(dataFile, buff)
,但它说我不能使用[]byte。据我了解,你可以像那样追加两个切片。我错在哪里?
以下是代码:
import (
"fmt"
"net"
"log"
"bufio"
"os"
"io"
)
func readData(conn net.Conn){
fmt.Println("Reading data...\n")
// 从conn创建一个新的reader
reader := bufio.NewReader(conn)
// 创建一个切片来保存所有传输的数据
var dataFile []byte
// 创建一个缓冲区来存储从conn传输的信息
buff := make([]byte, 4096)
for {
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff...)
if err != nil {
if err != io.EOF{
log.Fatalln(err)
}
break // 当err返回EOF时跳出循环
}
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", bytesReturned,"bytes.")
}
// 主函数开始 --------------------------------
func main(){
// 监听本地端口80
listener, err := net.Listen("tcp", ":5555")
if err != nil {
log.Fatalln("Unable to bind port")
}
fmt.Println("Port 5555 binded...\n")
// 处理多个连接
for {
conn, err := listener.Accept()
if err != nil {
log.Fatalln("Unable to accept connection...")
}
go readData(conn)
}
}
这是收到的错误的图片
https://i.stack.imgur.com/7gJP9.png
英文:
I am trying to use a buffer to receive data from conn. I have a for loop around reader.Read and will break the loop when the reader comes back with an err stating EOF. However, it seems everything outside of the loop is no longer defined.
The second issue I am running into is I cannot append two slices. I try and use
dataFile = append(dataFile, buff)
but it says that I cannot use []byte. To my understanding you are able to append two slices like that. Where am I going wrong?
Here is the code:
import (
"fmt"
"net"
"log"
"bufio"
"os"
"io"
)
func readData(conn net.Conn){
fmt.Println("Reading data...\n")
// Create a new reader from conn
reader := bufio.NewReader(conn)
// Make a slice to hold all data being transmitted
var dataFile []byte
// Create a buffer to store information as it comes across conn
buff := make([]byte, 4096)
for {
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff)
if err != nil {
if err != io.EOF{
log.Fatalln(err)
}
break //Break the loop when err returns EOF
}
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", bytesReturned,"bytes.")
}
// Start of main --------------------------------
func main(){
//Listen on local port 80
listener, err := net.Listen("tcp", ":5555")
if err != nil {
log.Fatalln("Unable to bind port")
}
fmt.Println("Port 5555 binded...\n")
//handle multiple connections
for {
conn, err := listener.Accept()
if err != nil {
log.Fatalln("Unable to accept connection...")
}
go readData(conn)
}
}
Here is a picture of the errors being received
https://i.stack.imgur.com/7gJP9.png
答案1
得分: 1
这一行重新定义了bytesReturned
,遮蔽了外部作用域中的定义:
bytesReturned, err := reader.Read(buff)
使用:
var err error
bytesReturned, err = reader.Read(buff)
代替。
对于追加操作,使用append(dataFile, buff...)
。
最后,err
没有被定义,因为唯一使用的err
在for循环中,并且由于它是一个不同的块,所以在外部不被识别。使用:
err := os.WriteFile("data.txt", dataFile, 0666)
代替。
大部分程序可以用io.Copy
函数来替代。
英文:
This line redefines bytesReturned
, shadowing the definition in the outer scope:
bytesReturned, err := reader.Read(buff)
Use:
var err error
bytesReturned, err = reader.Read(buff)
instead.
For appending, use append(dataFile, buff...)
Finally, err
is not defined, because the only err
used is in the for-loop, and since it is a different block, that err
is not recognized outside. Use:
err := os.WriteFile("data.txt", dataFile, 0666)
Instead.
Most of the program can be replaced with a call to io.Copy
.
答案2
得分: 0
追加读取的字节,而不是缓冲区本身。
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff[:bytesReturned]...)
注意使用slice表达式获取读取的字节的切片,并使用...
将切片的内容作为append
的参数。
使用短变量声明声明err
并将os.WriteFile的结果赋值给err
。
err := os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
使用缓冲区的长度报告读取的字节数:
fmt.Println("Read", len(datafile), "bytes.")
通过使用io.ReadAll简化代码:
func readData(conn net.Conn) {
fmt.Println("Reading data...\n")
dataFile, err := io.ReadAll(conn)
if err != io.EOF {
log.Fatalln(err)
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", len(dataFile), "bytes.")
}
英文:
Append the bytes read, not the buffer itself.
bytesReturned, err := reader.Read(buff)
dataFile = append(dataFile, buff[:bytesReturned]...)
Note the use of the slice expression to get a slice of the bytes read and the ...
to specify the contents of the slice as the arguments to append
.
Use a short variable declaration to declare err
and assign the result of os.WriteFile to err
.
err := os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
Use the length of the buffer to report the number of bytes read:
fmt.Println("Read", len(datafile),"bytes.")
Simplify the code by using io.ReadAll:
func readData(conn net.Conn) {
fmt.Println("Reading data...\n")
dataFile, err := io.ReadAll(conn)
if err != io.EOF {
log.Fatalln(err)
}
err = os.WriteFile("data.txt", dataFile, 0666)
if err != nil {
log.Fatal(err)
}
fmt.Println("Read", len(dataFile), "bytes.")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论