2017-03-14 24 views
3

如何从Golang的标准输入读取大量数据?我所有的读取当前停止在4095字节。我试过很多东西,但我现在的代码如下所示:从标准输入中读取大量数据

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 
} 

我使用扫描仪也尝试过,但无法弄清楚如何退出

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

换行符发生时(即当用户按下返回时)。

我也尝试了ReadBytes('\ n'),但即使是停止在4095字节。没有增加缓冲区的大小(这只是一个丑陋的黑客攻击),我不知道该怎么做。

+0

在解决如何阅读> 4095字节的问题之前,您试图实现的目标是什么?将“大量”数据浸入字节数组通常是一个坏主意。对于大多数用例,您应该在流上操作,以获得更好的性能和更低的内存消耗。 – Flimzy

+0

@Flimzy这是一个很好的观点,我会牢记在心。我后来计划使用文件进行输入,因此它将以块(即流)的形式出现。我只是想知道是否有从stdin读取超过4095字节的习惯方式。 – Awn

+0

为什么使用[ReadLine](https://golang.org/pkg/bufio/#Reader.ReadLine)?当'stdin'没有'\ n'时,它会停下来,因为你打断了,当isPrefix。如何使用'Read()'? – apxp

回答

1

如果你看围棋的来源,你会看到它使用默认的缓冲区大小:

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

所以,你可以在你的代码中使用如:

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

附: Go是开源的,所以你只需从内部查看内容就可以学到很多东西。

+0

是的,我知道缓冲区的大小可以改变,但这不是一个很好的解决方案。 – Awn

+1

这是非常好的解决方案。您每次都必须使用限制。你没有无限的资源。只需将它设置为适合您的尺寸。这是最佳做法。 –

+0

嗯谢谢你的解决方案,但它不是我要找的。我已经考虑过这个,它不适合我的用例。 – Awn