Go语言io.Reader,我犯的一个超愚蠢的错误,妹滴!

刘地 发布于 2013/08/11 17:37
阅读 3K+
收藏 0
Go

我之前从网上查查,写了个go版本的代理程序,但是运行的很奇怪,时好时坏的,而且优酷等等视频网站也不行。

我是修改来修改去,重新构建request啊,cookie保存位置啊,各种挠头,就是不行……

直到今天,突然有点灵光,把io.Reader(go接口,包含一个Read方法,传入一个切片,返回读取字节数),用Read读取数据后,不再直接把切片拿去Write,而是取切片的切片去Write,如下:

n,_:=resp1.Body.Read(data)
// resp2.Body.Write(data)
resp2.Body.Write(data[:n])
结果居然能用了,而且也能正常代理视频了(A站B站要TLS,没办法)

结果Go语言的io.Reader接口的Read方法,不是每个满足的类型该方法都能保证每次读取都填满切片长度的;更坑爹的是,它写入切片的时候,也不改变切片的长度……

回头看看,go语言并没有提供slice什么方法,可以直接修改切片的长度,它只是保证了不超出cap时不重新划分底层地址而已,所以Read方法,既然传入的不是指针,那么原切片的长度和容量实际上改变不了的……

尼玛我挠头那么久到底是在搞啥……

加载中
0
宏哥
宏哥

你被Google 这个 Gay 给Rape了

有python 你不用

偏要舔 Google的pussy

怪谁?

纠结名字_我艹你妹
纠结名字_我艹你妹
python 不是 Google 的jiba么? 只不过现在google把jiba割了....
0
刘地
刘地

引用来自“宏哥”的答案

你被Google 这个 Gay 给Rape了

有python 你不用

偏要舔 Google的pussy

怪谁?

因为go的语法我喜欢,更重要的是,我不了解http编程,python封装的太好了,太方便以致于我接触不到底层(python的库文档好大,吓坏我了),go的标准库很小(相对python),我可以边学go,顺便就把http给学了
0
Yu_Yang
Yu_Yang

引用来自“刘地”的答案

引用来自“宏哥”的答案

你被Google 这个 Gay 给Rape了

有python 你不用

偏要舔 Google的pussy

怪谁?

因为go的语法我喜欢,更重要的是,我不了解http编程,python封装的太好了,太方便以致于我接触不到底层(python的库文档好大,吓坏我了),go的标准库很小(相对python),我可以边学go,顺便就把http给学了
你这理由挺搞笑的,python的文档大,是因为库多,可是很多库不是必须的,你用到哪,你就看到哪,你想一口气全部看完,既找虐,也没意义,至于你说的python封装的太好,那我就更要吐槽了,python是给你多样的选择,你可以用高层的库,也可以深入底层,你可以直接用python的socket呀,这难道还不够底层,你用C进行网络编程,还不就是鼓捣socket,python为你想的如此周到,可是你却抱怨python太周到了,这真是和曾老师是同路中人,:)
0
刘地
刘地

引用来自“Yu_Yang”的答案

引用来自“刘地”的答案

引用来自“宏哥”的答案

你被Google 这个 Gay 给Rape了

有python 你不用

偏要舔 Google的pussy

怪谁?

因为go的语法我喜欢,更重要的是,我不了解http编程,python封装的太好了,太方便以致于我接触不到底层(python的库文档好大,吓坏我了),go的标准库很小(相对python),我可以边学go,顺便就把http给学了
你这理由挺搞笑的,python的文档大,是因为库多,可是很多库不是必须的,你用到哪,你就看到哪,你想一口气全部看完,既找虐,也没意义,至于你说的python封装的太好,那我就更要吐槽了,python是给你多样的选择,你可以用高层的库,也可以深入底层,你可以直接用python的socket呀,这难道还不够底层,你用C进行网络编程,还不就是鼓捣socket,python为你想的如此周到,可是你却抱怨python太周到了,这真是和曾老师是同路中人,:)

我也没说我不用python啊,事实上我大多数时候都是用的python,我的意思是,python库很多,封装也很多,不知道学哪个好;库文档很完备是不假,可英文的太痛苦了(所以我宁愿短一点,能让我下决心去看)

python和ms都太”庞大“了,让我有种无所适从的感觉,拿来应用我是很满意,可是要我用他们学习原理,老实说,我害怕,也不知道怎么下手……

0
豆豆爸
豆豆爸
这是黑Golang的帖子?用法问题,slice作为语言原语,不提供特定简便操作是有原因的,如果你想深究的话。
0
刘地
刘地

引用来自“lixin3811”的答案

这是黑Golang的帖子?用法问题,slice作为语言原语,不提供特定简便操作是有原因的,如果你想深究的话。
黑个毛,是我被黑,妹滴上来就爆粗话,这人太木有素质咧
0
豆豆爸
豆豆爸
同情且赞同博主,哪条路上还没有狂吠的狗呢,忽略它就是。
0
x
xx-xx-xx

引用来自“宏哥”的答案

你被Google 这个 Gay 给Rape了

有python 你不用

偏要舔 Google的pussy

怪谁?

Google跟你是有多大的仇恨啊?Python这种解释性的动态脚本语言,跟编译性的语言还是有很多差别的,有些地方适合,有些地方不适合!

0
waynehu
waynehu

slice是一个指针,底层是一个数组,它有容量大小

你每次读的时候,会把slice填满,最后一次读的时候才是填不满的,但已填的数据不会擦除,还有,至少需要循环(我相信你那么做了)

比如网页有50个字节,你slice定义容量为20,第一次read,拿到1到20,第二次read,拿到21到40,重点来了,第三次read的时候,只拿到41到50,所以slice里前10个空间被改写,而slice后10个空间还是31到40的内容

所以你write的时候前几次循环都对,最后一次会把一些垃圾也一起write,导致页面错误

返回值n会告诉你成功写入了多少字到slice,应该是20,20,10,而被你忽略的err会告诉你有什么错误和是否到文件结尾了

有人觉得go麻烦,不如别的语言方便,只是因为你用了更底层的工具,我完全可以写一个方法来封装它,一句命令搞定所有事,初学者只要用而不用关心底层实现,这是windows哲学

别的语言因为发展早,已经封装了很多功能进去,所以觉得特别好用,暂不评论

0
刘地
刘地

引用来自“waynehu”的答案

slice是一个指针,底层是一个数组,它有容量大小

你每次读的时候,会把slice填满,最后一次读的时候才是填不满的,但已填的数据不会擦除,还有,至少需要循环(我相信你那么做了)

比如网页有50个字节,你slice定义容量为20,第一次read,拿到1到20,第二次read,拿到21到40,重点来了,第三次read的时候,只拿到41到50,所以slice里前10个空间被改写,而slice后10个空间还是31到40的内容

所以你write的时候前几次循环都对,最后一次会把一些垃圾也一起write,导致页面错误

返回值n会告诉你成功写入了多少字到slice,应该是20,20,10,而被你忽略的err会告诉你有什么错误和是否到文件结尾了

有人觉得go麻烦,不如别的语言方便,只是因为你用了更底层的工具,我完全可以写一个方法来封装它,一句命令搞定所有事,初学者只要用而不用关心底层实现,这是windows哲学

别的语言因为发展早,已经封装了很多功能进去,所以觉得特别好用,暂不评论

我最后一次是用了[:n]的,只是前面的没有用,实际上go没有明确规定必须填满容量,我记得有的是不满就会返回错误,但是这个还真不会返回错误。

因为和本地文件不同,这个还要看网络情况的。

返回顶部
顶部