Golang学习笔记_19------Stringer
Golang学习笔记_20------error
Golang学习笔记_21------Reader
文章目录
-
- [`io.Reader` 示例](#
io.Reader
示例) - 源码
- [`io.Reader` 示例](#
io.Reader
示例
从字符串中读取
go
func ReadFromStrDemo() {
str := "hello world"
reader := bufio.NewReader(strings.NewReader(str))
buf := make([]byte, 2)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
测试方法
go
func TestReadFromStrDemo(t *testing.T) {
ReadFromStrDemo()
}
输出结果
=== RUN TestReadFromStrDemo
he
ll
o
wo
rl
d
--- PASS: TestReadFromStrDemo (0.00s)
PASS
从文件中读取
go
func ReadFromFileDemo() {
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("Error opening file", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
测试方法
go
func TestReadFromFileDemo(t *testing.T) {
ReadFromFileDemo()
}
输出结果
=== RUN TestReadFromFileDemo
h
e
l
l
o
i
o
.
R
e
a
d
e
r
--- PASS: TestReadFromFileDemo (0.00s)
PASS
从HTTP响应中读取
go
func ReadFromHTTPResponseDemo() {
resp, err := http.Get("https://www.bing.com")
if err != nil {
fmt.Println("Error", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Println("StatusCode", resp.StatusCode)
return
}
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error", err)
return
}
fmt.Println(string(body))
}
测试文件
go
func TestReadFromHTTPResponseDemo(t *testing.T) {
ReadFromHTTPResponseDemo()
}
输出结果
=== RUN TestReadFromHTTPResponseDemo
<!doctype html><html lang="zh" dir="ltr"><head><meta name="theme-color" content="#4F4F4F" /><meta name="description" content="使用 Microsoft 必应进行搜索,并利用 AI 的强大功能查找信息、浏览网页、图像、视频、地图等。为永远充满好奇心的人提供的智能搜索引擎。" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta property="fb:app_id" content="3732605936979161" /><meta property="og:type" content="website" /><meta property="og:title" content="变换的地平线" /><meta property="og:image" content="https://www.bing.com/th?id=OHR.NamibiaDunes_ZH-CN5102483490_tmb.jpg&rf=" /><meta property="og:image:width" content="1366" /><meta property="og:image:height" content="768" /><meta property="og:url" content="https://www.bing.com/?form=HPFBBK&ssd=20250108_1600&mkt=zh-CN" /><meta property="og:site_name" content="搜索 - Microsoft 必应" /><meta property="og:description" content="想象在日出时分,连绵起伏的沙丘泛着橙色光芒,延伸至视野尽头,欢迎来到横跨纳米比亚数千英里的纳米布沙漠" /><title>搜索 - Microsoft 必应</title><link href="https://cn.bing.com/" rel="canonical" /><link rel="preconnect" href="https://r.bing.com" /><link rel="preconnect" href="https://r.bing.com" crossorigin/><link rel="dns-prefetch" href="https://r.bing.com" /><link rel="dns-prefetch" href="https://r.bing.com" crossorigin/><link rel="stylesheet" href="/rp/RCJCS6O5TykkUhXX1pwc6RsdyuI.gz.css" type="text/css"/><script type="text/javascript" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=">//<![CDATA[
var __assign=this&&this.__assign||function(){return __assign=Object.assign||function(n){for(var t,r,i=1,u=arguments.length;i<u;i++){t=arguments[i];for(r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r])}return n},__assign.apply(this,arguments)},logE=function(n,t,i){t===void 0&&(t=null);i===void 0&&(i="ClientInst");var r=[__assign({T:"CI.".concat(i),FID:"CI",Name:n},t&&{Text:t})],u="".concat(_G.lsUrl,"&Type=Event.ClientInst&DATA=").concat(encodeURIComponent(JSON.stringify(r)));(new Image).src=u},CSPIF;window.CSPEL=[];CSPIF=function(n){var t="clarity",i="CSPViolation",r,u;return(window[t]&&(window[t]("set",i,n.sample),window[t]("event",i)),r=["chrome-extension"],u=["javascript:void(0)","javascript: void(0)"],r.some(function(t){return n.sourceFile.includes(t)})||u.some(function(t){return n.sample.includes(t)}))?!0:window.CSPEL.includes(n.sample)?!0:(window.CSPEL.push(n.sample),!1)};try{var ignErr=["ResizeObserver loop","Script error"],ignCSPErr=["unsafe-eval"],maxErr=3,ignoreCurrentError=function(n,t){return(ignErr.some(function(t){return n.includes(t)})||ignCSPErr.some(function(t){return n.includes(t)}))?ignCSPErr.some(function(t){return n.includes(t)})&&t.filename&&!t.filename.includes("chrome-extension://")?!1:(t!=null&&(typeof sj_sp!="undefined"&&sj_sp(t),typeof sj_pd!="undefined"&&sj_pd(t)),!0):!1},regexEsc=function(n){return n.replace(/([.?*+^$&[\]\\(){}|<>-])/g,"\\$1")},ignoreCSPLog=function(n){return["javascript:void(0)","javascript: void(0)","javascript:void()"].some(function(t){return n.sample.includes(t)})};window.jsErrorHandler=function(n){var f,p,h,rt,ut,u,e,ft,o,a,v,s;try{if(f='"noMessage"',p=(n.error||n).message||f,ignoreCurrentError(p,n))return;if(h=(window.ERC?window.ERC:0)+1,window.ERC=h,h>maxErr){logE("max errors reached");return}var c=n.error||n,w=n.filename,b=n.lineno,k=n.colno,d=n.extra,l=c.severity||"Error",g=c.message||f,i=c.stack,t='"'+escape(g.replace(/"/g,""))+'"',nt=new RegExp(regexEsc(location.href),"g"),tt=window.lirab,it=window.liraa,r=tt?" hint == ["+tt:"";if(r=r+(it?", "+it+")":r?"]":""),i){for(rt=/\(([^\)]+):[0-9]+:[0-9]+\)/g,u={};(ut=rt.exec(i))!==null;)e=ut[1],u[e]?u[e]++:u[e]=1;o=0;for(a in u)u[a]>1&&(v=regexEsc(a),ft=new RegExp(v,"g"),i=i.replace(ft,o),i+="#"+o+"="+v,o++);i=i.replace(nt,"self").replace(/"/g,"");t+=',"Stack":"'+(escape(i)+'"')}if(w?t+=',"Meta":"'+escape(w.replace(nt,"self"))+r+'"':r&&(t+=',"Meta":"'+r+'"'),b&&(t+=',"Line":"'+b+'"'),k&&(t+=',"Char":"'+k+'"'),d&&(t+=',"ExtraInfo":"'+d+'"'),g===f)if(l="Warning",t+=',"ObjectToString":"'+n.toString()+'"',JSON&&JSON.stringify)t+=',"JSON":"'+escape(JSON.stringify(n))+'"';else for(s in n)n.hasOwnProperty(s)&&(t+=',"'+s+'":"'+n[s]+'"');var et=(new Date).getTime(),ot='"T":"CI.'+l+'","FID":"CI","Name":"JS'+l+'","Text":'+t+"",st="<E><T>Event.ClientInst<\/T><IG>"+_G.IG+"<\/IG><TS>"+et+"<\/TS><D><![CDATA[[{"+ot+"}]]\]><\/D><\/E>",ht="<ClientInstRequest><Events>"+st+"<\/Events><STS>"+et+"<\/STS><\/ClientInstRequest>",y=new XMLHttpRequest;y.open("POST","/fd/ls/lsp.aspx?",!0);y.setRequestHeader("Content-Type","text/xml");y.send(ht);typeof sj_evt!="undefined"&&sj_evt.fire("ErrorInstrumentation",t)}catch(ct){logE("MetaJSError","Failed to execute error handler. "+ct.message)}};window.CSPEH=function(n){CSPIF(n)||logE("CSPViolation",n.sample,"Error")};window.addEventListener&&(window.addEventListener("error",window.jsErrorHandler,!1),window.addEventListener("unhandledrejection",window.jsErrorHandler,!1),window.addEventListener("securitypolicyviolation",window.CSPEH))}catch(e){logE("MetaJSError","Failed to bind error handler "+e.message)};
//]]></script></head><body><div class="hp_body"><div class="hpl hp_cont"><div class="sbox"><form action="/search" id="sb_form" class="sb_form"><input id="sb_form_q" class="sb_form_q" name="q"
placeholder="" type="search" maxlength="1000" autocapitalize="off" autocomplete="off" spellcheck="false"
title="输入搜索词" autofocus="autofocus" ) /><input id="sb_form_go" type="submit"
title="搜索" name="search" value=""
tabIndex="0" /><label for="sb_form_go" class="search icon tooltip" aria-label="搜索网页"><svg viewBox="0 0 25 25" enable-background="new 0 0 25 25"><path stroke="#007DAA" stroke-width="2.5" stroke-linecap="round" stroke-miterlimit="10" fill="none" d="M23.75 23.75l-9-9" /><circle stroke="#007DAA" stroke-width="2.5" stroke-linecap="round" stroke-miterlimit="10" cx="9" cy="9" r="7.75" fill="none" /><path fill="none" d="M25 25h-25v-25h25z" /></svg></label><input type="hidden" value="QBLH" name="form" /></form><a id="hpinsthk" aria-hidden="true" tabindex="-1" class="linkBtn" href="javascript:void(0)" h="ID=SERP,5067.1"><span></span></a></div></div><div class="hpl bottom_row"><div class="scroll_cont" id="scroll_cont"><footer class="footer no_mod " id="footer"><div class="footerbody "><span class="msft">© 2025 Microsoft</span><ul class="items"><li class="item"><a id="ICPLicense" href="https://dxzhgl.miit.gov.cn/dxxzsp/xkz/xkzgl/resource/qiyereport.jsp?num=caf04fa4-bd8a-4d9e-80b6-2aa1b86c1509&type=yreport" h="ID=SERP,5068.1">增值电信业务经营许可证:合字B2-20090007</a></li><li class="item"><a id="ICPFiling" href="https://beian.miit.gov.cn" h="ID=SERP,5069.1">京ICP备10036305号-7</a></li><li class="item"><a id="MMAIS" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802022657" h="ID=SERP,5070.1">京公网安备11010802022657号</a></li><li class="item"><a id="privacy" href="//go.microsoft.com/fwlink/?LinkId=521839" h="ID=SERP,5071.1">隐私与 Cookie</a></li><li class="item"><a id="legal" href="//go.microsoft.com/fwlink/?LinkID=246338" h="ID=SERP,5072.1">法律声明</a></li><li class="item"><a id="" href="//go.microsoft.com/fwlink/?linkid=868923" h="ID=SERP,5073.1">广告</a></li><li class="item"><a id="" href="//go.microsoft.com/fwlink/?LinkID=286759" h="ID=SERP,5074.1">关于我们的广告</a></li><li class="item"><a id="help" href="//support.microsoft.com/topic/82d20721-2d6f-4012-a13d-d1910ccf203f" h="ID=SERP,5075.1">帮助</a></li><li class="item"><a id="sb_feedback" href="#" h="ID=SERP,5076.1">反馈</a></li></ul></div></footer></div></div></div><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="https://r.bing.com/rs/6r/fU/jnc,nj/tlifxqsNyCzxIJnRwtQKuZToQQw.js?or=n"></script><script type="text/javascript" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=">//<![CDATA[
_G={Region:"CN",Lang:"zh-CN",ST:(typeof si_ST!=='undefined'?si_ST:new Date),Mkt:"zh-CN",RevIpCC:"cn",RTL:false,Ver:"02",IG:"FF4EF23145174E85AD474F918FF1DBA7",EventID:"677f654f27004b968703ecd7c0d95c04",V:"homepage",P:"SERP",DA:"MWHE01",CID:"38558B11726A671F048D9E7E73306660",SUIH:"WRx5BKryomwCvf4uGF4x7w",adc:"b_ad",EF:{bmasynctrigger:1,getslctspt:1,newtabsloppyclick:1,chevroncheckmousemove:1,sharepreview:1,shareoutimage:1,sharefixreadnum:1,sharepreviewthumbnailid:1,shareencodefix:1,chatskip2content:1,fablogfix:1},gpUrl:"\/fd\/ls\/GLinkPing.aspx?" }; _G.lsUrl="/fd/ls/l?IG="+_G.IG+"&CID="+_G.CID ;curUrl="https:\/\/cn.bing.com\/";_G.EnableCompression=false;_G.DirectLogFlight=0;function si_T(a){ if(document.images){_G.GPImg=new Image;_G.GPImg.src=_G.gpUrl+'IG='+_G.IG+'&CID='+_G.CID+'&'+a;}return true;}_G.BAT="0";_G.NTT="600000";_G.CTT="3000";_G.BNFN="Default";_G.LG="160";_G.FilterFlareInterval=5;;
//]]></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/ACby6guiuiyuEYRTFOH8no-JKCo.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/sTqO8BLDL3SMwm5-DmlL0eodCJk.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/PVEp6LmF7FGQF4_wW3Ri1trRPv4.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/oJtq_u9TBV7TshzGOx6yvnobEEU.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/PrUVzF4hlCEHR6XAp8AR6euT5OM.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/qN3rmGYj9Qsn6JmjzmYclpmfCHI.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/omjewb8RA_1ed-86jqIwN_f_ON8.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/9RU9Mo45ZvCytDGnLCWS0LulULU.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/svYzgo4yD9vzUlVytiD-v2lepRM.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="https://r.bing.com/rb/5U/jnc,nj/P2x0V8oF_ckBp8Ub5FlrxazIArQ.js?bu=BuAE5ATmBKMEzwTsBA&or=n"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/ICf9X-WMafiZOnS_3M9RpM8994E.gz.js"></script><script type="text/javascript" crossorigin="anonymous" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=" src="/rp/nIt_N_kpXwbKZc4NbcR2zfSrv0E.gz.js"></script><script type="text/javascript" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=">//<![CDATA[
_w.rms.js({'A:rms:answers:Shared:BingCore.Bundle':'\/rp\/yvav1_QXkA6zP3dpoNUdncQpO8o.gz.js'},{'A:rms:answers:Feedback:FeedbackAccessibility':'\/rp\/peNl4yUB4P3PwDM4J7NWGzi8hKM.gz.js'},{'A:AppendHTML':'https:\/\/r.bing.com\/rs\/6r\/lz\/nj\/pxzfjFIjWTDQikh0A5aT_cguYyc.js?or=n'},{'A:AjaxLoad':'https:\/\/r.bing.com\/rs\/6r\/lN\/nj\/EmG-XMIMCcq8zmcVBBO7jkFERAE.js?or=n'},{'A:rms:answers:Feedback:FeedbackBootstrapBundle':'\/rp\/FfXzXdr8vxge7bE3bEZV_NYyNIE.gz.js'},{'A:0':0},{'A:rms:answers:BoxModel:Rules':'\/rp\/N0NZj2UoTgAcpHMO-3FYmE5C7G4.gz.js'},{'A:rms:answers:BoxModel:TriggerFirstChunk':'\/rp\/iuYNUHE3kZrz6Jrb0_Mf0yBFZN0.gz.js'},{'A:rms:answers:BoxModel:ViewportQueue':'\/rp\/8srl0LOx92Ew0yyAq2m2e33cq7I.gz.js'},{'A:rms:answers:BoxModel:LayoutQueue':'\/rp\/Mt62GUgrdySmO3Hz6WvsY51OVCM.gz.js'},{'A:rms:answers:BoxModel:EventQueue':'\/rp\/8AigLIxHhxH6NCSV3aSsPWpKiRs.gz.js'},{'A:rms:answers:BoxModel:Framework':'\/rp\/TLp8x4XeidQ-QJsLYxakNdnyojQ.gz.js'});;
//]]></script><div id="aRmsDefer"><script type="text/rms" nonce="NswLywYcmcprKdDH3kMxFF5vl+yeKu1radXvoCmwxVY=">//<![CDATA[
Feedback.Bootstrap.InitializeFeedback({page:true},"sb_feedback",1,0,0);;
//]]></script></div></body></html>
--- PASS: TestReadFromHTTPResponseDemo (1.40s)
PASS
从内存的字节切片中读取
go
func ReadFromMemoryDemo() {
data := []byte("hello io.Reader")
reader := bytes.NewReader(data)
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
测试方法
go
func TestReadFromMemoryDemo(t *testing.T) {
ReadFromMemoryDemo()
}
输出结果
=== RUN TestReadFromMemoryDemo
h
e
l
l
o
i
o
.
R
e
a
d
e
r
--- PASS: TestReadFromMemoryDemo (0.00s)
PASS
自定义io.Reader
实现
go
// 自定义io.Reader实现
type myReader struct {
data []byte
pos int
}
func (mr *myReader) Read(p []byte) (int, error) {
n := copy(p, mr.data[mr.pos:])
mr.pos += n
if mr.pos >= len(mr.data) {
return n, io.EOF
}
return n, nil
}
func ReadFromMyReaderDemo() {
data := []byte("hello io.Reader")
reader := &myReader{data, 0}
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
测试方法
go
func TestReadFromMyReaderDemo(t *testing.T) {
ReadFromMyReaderDemo()
}
输出结果
=== RUN TestReadFromMyReaderDemo
h
e
l
l
o
i
o
.
R
e
a
d
e
r
--- PASS: TestReadFromMyReaderDemo (0.00s)
PASS
源码
go
// reader_demo_2.go 文件
package reader_demo
import (
"bufio"
"bytes"
"fmt"
"io"
"net/http"
"os"
"strings"
)
func ReadFromStrDemo() {
str := "hello world"
reader := bufio.NewReader(strings.NewReader(str))
buf := make([]byte, 2)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
func ReadFromFileDemo() {
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("Error opening file", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
func ReadFromHTTPResponseDemo() {
resp, err := http.Get("https://www.bing.com")
if err != nil {
fmt.Println("Error", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Println("StatusCode", resp.StatusCode)
return
}
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error", err)
return
}
fmt.Println(string(body))
}
func ReadFromMemoryDemo() {
data := []byte("hello io.Reader")
reader := bytes.NewReader(data)
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
// 自定义io.Reader实现
type myReader struct {
data []byte
pos int
}
func (mr *myReader) Read(p []byte) (int, error) {
n := copy(p, mr.data[mr.pos:])
mr.pos += n
if mr.pos >= len(mr.data) {
return n, io.EOF
}
return n, nil
}
func ReadFromMyReaderDemo() {
data := []byte("hello io.Reader")
reader := &myReader{data, 0}
buf := make([]byte, 1)
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("Error reading", err)
break
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}
go
// readder_demo_2_test.go 文件
package reader_demo
import "testing"
func TestReadFromStrDemo(t *testing.T) {
ReadFromStrDemo()
}
func TestReadFromFileDemo(t *testing.T) {
ReadFromFileDemo()
}
func TestReadFromHTTPResponseDemo(t *testing.T) {
ReadFromHTTPResponseDemo()
}
func TestReadFromMemoryDemo(t *testing.T) {
ReadFromMemoryDemo()
}
func TestReadFromMyReaderDemo(t *testing.T) {
ReadFromMyReaderDemo()
}