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

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

本文介绍了如何使用Golang自定义扫描器字符串文字并扩展内存以将整个文件加载到内存中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图弄清楚如何实现我最初认为是简单的程序.我有一个引号的文本文件,所有引号均以"$$"

I have been trying to figure out how to implement what I originally thought would be a simple program.I have a text file of quotations that are all separated by ‘$$’

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

I want the program to parse the quotation file and randomly select 3 quotes to display and standard output.

文件中有1022个引号.

There are 1022 quotes in the file.

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

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

I can’t seem to figure out how to assign $$ with a string literal, I keep getting:
missing '

这是自定义扫描仪:

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
        }
    }

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

The string literal works fine if I only use one $.

由于某些原因,仅将71个报价加载到报价切片中.我不确定如何扩展.允许将所有1022个引用都存储在内存中.

For some reason only 71 quotations are loaded into the quotes slice. I'm not sure how to expand. To allow all 1022 quotes to be stored in memory.

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

I've been having a really difficult time trying to figure out how to do this. this is what I have right now:

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))])
}

推荐答案

如果最终还是要读取整个文件,则使用扫描仪是一件令人费解的事情.我将阅读整个文件,然后将其拆分为引号列表:

Using a scanner if you end up reading the whole file anyway is kind of convoluted. I'd read the whole file and then simply split it into the list of 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
    }
}

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

Using a scanner would make sense if you selected three quotes before reading the file; then you can stop reading after you have reached the last quote.

这篇关于如何使用Golang自定义扫描器字符串文字并扩展内存以将整个文件加载到内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 02:36