当前位置: 首页 > 面试题库 >

Golang从管道中读取大量数据

南门鸿振
2023-03-14
问题内容

我试图读取就是BEING柏油,流媒体,以标准输入存档,但我不知怎么读 远远 在管道的数据超过焦油发送。

我这样运行我的命令:

tar -cf - somefolder | ./my-go-binary

源代码是这样的:

package main

import (
    "bufio"
    "io"
    "log"
    "os"
)

// Read from standard input
func main() {
    reader := bufio.NewReader(os.Stdin)
    // Read all data from stdin, processing subsequent reads as chunks.
    parts := 0
    for {
        parts++
        data := make([]byte, 4<<20) // Read 4MB at a time
        _, err := reader.Read(data)
        if err == io.EOF {
            break
        } else if err != nil {
            log.Fatalf("Problems reading from input: %s", err)
        }
    }
    log.Printf("Total parts processed: %d\n", parts)
}

对于100MB的涂油文件夹,我将获得1468个4MB的块(即6.15GB)!此外,data []byte数组的大小似乎无关紧要:如果将块大小设置为40MB,我仍然会获得约1400个40MB数据块,这根本没有意义。

os.Stdin使用Go正确读取数据,我需要做些什么吗?


问题答案:

您的代码效率低下。data每次通过循环分配和初始化。

for {
    data := make([]byte, 4<<20) // Read 4MB at a time
}

为你的代码reader作为io.Reader是错误的。例如,您忽略了读取的字节数,_, err := reader.Read(data)并且无法err正确处理错误。

套餐io

import "io"

类型阅读器

type Reader interface {
        Read(p []byte) (n int, err error)
}

Reader是包装基本Read方法的接口。

Read将最多len(p)个字节读入p。它返回读取的字节数(0 <= n <= len(p))和遇到的任何错误。即使Read返回n
<len(p),也可能在调用过程中将所有p用作临时空间。如果某些数据可用但不是len(p)个字节,则按常规方式,Read将返回可用数据,而不是等待更多数据。

当成功读取n> 0个字节后,Read遇到错误或文件结束条件时,它将返回读取的字节数。它可能从同一调用返回(非nil)错误,或者从后续调用返回错误(n
== 0)。这种一般情况的一个实例是,读取器在输入流的末尾返回非零字节数的情况下,可能返回err == EOF或err ==
nil。下一次读取应返回0,无论EOF为何。

在考虑错误err之前,调用者应始终处理返回的n> 0个字节。这样做可以正确处理在读取某些字节后发生的I / O错误,以及两种允许的EOF行为。

不鼓励Read的实现不返回零字节且错误为nil的计数,除非len(p)== 0除外。调用者应将返回0和nil视为没有任何反应;特别是它并不表示EOF。

实现不得保留p。

这是符合io.Reader接口的模型文件读取程序:

package main

import (
    "bufio"
    "io"
    "log"
    "os"
)

func main() {
    nBytes, nChunks := int64(0), int64(0)
    r := bufio.NewReader(os.Stdin)
    buf := make([]byte, 0, 4*1024)
    for {
        n, err := r.Read(buf[:cap(buf)])
        buf = buf[:n]
        if n == 0 {
            if err == nil {
                continue
            }
            if err == io.EOF {
                break
            }
            log.Fatal(err)
        }
        nChunks++
        nBytes += int64(len(buf))
        // process buf
        if err != nil && err != io.EOF {
            log.Fatal(err)
        }
    }
    log.Println("Bytes:", nBytes, "Chunks:", nChunks)
}

输出:

2014/11/29 10:00:05字节:5589891块:1365


 类似资料:
  • 问题内容: 我正在尝试从golang中的telnet会话读取数据。为了达到这个目的,我编写了以下函数。 最初,我遇到一个问题,即我从没有数据的套接字读取数据,因此它将锁定并且永远不会返回。BufferSocketData是我尝试解决此问题的方法,因为我不知道是否有要读取的数据。这个想法是它将等待1秒钟,然后确定套接字中没有数据并返回一个空字符串。 GetData似乎第一次在缓冲区中有新数据时起作用

  • 问题内容: 我是Golang的新手。现在,我正在尝试找出如何在Golang中建立任意一对一频道的方法,其设置如下: 说我有两个goroutines numgen1和numgen2同时执行并将数字写入通道num1resp。num2。我想在新进程addnum中添加从numgen1和numgen2发送的数字。我已经尝试过这样的事情: 但这似乎令人遗憾。有人可以给我一些想法吗? 非常感谢您的帮助。 问题答

  • 问题内容: 我知道 bufio 包中的golang中的特定功能。 Peek返回下一个n个字节, 而不会使阅读器前进 。在下一个读取调用中,字节停止有效。如果Peek返回的字节数少于n个字节,则它还会返回一个错误,解释读取短的原因。如果n大于b的缓冲区大小,则错误为ErrBufferFull。 我需要能够从阅读器读取特定数量的字节,以 使阅读器更先进 。基本上,与上面的功能相同,但是它使阅读器更高级

  • 问题内容: 我有包含以下格式的数字的文本文件: 现在,我需要读取该数据并将其分配给变量(前两个数字),并将其余所有数据( 1 000 000个 数字)分配给数组。 这不是一项艰巨的任务,但是-这太慢了。 我的第一次尝试是: 它按例外方式工作,但执行大约需要 7500毫秒 。我需要在几百毫秒内获取该数据。 然后我尝试了: 使用和我大约在 1700毫秒内 得到了相同的结果,但是仍然太多了。 如何在不到

  • 问题内容: 我正在尝试从golang中的SSH会话读取数据。我编写了以下函数来尝试实现此目的。 我遇到了一个问题,尝试从stdout读取内容,它为空,导致程序锁定。为了解决这个问题,我编写了BufferSocketData,它检查ReadDataFromSocket应该附加到的通道,如果它有数据,则将其添加到缓冲区。如果1秒钟后仍未收到任何数据,它将停止读取。 但是,这不能正常工作,我不确定为什么

  • 我正在尝试从管道(如stdin,named pipe等)加载图像。 这是我的示例代码: #包括“opencv2/opencv.hpp” 使用名称空间CV; int main(int argc,char**argv){ } 会有用的,但是 而且 不能工作,并且Mat img的行和列为0。 真正的文件和管道有什么区别?