8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Golang bufio.Scanner:令牌太长

Satyajay Prabhakar 2月前

232 0

我有一个大文件(对于内存来说太大了),我需要用分隔符 \'|\' 解析每个记录。问题是,每个记录的大小都不同,这就是为什么我总是收到错误 \'但是...

我有一个大文件(对于内存来说太大了),我需要用分隔符“|”解析每个记录。问题是,每个记录的大小都不同,这就是为什么我总是收到错误“bufio.Scanner:token 太长”。

如果我遇到 bufio.Scanner:token too long 错误,是否有任何方法可以用更大的缓冲区大小重试扫描?或者 bufio.Scanner 对我来说不是正确的选择,因为我不知道每个记录的确切大小?

谢谢

https://go.dev/play/p/Erx15nXXCGk

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "strings"
)

func main() {
    // Example byte array
    byteArray := []byte("data1|data2|data3|data4|data5|data6|data7|data8|data9|data10")

    // Buffer size for reading chunks
    bufferSize := 6
    buf := make([]byte, bufferSize)

    // Create a bufio.Scanner with a custom split function
    scanner := bufio.NewScanner(bytes.NewReader(byteArray))
    scanner.Buffer(buf, bufferSize)
    scanner.Split(splitFunc)

    // Read the byte array in chunks
    for scanner.Scan() {
        // Process each token (chunk)
        chunk := scanner.Text()
        fmt.Println("Chunk:", chunk, "Chunk Length:", len(chunk))
    }
    if err := scanner.Err(); err != nil {
        if err == bufio.ErrTooLong {
            fmt.Println("Error:", err)
            fmt.Printf("Buffer size %d is too small...\n", bufferSize)
        } else {
            fmt.Println("Error:", err)
        }
    }
}

func splitFunc(data []byte, atEOF bool) (advance int, token []byte, err error) {

    // Return nothing if at end of file and no data passed
    if atEOF && len(data) == 0 {
        return 0, nil, nil
    }

    if i := strings.Index(string(data), "|"); i >= 0 {
        return i + 1, data[0:i], nil
    }

    // If at end of file with data return the data
    if atEOF {
        return len(data), data, nil
    }

    return
}
帖子版权声明 1、本帖标题:Golang bufio.Scanner:令牌太长
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Satyajay Prabhakar在本站《file》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我在 Python 中有一个抽象类,如下所示:class Sinker(ABC): @abstractmethod def batch_write(self, data) -> None: pass具体类需要将数据写入某些

    我在 Python 中有一个像这样的抽象类

    class Sinker(ABC):
        @abstractmethod
        def batch_write(self, data) -> None:
            pass
    

    具体类需要将数据写入某些云数据库。我这样编写抽象类的目的是确保具体类始终实现该 batch_write() 方法。

    但是,我不确定应该输入什么类型的提示, data 因为我的一个具体班级正在期待 List[str] ,而另一个具体班级正在期待 List[dict] .

    这些只是目前我脑海中浮现的一些选择。

    1. Any
    2. List[Any]
    3. List[str|dict]

    有什么更好的方法吗? 有没有针对这种情况的风格指南?

    我尝试了所有三个选项,由于它们只是类型提示,所以不会给我带来任何麻烦。但我只是想确保我编写的代码与 OOP 中相应的最佳实践保持一致(如果有的话)。

  • 我正在 MATLAB 中开发一个项目,该项目本质上是一个具有大量参数的物理问题的线性系统求解器,这是我第一次尝试 OOP。之前,我有很多 MATLAB 脚本...

    我正在 MATLAB 中做一个项目,它本质上是一个具有大量参数的物理问题的线性系统求解器,这是我第一次尝试 OOP。之前,我有很多 MATLAB 脚本,其中包含大量非常相似的代码,所以我认为这将是一个学习 OOP 的好例子。

    我有一个类,其属性包含物理问题中可能存在的所有参数(但不一定需要所有参数),以及我想用来解决该问题的线性系统的大小。我有两个依赖属性,分别表示矩阵 A 和右侧向量 B。求解 Ax = B 是该应用程序的重点。

    我现在正尝试编写一个 get 方法来确定 B。我的问题是,这不遵循可以用类属性来一般表达的公式。(可以,但对于每个问题,方法不同。我的意思是,对于一个问题,可以有像 B(n) = obj.parameter1*obj.parameter2 这样的依赖关系,而对于另一个问题,可以有 B(n) = 3*obj.paramter(1)*obj.parameter2)

    我想知道上述内容是否意味着必须在类之外定义 B?如果是这样,我该如何避免陷入之前的情况,即有大量类似的脚本定义 B?

    在各个问题中始终一致的一点是,B 的代数定义如下:

    nj = -10:10 % array of integers from -10 to 10
    for m=1:length(nj)
        if nj(m) == 0
            B(m) = % (function)
        else
            B(m) = % (another function, dependent on m)
        end
    end
    

    我希望这是有道理的。谢谢你帮助这位无知的数学家。

  • 我有一个应用程序,允许将字符串拖放到其中一个组件上。这很好用。现在我希望能够为该操作添加自定义选项。我的第一个

    我有一个应用程序,允许将字符串拖放到其中一个组件上。这工作正常。

    现在我希望能够为该操作添加自定义选项。我的第一个尝试是在接受放置操作后构造并显示 JPopupMenu。这似乎不起作用,因为弹出菜单没有显示,就像 show 方法被忽略了一样。

    有没有什么办法可以解决此问题,或者我必须使用更重的东西,例如 JOptionPane?

    这是我的示例代码:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.dnd.DropTarget;
    import java.awt.dnd.DropTargetAdapter;
    import java.awt.dnd.DropTargetDropEvent;
    
    import static java.awt.dnd.DnDConstants.ACTION_COPY;
    
    public class DNDTest {
    
        DNDTest() {
            JFrame f = new JFrame("Test dnd");
            Container c = f.getContentPane();
            final JPanel jp = new JPanel(new BorderLayout());
            jp.setBackground(Color.RED);
            jp.setToolTipText("Drop a string here");
            jp.setPreferredSize(new Dimension(200,200));
            c.add(jp);
    
            DropTarget dt = new DropTarget(jp, ACTION_COPY, new DropTargetAdapter() {
                @Override
                public void drop(DropTargetDropEvent dtde) {
                    if (dtde.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                        try {
                            dtde.acceptDrop(ACTION_COPY);
                            String trns = (String) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor);
                            System.err.println("Dropped string "+trns);
                            Point loc = dtde.getLocation();
    
                            // Show a popup after the drop operation
                            JPopupMenu jpm2 = new JPopupMenu("Popup menu");
                            JMenuItem jmi2 = new JMenuItem("Popup option 1");
                            jpm2.add(jmi2);
                            System.err.println("About to show popup after drop at "+loc.getX()+","+loc.getY());
                            jpm2.show(jp, (int)loc.getX(), (int)loc.getY());
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                        return;
                    }
                    dtde.rejectDrop();
                }
            }, true);
    
            f.pack();
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(DNDTest::new);
        }
    }
    
  • 我想知道为什么我的代码返回'nullnullnull'而不是预期的答案,以及为什么使用方法时它能正常工作。考虑以下代码:open class Base(...

    我想知道为什么我的代码返回的 "nullnullnull" 不是预期的答案,以及为什么使用方法时它能正常工作。

    考虑以下代码:

    open class Base(
        open val a: String,
        open val b: String,
        open val c: String,
    ) {
        val concatenation = a + b + c
    }
    
    class Derived(
        override val a: String,
        override val b: String,
        override val c: String
    ) : Base(a = a, b = b, c = c)
    
    fun main() {
        val derived = Derived(a = "foo", b = "bar", c = "baz")
        println(derived.concatenation)
    }
    

    此示例打印出 "nullnullnull" ,而不是 "foobarbaz" .

    但是如果你在超类中替换 val concatenation = a + b + c 它, fun concatenation() = a + b + c 它似乎可以很好地与该方法调用一起工作。

    此外, Accessing non-final property <property> in constructor 使用时 val concatenation = a + b + c ,但我不确定这到底意味着什么。

    初始化 Base 类和 Derived 类属性的顺序是否有什么问题?我认为可能是我 concatenation 从 Base 类中使用,但是对于继承,我也调用 Base 类构造函数,并且必须初始化具有相同字符串的相同属性。

  • M.M 2月前 0 只看Ta
    引用 6

    由于该 batch_write 方法在所有实例之间没有共同定义 Sinker 在 上 Any 模糊地(或通用地)定义它 Sinker 不会增加关于如何使用它的任何清晰度。人们仍然需要查看子类来确定他们的参数是否可接受。因此,我认为在 上定义它不会 Sinker 增加任何东西。

    相反,等到方法(包括其参数)的子类完全定义之后再创建抽象方法,即使这涉及添加另一个抽象中间体,例如。

    class SinkerStringBatchWritable(Sinker):
        @abstractmethod
        def batch_write(self, data: list[str]) -> None:
            pass
    
  • 谢谢!我喜欢这一点,即 List[dict | str] 可能会迫使我在实现新的具体类时更改抽象类。我更有信心删除第三个选项。

  • BUFU 2月前 0 只看Ta
    引用 8

    我应该说“参数类型提示的意义在于指出执行该操作时需要哪种类型的参数”。关于“此处的抽象方法显然应在子类中指定”——所有抽象方法都应在子类中实现:这就是抽象方法。

  • 好的,但问题不在于返回类型,这里的抽象方法显然是在子类中指定的。也许我应该把它写成“您无法实例化抽象类”。这样可能会更好,但在这个例子中,抽象方法仍然没有做任何事情。如果其中有一些实际的逻辑,那将会产生巨大的不同。但是,我也会建议对参数使用更具体的类型提示。

  • \'无法直接从 Sinker 使用/实现 batch_write 方法\'—您可以在 Sinker 对象上调用它,而不必知道正在使用哪个具体子类。这就是抽象方法的全部意义所在。返回类型提示的全部意义在于,当您这样做时,您知道会得到什么。

  • tiao 2月前 0 只看Ta
    引用 11

    我想说的 Any 是这里推荐的解决方案。由于它是一个 abstractmethod ,人们不能直接使用/实现 batch_write 来自的方法 Sinker pass 并且它有 batch_write 语句,所以在我看来你不需要非常具体。我会在继承自的类的方法中实现更具体的类型提示。此外 Sinker ,如果你使用 List[dict | str] 具有不同类型 batch_write 方法 data 的新子类时,你都必须更新此类型提示 List[int] 例如)。在抽象类中尽可能通用,以避免更改签名。但是,如果你确定它始终是 list ,你可以选择 List[Any ]`。(请参阅 Lrx 问题下的命令,我喜欢那个)。

  • 引用 12

    您可以创建 Sinker 一个 generic 类,以便传递给的列表中的项目类型 batch_write 可以参数化:

    from abc import ABC, abstractmethod
    
    class Sinker[T](ABC):
        @abstractmethod
        def batch_write(self, data: list[T]) -> None:
            ...
    
    class StrSinker(Sinker[str]):
        def batch_write(self, data: list[str]) -> None:
            pass
    
    class DictSinker(Sinker[dict]):
        def batch_write(self, data: list[dict]) -> None:
            pass
    

    黄铁矿 演示

    这样,类型检查器就能帮你发现错误的类型提示。例如:

    class StrSinker(Sinker[str]):
        def batch_write(self, data: list[int]) -> None:
            pass
    

    Pyright 将提出以下投诉:

    Method "batch_write" overrides class "Sinker" in an incompatible manner
      Parameter 2 type mismatch: base parameter is type "list[str]", override parameter is type "list[int]"
        "list[str]" is incompatible with "list[int]"
          Type parameter "_T@list" is invariant, but "str" is not the same as "int"
          Consider switching from "list" to "Sequence" which is covariant  (reportIncompatibleMethodOverride)
    

    黄铁矿 演示

  • 对于这种情况,你的选择取决于你想要抽象基类的抽象级别。如果你确定你的参数将是一个列表,那么

  • 这就是我在评论中提出的建议:

    classdef MySolver
        properties 
            parameter
            Bform double {mustBeMember(Bform,[1,2])} = 1
            B
        end
    
        methods
            function B = get.B(obj)
                % Calculates B according to the specific form
                switch obj.Bform
                    case 1
                        B = obj.parameter(1)*obj.parameter(2);
                    case 2
                        B = 3*obj.parameter(1)*obj.parameter(2);
                end
            end
        end
    end
    

    当然,您可以在属性的文档字符串中包含 B 的不同形式的描述、对“参数”的检查等。

    以下是一个使用示例:

    obj = MySolver();
    obj.parameter = randn(1,2);
    obj.Bform = 2;
    disp(obj.B)
    
  • 请不要尝试使用 MATLAB 学习 OOP。MATLAB 的类与任何 OOP 语言的工作方式都大不相同。是的,你可以在 MATLAB 中使用类,它们非常有用。但你的技能无法很好地转化为其他语言。此外,通常你并不需要使用类(在我看来,OOP 被夸大了)。如果你的脚本中有重复的代码,请创建函数。这就是函数的用途。

  • 引用 16

    @Zep 这个想法不错,我想试试。抱歉,您能否进一步解释一下检查预期形式是什么意思?您的意思是我可以定义一个属性“form”,指定形式“a”、“b”、“c”等,以及一个以“form”为参数的 get 方法,该方法以“if/else”或“switch case”为基础运行?

  • 为什么不添加另一个属性来指定 B 的形式?然后在 B getter 中,您可以首先检查 B 的预期形式,然后计算它。

  • 既然您已经覆盖了 a、b、c;您的基类为什么应该知道被覆盖字段的值?

    我假设您想参数化 a、b、c,而不是覆盖它们。

    open class Base(
        val a: String,
        val b: String,
        val c: String,
    ) {
        val concatenation = a + b + c
    }
    
    class Derived(
        a: String,
        b: String,
        c: String
    ) : Base(a = a, b = b, c = c)
    
    fun main() {
        val derived = Derived(a = "foo", b = "bar", c = "baz")
        println(derived.concatenation)
    }
    
  • 有趣。谢谢你的回答,我没有想到在初始化之前属性会为空,我以为 Kotlin 可以完美解决 Java 固有可空性的各个方面。

  • Brom 2月前 0 只看Ta
    引用 20

    我认为,他们应该将其设计 Accessing non-final property <property> in constructor 为编译错误,而不仅仅是警告,因为它会产生一些奇怪的行为,而这些行为甚至不一定在文档中定义。例如, !! 通过这样做,您可以轻松创建 NullPointerException,而无需使用或任何 Java 互操作代码。

    “非最终”与“开放”含义相同。您正在从构造函数调用开放属性或函数,这可能会引发大问题,因此绝不应该这样做。

    分配属性初始值的代码被视为构造函数的一部分,因此您的代码 = a + b + c 是构造函数的一部分,并且是触发警告的原因。

    以下是获取空值的过程。Derived 类构造函数将这三个值传递给超类构造函数。超类将这些值分配给超类的 a , b 、 和 c 属性的支持字段。然后 concatenation 调用 a , b 、 和 c 属性来获取它们的值,但由于我们实际上是 Derived 的一个实例,这些属性已被覆盖,并且指向与作为超类的一部分初始化的支持字段不同的支持字段。

    此外,由于我们仍在执行超类构造函数,派生类的支持字段尚未初始化,因此它们仍然持有空值。

返回
作者最近主题: