从标准输入读取大量数据

huangapple go评论79阅读模式
英文:

Read large amount of data from standard input

问题

在Golang中,从标准输入(stdin)读取大量数据的方法是使用bufio包中的Scanner类型。以下是你的代码的翻译版本:

import (
	"bufio"
	"fmt"
	"os"
)

var stdinReader = bufio.NewReader(os.Stdin)

// Input 从stdin读取输入并回显。
func Input(prompt string) []byte {
	var data []byte

	// 输出提示信息。
	fmt.Print(prompt)

	// 读取直到换行符。
	for {
		bytes, isPrefix, _ := stdinReader.ReadLine()
		data = append(data, bytes...)

		if !isPrefix {
			break
		}
	}

	// 一切顺利。返回数据。
	return data
}

你也可以尝试使用Scanner类型来实现退出逻辑,当用户按下回车键时退出循环。以下是相应的代码:

import (
	"bufio"
	"fmt"
	"os"
)

var stdinScanner = bufio.NewScanner(os.Stdin)

// Input 从stdin读取输入并回显。
func Input(prompt string) []byte {
	var data []byte

	// 输出提示信息。
	fmt.Print(prompt)

	// 读取直到换行符。
	for stdinScanner.Scan() {
		bytes := stdinScanner.Bytes()
		data = append(data, bytes...)

		if len(bytes) == 0 {
			break
		}
	}

	// 一切顺利。返回数据。
	return data
}

如果你想使用ReadBytes('\n')方法,但是发现它在4095字节处停止,那么可能是因为默认的缓冲区大小限制。你可以通过调用Scanner的Buffer方法来设置更大的缓冲区大小,例如:

stdinScanner.Buffer(make([]byte, 8192), bufio.MaxScanTokenSize)

这将创建一个大小为8192字节的缓冲区,并将其分配给Scanner。这样就可以读取更多的数据了。

英文:

How do you read lots of data from stdin in Golang? All of my reads currently stop at 4095 bytes. I've tried lots of things but my current code looks like:

var stdinReader = bufio.NewReader(os.stdin)

// Input reads from stdin while echoing back.
func Input(prompt string) []byte {
	var data []byte

	// Output prompt.
	fmt.Print(prompt)

	// Read until newline.
	for {
		bytes, isPrefix, _ := stdinReader.ReadLine()
		data = append(data, bytes...)

		if !isPrefix {
			break
		}
	}

	// Everything went well. Return the data.
	return data
}

I've also tried using a scanner but couldn't figure out how to exit

for scanner.Scan() {
    data = append(data, scanner.Bytes()...)
}

when a newline occurred (i.e. when the user pressed return).

I also tried ReadBytes('\n') but even that stopped at 4095 bytes. Short of increasing the size of the buffer (which is just an ugly hack) I'm not sure what to do at this point.

答案1

得分: 2

如果你查看Go的源代码,你会发现它使用了默认的缓冲区大小:

func NewReader(rd io.Reader) *Reader {
    return NewReaderSize(rd, defaultBufSize)
}

所以你可以在你的代码中这样使用:

var stdinReader = bufio.NewReaderSize(os.Stdin, 10000)

附注:
Go是开源的,所以你可以通过查看内部实现来学到很多。

英文:

If you'll look at Go sources, you will see that it uses default buffer size:

func NewReader(rd io.Reader) *Reader {
	return NewReaderSize(rd, defaultBufSize)
}

So you can use in your code as:

var stdinReader = bufio.NewReaderSize(os.Stdin, 10000)

P.S.
Go is open source, so you can learn a lot just from looking inside internals.

huangapple
  • 本文由 发表于 2017年3月14日 15:17:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/42779856.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定