登录
首页 >  Golang >  Go问答

如何按长度为n的块读取大文件

来源:stackoverflow

时间:2024-04-08 22:57:30 316浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《如何按长度为n的块读取大文件》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我想读取大型文本文件(接近 3gb)并将其拆分为具有 n 个符号长度的块。我试图使用符文读取文件并拆分,但它需要大量内存。

func SplitSubN(s string, n int) []string {
    sub := ""
    subs := []string{}
    runes := bytes.Runes([]byte(s))
    l := len(runes)
    for i, r := range runes {
        sub = sub + string(r)
        if (i+1)%n == 0 {
            subs = append(subs, sub)
            sub = ""
        } else if (i + 1) == l {
            subs = append(subs, sub)
        }
    }
    return subs
}

我认为它可以以更智能的方式完成,例如从文件中分阶段读取特定长度的块,但我不知道如何正确执行。


解决方案


扫描 rune start 字节并据此进行分割。这消除了函数内除结果切片分配之外的所有分配。

func splitsubn(s string, n int) []string {
    if len(s) == 0 {
        return nil
    }
    m := 0
    i := 0
    j := 1
    var result []string
    for ; j < len(s); j++ {
        if utf8.runestart(s[j]) {
            if (m+1)%n == 0 {
                result = append(result, s[i:j])
                i = j
            }
            m++
        }
    }
    if j > i {
        result = append(result, s[i:j])
    }
    return result

}

问题中指定的 api 要求应用程序在将从文件读取的 []byte 转换为字符串时分配内存。通过更改函数以处理字节可以避免这种分配:

func SplitSubN(s []byte, n int) [][]byte {
    if len(s) == 0 {
        return nil
    }
    m := 0
    i := 0
    j := 1
    var result [][]byte
    for ; j < len(s); j++ {
        if utf8.RuneStart(s[j]) {
            if (m+1)%n == 0 {
                result = append(result, s[i:j])
                i = j
            }
            m++
        }
    }
    if j > i {
        result = append(result, s[i:j])
    }
    return result

}

这两个函数都要求应用程序将整个文件放入内存中。我认为这没问题,因为问题中的函数也可以。如果您一次只需要处理一个块,那么上面的代码适合在文件增量读取时进行扫描。

本篇关于《如何按长度为n的块读取大文件》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

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