fmt.printf 为什么能输出整个缓冲数据?

junliuxian · 2017-11-21 12:57:23 · 1483 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-11-21 12:57:23 的主题,其中的信息可能已经有所发展或是发生改变。

我尝试使用 net 包的客户端接收服务端的数据。但是我发现 fmt.Printf 和 log.Printf 输出的完全不同。缓冲区我是故意设置为 2 的。我的假设传输的数据为: hello world 求大神指点!感激~

buff := make([]byte, 2)

for {
    count, err := this.conn.Read(buff)

    if err != nil {
        return
    }

    fmt.Printf("%s", buff[:count]) // hello world

    log.Printf("%s", buff[:count]) // he ll o  wo rl d
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1483 次点击  
加入收藏 微博
10 回复  |  直到 2017-11-23 02:00:00
polaris
polaris · #1 · 7年之前

fmt.Printf 是输出到 os.Stdout,它是行缓冲的,而 log.Printf 是输出到 os.Stderr,这是无缓冲的。所以有这个差异!

wi-cuckoo
wi-cuckoo · #2 · 7年之前

我感觉不像是 fmt 与 log 的问题,如果是设置了缓冲区,每次打印不会超过这个值。另外怎么还有 this 这种操作

polaris
polaris · #3 · 7年之前
wi-cuckoowi-cuckoo #2 回复

我感觉不像是 fmt 与 log 的问题,如果是设置了缓冲区,每次打印不会超过这个值。另外怎么还有 this 这种操作

你可以 log.SetOutput(os.Stdout) 试试,看看结果是不是和 fmt.Printf 一样了!

PS: this 应该是它代码内部的,不用关心。

wi-cuckoo
wi-cuckoo · #4 · 7年之前
polarispolaris #3 回复

#2楼 @wi-cuckoo 你可以 `log.SetOutput(os.Stdout)` 试试,看看结果是不是和 `fmt.Printf` 一样了! PS: `this` 应该是它代码内部的,不用关心。

原本的 log 默认 out 是 os.Stderr,这个设置我觉得意义不大。你可能是怀疑 os.Stderr 与 os.Stdout 实现的 io.Writer 接口有差异。我建立了一个 tcp 连接的例子来测试,并不知道楼主这个输出怎么来,并且log 输入默认要加换行符的

marlonche
marlonche · #5 · 7年之前

log.Printf()保证最后有换行符,A newline is appended if the last character of s is not already a newline

fmt.Printf()传什么就输出什么

junliuxian
junliuxian · #6 · 7年之前
polarispolaris #1 回复

`fmt.Printf` 是输出到 `os.Stdout`,它是行缓冲的,而 `log.Printf` 是输出到 `os.Stderr`,这是无缓冲的。所以有这个差异!

那这样的话,我实际 buff 缓存切片里面 一值存储的只有 2 个 字节的数据对吧

marlonche
marlonche · #7 · 7年之前
package main

import (
    //"fmt"
    "log"
    "strings"
    "os"
)

func main() {
    log.SetOutput(os.Stdout)
    buff := make([]byte, 2)
    r := strings.NewReader("hello world")
    for {
        count, err := r.Read(buff)

        if err != nil {
            return
        }

        //fmt.Printf("%s", buff[:count]) // hello world

        log.Printf("%s", buff[:count]) // he ll o  wo rl d
    }
}

2009/11/10 23:00:00 he
2009/11/10 23:00:00 ll
2009/11/10 23:00:00 o 
2009/11/10 23:00:00 wo
2009/11/10 23:00:00 rl
2009/11/10 23:00:00 d
zweite
zweite · #8 · 7年之前
polarispolaris #3 回复

#2楼 @wi-cuckoo 你可以 `log.SetOutput(os.Stdout)` 试试,看看结果是不是和 `fmt.Printf` 一样了! PS: `this` 应该是它代码内部的,不用关心。

fmt.Sprintf 后面自动加了换行

可以看这个示例 https://play.golang.org/p/A0l45p9p8O

windy_
windy_ · #9 · 7年之前
func (l *Logger) Output(calldepth int, s string) error {
    ....
    if len(s) == 0 || s[len(s)-1] != '\n' {
        l.buf = append(l.buf, '\n')
    }
    ....
}

无非就是log.Printf自动加了换行,fmt.Printf没加,你在fmt.Printf后加一个fmt.println,它们就一样了

junliuxian
junliuxian · #10 · 7年之前
windy_windy_ #9 回复

``` func (l *Logger) Output(calldepth int, s string) error { .... if len(s) == 0 || s[len(s)-1] != '\n' { l.buf = append(l.buf, '\n') } .... } ``` 无非就是log.Printf自动加了换行,fmt.Printf没加,你在fmt.Printf后加一个fmt.println,它们就一样了

你是最佳答案

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传