简体   繁体   English

为什么需要第二个文件写入golang中的pos打印机才能输出?

[英]Why do I need a second file write to the pos printer in golang to be able to output?

I have an Epson TM-T88III pos printer on a Linux machine hooked up on a USB port. 我在连接USB端口的Linux机器上有一台Epson TM-T88III pos打印机。 All is working relative good, It gets recognised, I can open the device, I can echo "Hello World" on the commandline to the printer and it prints without problem. 一切都相对良好,它得到认可,我可以打开设备,我可以在命令行上向打印机回显“ Hello World”,并且可以正常打印。

However in golang when I open the device with os.OpenFile and write some test sequences either as byteslice or string it only prints that sequence after I do another write. 但是在golang中,当我使用os.OpenFile打开设备并以字节片或字符串形式写入一些测试序列时,它仅在我执行另一次写入操作后才打印该序列。

Can somebody explain if I miss something in what I need to do? 有人可以解释我是否错过了我需要做的事情吗? I am a relative beginner in golang but I do program in other languages. 我是golang的相对入门者,但是我使用其他语言编程。


I open with: 我打开:

f, err := os.OpenFile("/dev/usb/lppos",os.O_RDWR,0755)
if err != nil {
    panic(err)
}
defer f.Close()

Then I define some esc commands and catch them in a byteslice (i use the escpos package of panjjo for that): 然后,我定义一些esc命令并将其捕获到字节片中(为此我使用panjjo的escpos包):

p := escposc.New()

p.Init()
p.SetSmooth(1)
p.SetFontSize(2, 3)
p.SetFont("A")
p.Write("test ")
p.SetFont("B")
p.Write("test2 ")
p.Formfeed()

p.SetFont("B")
p.SetFontSize(1, 1)

p.SetEmphasize(1)
p.Write("halle")
p.Formfeed()

p.SetUnderline(1)
p.SetFontSize(4, 4)
p.Write("halle")

p.SetReverse(1)
p.SetFontSize(2, 4)
p.Write("halle")
p.Formfeed()

p.FormfeedN(5)

p.Cut()

_,b:=p.Readbyte()

p.End()

Then I write the catched slice b to the device: 然后,将捕获的片b写入设备:

n,err:=f.Write(b)
if err != nil {
    panic(err)
}

At this point nothing happens, and it took me a while to find out that if I do a last: 在这一点上什么都没有发生,我花了一段时间才知道我是否做了最后一遍:

f.WriteString(" ")

Then all sequences get printed as should, with all the styling, linefeeds and cut. 然后将按顺序打印所有序列,包括所有样式,换行和剪切。 And all is well, but not without that last WriteString. 一切都很好,但并非没有最后一个WriteString。 Oh yes, It does need the space or other character, writing an empty string does not work. 哦,是的,它确实需要空格或其他字符,无法写空字符串。

I also tried to write a string of commands instead of a byteslice, but I need the same 2nd WriteString or it wont output on the paper roll. 我还尝试编写命令字符串而不是字节片,但是我需要相同的第二个WriteString,否则它不会在纸卷上输出。

I am going to answer my own question. 我要回答我自己的问题。 Last few days I spent writing my own implemententation of escpos in golang. 最近几天,我用golang编写了自己的escpos实现。 I learned a few things along the way. 一路上我学到了一些东西。 Main thing is that the thermal printer will decide itself what to buffer and how to do that. 最主要的是,热敏打印机将自行决定要缓冲什么以及如何进行缓冲。 It means you need to open the device and without buffering you write commands to it. 这意味着您需要打开设备并且在不缓冲的情况下向其写入命令。

In the golang escpos packages around on github (which, in my opinion, are incomplete) io.Writer is used to stream the commands. 在github上的golang escpos包中(我认为这是不完整的),io.Writer用于流命令。 Instead of that you need to use *os.File and use its Write method to stream the command directly to the printer. 取而代之的是,您需要使用* os.File并使用其Write方法将命令直接流式传输到打印机。 This works immediately and flawless on my Epson TM-T88III thermal printer. 这在我的Epson TM-T88III热敏打印机上可以立即正常运行。

Basicly I changed the following core of the escpos code: 基本上,我更改了escpos代码的以下核心:

type Escpos struct {
    enc *encoding.Encoder
    w   io.Writer
}

func NewEscpos(w io.Writer) *Escpos {
    return &Escpos{
        enc: charmap.CodePage437.NewEncoder(),
        w:   w,
    }
}

func (e *Escpos) write(b []byte) error {
    _, err := e.w.Write(b)
    return err
}

Into this new code where I can open a device and give the pointer to the file handle as parameter to the Escpos type reference, when the command sequence is done I can close the device. 在此新代码中,我可以打开设备并将文件句柄的指针作为Escpos类型引用的参数,完成命令序列后,我可以关闭设备。 Meanwhile it outputs the receipt and the printing I want on it. 同时,它输出收据和我想要的打印件。

type Escpos struct {
    enc *encoding.Encoder
    f   *os.File
}


func NewEscpos(f *os.File) *Escpos {
    return &Escpos{
        enc: charmap.CodePage437.NewEncoder(),
        f:   f,
    }
}

func (e *Escpos) write(b []byte) error {
    _, err := e.f.Write(b)
    return err
}

Your problem is that you call 你的问题是你打电话

p.End()

after

p.Readbyte()

While you should do it before. 虽然您应该先做。 I beleve your printer treats " "(space) as an invalid command and automatically finishes a preceding sequence of valid commands. 我相信您的打印机将“”(空格)视为无效命令,并自动完成前面的有效命令序列。

Looks like you have captured the byte slice before you were finished writing to it. 看起来您已经在完成写入之前捕获了字节片。

p.Cut()

_,b:=p.Readbyte()

p.End()

The byte from the call to p.End() never gets added to your output data, so the printer waits forever for it... 调用p.End()的字节永远不会添加到您的输出数据中,因此打印机将永远等待它。

As shown in the example , this should be instead: 如在所示的示例中 ,这应该是代替:

p.Cut()

p.End()

_,b:=p.Readbyte()

You have to do f.Sync() . 您必须执行f.Sync() From the docs: Sync commits the current contents of the file to stable storage. 从文档: Sync commits the current contents of the file to stable storage. ( https://golang.org/src/os/file_posix.go?s=3352:3379#L11 ). https://golang.org/src/os/file_posix.go?s=3352:3379#L11 )。 And after you end using the device, you may have to do f.Close() . 在结束使用设备后,可能必须执行f.Close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Golang热敏打印机设备上写 - Write on thermal printer device in golang 我有一个日志文件,我需要在其中获取指定的输出,并且需要逻辑来编写shell脚本 - I have a log file where I need to get the output as specified and I need the logic to write in shell script 如何将nginx -t(配置测试)的输出写入文件? - How do I write the output of nginx -t (config test) to a file? 为什么我需要重新打开文件才能获取其最新数据? - Why do I need to reopen a file to get its newest data? 如果文件是可执行的,为什么我需要安装一些依赖项? - If the file is executable, why do I need to install some dependencies? linux-如何将所有编译器的输出捕获到文件中以及需要显示输出 - linux - How do I capture all of my compiler's output to a file as well as need to display output 为什么我需要在syscall读取之前调用syscall write以使其接受用户输入? - Why do i need to call syscall write before syscall read to make it accept user input? Bash-需要根据bash中命令的输出将数据写入文件 - Bash - need to write data to a file based on output of a command in bash 如何将此输出命令写入文件 - How to I write this output command to a file 如何保留命令 output 中的换行符并使用 ansible 复制模块将其写入文件 - How do I preserve line breaks from a command output and write it to a file using ansible copy module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM