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

如何使用Golang自定义扫描器字符串文字并扩展内存以将整个文件加载到内存中?

锺离德运
2023-03-14
问题内容

我一直在试图弄清楚如何实现最初认为简单的程序。我有一个引号的文本文件,所有引号均以“ $$”分隔

我希望程序解析报价文件并随机选择3个引号来显示和标准输出。

文件中有1022个引号。

当我尝试分割文件时,出现此错误:缺少“

我似乎无法弄清楚如何为$$分配字符串文字,但我不断得到:
缺少’

这是自定义扫描仪:

onDollarSign := func(data []byte, atEOF bool) (advance int, token []byte, err error) {  
    for i := 0; i < len(data); i++ { 
        //if data[i] == "$$" {              # this is what I did originally
        //if data[i:i+2] == "$$" {    # (mismatched types []byte and string)
        //if data[i:i+2] == `$$` {    # throws (mismatched types []byte and string)
        // below throws syntax error: unexpected $ AND missing '
        if data[1:i+2] == '$$' {   
            return i + 1, data[:i], nil  
        }  
    }

如果我仅使用一个字符串文字,则可以正常工作$

由于某种原因, 仅71个报价被加载到报价切片中。 我不确定如何扩展。允许将所有1022行情存储在内存中。

我一直很难解决这个问题。这就是我现在所拥有的:

package main
import (  
    "bufio"  
    "fmt"  
    "log"  
    "math/rand"  
    "os"  
    "time"  
)

func main() {  
    rand.Seed(time.Now().UnixNano()) // Try changing this number!  
    quote_file, err := os.Open("/Users/bryan/Dropbox/quotes_file.txt")  
    if err != nil {  
        log.Fatal(err)  
    }  
    scanner := bufio.NewScanner(quote_file)  
    // define split function  
    onDollarSign := func(data []byte, atEOF bool) (advance int, token []byte, err error) {  
        for i := 0; i < len(data); i++ {  
            if data[i] == '$$' {  
                return i + 1, data[:i], nil  
            }  
        }  
        fmt.Print(data)  
        return 0, data, bufio.ErrFinalToken  
    }  
    scanner.Split(onDollarSign)  
    var quotes []string

    // I think this will scan the file and append all the parsed quotes into quotes  
    for scanner.Scan() {  
        quotes = append(quotes, scanner.Text())

    }  
    if err := scanner.Err(); err != nil {  
        fmt.Fprintln(os.Stderr, "reading input:", err)  
    }  
    fmt.Print(len(quotes))  
    fmt.Println("quote 1:", quotes[rand.Intn(len(quotes))])  
    fmt.Println("quote 2:", quotes[rand.Intn(len(quotes))])  
    fmt.Println("quote 3:", quotes[rand.Intn(len(quotes))])  
}

问题答案:

如果最终还是要读取整个文件,则使用扫描仪会有些麻烦。我将阅读整个文件,然后将其拆分为引号列表:

package main

import (
    "bytes"
    "io/ioutil"
    "log"
    "math/rand"
    "os"
)

func main() {
    // Slurp file.
    contents, err := ioutil.ReadFile("/Users/bryan/Dropbox/quotes_file.txt")
    if err != nil {
            log.Fatal(err)
    }

    // Split the quotes
    separator := []byte("$$") // Convert string to []byte
    quotes := bytes.Split(contents, separator)

    // Select three random quotes and write them to stdout
    for i := 0; i < 3; i++ {
            n := rand.Intn(len(quotes))
            quote := quotes[n]

            os.Stdout.Write(quote)
            os.Stdout.Write([]byte{'\n'}) // new line, if necessary
    }
}

如果 读取文件 之前 选择了三个引号 则使用扫描仪将很有意义。那么您可以在到达最后一个报价后停止阅读。



 类似资料:
  • 问题内容: 我想将包含字符串的巨大文件合并为一个文件,并尝试使用nio2。我不想将整个文件加载到内存中,因此我尝试了BufferedReader: 我对此进行了尝试,但是,它的工作原理,字符串的格式(例如,新行等未复制到合并文件中): 如何在不将整个文件加载到内存的情况下将大型文件与NIO2合并? 问题答案: 如果您想有效地合并两个或多个文件,则应问自己,为什么要使用基础文件并执行该任务。 通过使

  • 如何使用在目录中查找在其内容中包含特定字符串的文件。

  • 问题内容: 我只想从Excel文件(xlsx)中读取10行,而不一次加载整个文件,因为这不能在我的一台计算机上完成(内存不足)。 我尝试使用 看来文件先被加载然后又被分成几部分。 如何只读取第一行? 问题答案: 由于文件的性质(本质上是一堆压缩在一起的文件),您不能将文件戳到任意字节,而希望它成为您感兴趣的表中表格的第N行的开头。 你能做的最好是用与(从文件顶部跳过行)和(从底部跳跃行)参数。但是

  • 问题内容: 在Java中,我来自一个名为“ text”的String变量中的文本字段中的文本。 如何将“文本”变量的内容保存到文件中? 问题答案: 如果你只是输出文本,而不是任何二进制数据,则可以执行以下操作: 然后,将String写入其中,就像写入任何输出流一样: 与以往一样,你将需要异常处理。完成写作后,请务必致电。 如果你使用的是Java 7或更高版本,则可以使用“ 语句 ”,该语句将Pri

  • 问题内容: 我正在使用 map [string] string 优化代码,其中 map 的值仅为“ A”或“ B”。因此,我认为显然, map [string] bool 更好,因为该地图可容纳约5000万个元素。 结果是: 在测试时,我发现有些奇怪,为什么带有很长字符串的 a2 使用8个字节,就像 一个 只有一个字母一样? 问题答案: 不会递归地进入数据结构,它只是报告传递的值的“浅”大小。引用

  • 问题内容: 我经常使用Scanner类来读取文件,因为它非常方便。 我的问题是,以上语句是否一次将整个文件加载到内存中?或者在fileScanner上进行后续调用,例如 从文件中读取(即从外部存储而不是从内存中读取)?我问是因为我担心如果文件太大而无法一次全部读入内存会发生什么。谢谢。 问题答案: 如果您阅读了源代码,则可以自己回答问题。 看来所讨论的Scanner构造函数的实现显示: 后者包装在