How do you make a ReadCloser?

33,745 views
Skip to first unread message

Charles

unread,
Jun 12, 2010, 2:53:05 AM6/12/10
to golang-nuts
Nube go programmer needs help:

I want to write a go DB driver for Riak. Riak requires clients issue
HTTP GETs, PUTs, POSTs, and DELETEs to perform various DB operations.

I can't figure out how to make a "readcloser" to assign to a
http.Request.Body object. Consider the code statement below.

var req http.Request
req.Method = "PUT"
// assign more req properties here ...
req.Body = bytes.NewBufferString("foo") // won't work because a Buffer
doesn't implement read and close

req.Body = "hello" //Doesn't work because strings don't implement read
and close

How do I make a read closer? I've scoured through Go source code, but
an obvious solution hasn't jumped out at me.

Best,

Charles

John Asmuth

unread,
Jun 12, 2010, 8:51:31 AM6/12/10
to golang-nuts
Hi,

Taking a look at io.ReadCloser, it's a union of the Reader and Closer
interfaces.

bytes.NewBufferString returns a bytes.Buffer* something that
implements Reader, so if we start with that class, we're half way
there.

You can add functionality to this class very easily.

type ClosingBuffer struct {
*bytes.Buffer
}
func (cb *ClosingBuffer) Close() (err os.Error) {
//we don't actually have to do anything here, since the buffer is
just some data in memory
//and the error is initialized to no-error
return
}

And use it like the following:

func main () {
cb := &ClosingBuffer{bytes.NewBufferString("Hi!")}
var rc io.ReadCloser
rc = cb
rc.Close()
}

- John

Michael Hoisie

unread,
Jun 12, 2010, 11:58:40 AM6/12/10
to golang-nuts
This is how I do it for my projects:

type nopCloser struct {
io.Reader
}

func (nopCloser) Close() os.Error { return nil }

And then in your program:
req.Body = nopCloser{bytes.NewBufferString(conn.postData)}

- Mike

Charles

unread,
Jun 12, 2010, 11:55:00 PM6/12/10
to golang-nuts
Thanks for explaining this. Compilation successful!

I had spent two nights reading documentation and writing code to no
avail. The big idea is that you can make a struct that IS a
bytes.Buffer, rather than a struct of which one of its properties is a
bytes.Buffer.

Awesome!

-C

John Asmuth

unread,
Jun 13, 2010, 11:22:07 AM6/13/10
to golang-nuts
This way is slicker, yeah.

payton...@gmail.com

unread,
Aug 28, 2015, 8:07:20 PM8/28/15
to golang-nuts, charleswt...@gmail.com

borjabe...@gmail.com

unread,
Dec 1, 2015, 8:29:27 AM12/1/15
to golang-nuts, charleswt...@gmail.com
Hi all, first, sorry for the post necromancy... but I found this question while looking and I think this might be useful for someone like me :)

How about this?

req.Body = ioutil.NopCloser(bytes.NewReader([]byte("foo")))

Best regards,

mark...@gmail.com

unread,
Dec 7, 2015, 11:02:50 AM12/7/15
to golang-nuts, charleswt...@gmail.com, borjabe...@gmail.com
Thanks for this :-)

liuda...@gmail.com

unread,
Mar 10, 2016, 2:33:23 AM3/10/16
to golang-nuts, charleswt...@gmail.com
Awsome~

keens...@gmail.com

unread,
Jun 27, 2018, 12:51:52 PM6/27/18
to golang-nuts
This worked perfectly, thanks!

Ansuraj Khadanga

unread,
Jul 1, 2022, 1:09:15 AM7/1/22
to golang-nuts
Thats great! Thanks for sharing.

req.Body = ioutil.NopCloser(bytes.NewReader([]byte("foo")))

works!

Alex Shi

unread,
Jul 3, 2022, 9:47:21 PM7/3/22
to golang-nuts
Note. For ioutil#NopCloser, as of Go 1.16, this function simply calls io.NopCloser.
Reply all
Reply to author
Forward
0 new messages