登录
首页 >  Golang >  Go问答

使用Golang将标准输入流分块写入文件

来源:stackoverflow

时间:2024-02-08 15:33:14 460浏览 收藏

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《使用Golang将标准输入流分块写入文件》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~

问题内容

我不想将管道写入一个大文件,而是想在信号 usr1 上将流分段。我认为我已经掌握了基础知识,但应用程序只是挂起并且没有任何反应,在处理无法控制的输入流和字节完美分段时有任何线索或最佳实践吗?

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "os/signal"
    "syscall"
    "time"
)

var done bool

func handle(c chan os.Signal) {
    for {
        sig := <-c
        switch sig {
        case syscall.SIGUSR1:
            fmt.Println("###Sink temporarily_closed###")
            done = true
        case syscall.SIGUSR2:
            fmt.Println("###Sink closed###")
            done = true
        case syscall.SIGHUP:
            fmt.Println("###Sink running###")
        }
        
    }
}

func check(e error) {
    if e != nil {
        panic(e)
    }
}



func main() {
    c := make(chan os.Signal, 1)
    signal.Notify(c, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGHUP)
    go handle(c)
    
    reader := bufio.NewReaderSize(os.Stdin,1024*10)

    for true {
        if done {
            file, err := os.Create("./temp.file")
            check(err)
            writer := bufio.NewWriter(file)
            written, err := io.Copy(writer,reader)
            check(err)
            fmt.Println(written)
            writer.Flush()
            file.Close()
            reader.Reset(os.Stdin)
            done = false
        }
        time.Sleep(time.Millisecond)
    }
}

正确答案


因此,您需要在循环中使用 io.copyn(dst, src, 4096) 并偶尔旋转一次文件。参见示例。我按大小进行旋转,但添加信号处理很容易。

package main

import (
    "fmt"
    "io"
    "log"
    "os"
    "time"
)

var count int
var f *os.File

func rotate() *os.File {
    if f != nil {
        if err := f.Close(); err != nil {
            log.Fatal(err)
        }
    }

    fname := fmt.Sprintf("./dump-%d.bin", count)
    count++
    f, err := os.Create(fname)
    if err != nil {
        log.Fatal(err)
    }
    log.Println("rotated:", fname)

    return f
}

func main() {
    var n, written int
    reader := os.Stdin

    for {
        if written == 0 || written >= 4096*10 {
            f = rotate()
            written = 0
        }

        n, err := io.CopyN(f, reader, 4096)
        if err != nil {
            log.Fatal(err)
        }
        written += n
        log.Println("written:", written)
        time.Sleep(time.Millisecond * 500)
    }
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>