-
Notifications
You must be signed in to change notification settings - Fork 18k
io: add OffsetWriter, NewOffsetWriter #45899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Where would this be used? does it come up often enough to be in the stdlib? |
Inconvenience with current implementations:
Better Performance for concurrent writes.
or another option would be to povide In-case of Thank you. |
Note that we use the In I think in general having both We already have |
Yes, But some book-keeping is needed.
Like // CopyBufferAt , copies `src` to `dst` at `off` using `buf`
//
// copied from io.copyBuffer
func CopyBufferAt(dst io.WriterAt, src io.Reader, off int64, buf []byte) (written int64, err error) {
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.WriteAt(buf[0:nr], off+written)
if nw < 0 || nr < nw {
nw = 0
if ew == nil {
ew = errors.New("invalid write result")
}
}
written += int64(nw)
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
if er != io.EOF {
err = er
}
break
}
}
return written, err
} As for my limited understanding goes, Thank you. |
Adding more variants of Copy seems like a mistake, as others have noted. |
This proposal has been added to the active column of the proposals project |
Does a call to |
I don't think I just copied definitions from Edit: Taking cue from
If If I think |
If
Thanks. |
It depends on subsequent writes. |
How would that be helpful for concurrent writes, then? |
Isn't this going to work? func main() {
var length, ps, i int64 = 1000000, 100000, 0
f, _ := os.Create("file")
for ; i < length; i += ps {
go func(from, to int64) {
req, _ := http.NewRequest(http.MethodGet, "https://someurl.com/file", nil)
setRange(req, from, to)
resp, _ := http.DefaultClient.Do(req)
nw := io.NewSectionWriter(f, from, to)
io.Copy(nw, resp.Body)
resp.Body.Close()
}(i, i+ps)
}
}
func setRange(req *http.Request, start, end int64) {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end-1))
} |
It's true, you don't seem to need n (the section length). But that makes it not really a SectionWriter but more like an OffsetWriter. That's fine of course. |
OK so it sounds like the API is:
Do I have that right? Does anyone object to this? |
Personally no. |
Based on the discussion above, this proposal seems like a likely accept. |
Just clairfying, the offsets in these methods end up being on top of the original offset used to create the
|
I'm not sure what do mean by NewOffsetWriter(x, 10)
WriteAt(y, 10) // y is written at offset 20 of x. |
Yes. Thanks. |
No change in consensus, so accepted. 🎉 |
Change https://go.dev/cl/406776 mentions this issue: |
Sadly I didn't see this proposal while it was still in the comments period. This API is supposed to help with concurrent writes in the multi section download. Since the upper bound of the file write is not limited anymore this looks very dangerous to use. I fear it will lead to concurrent writes to overlapping file sections, probably resulting in file corruptions. @rsc / @ianlancetaylor could you please reconsider this API addition before it gets implemented or do I overlook something? The original API with sections seemed much safer to me. |
@nightlyone Perhaps we should separate |
But, it is similar to other api's like Another possible solution, is to wrap your source (reader) with nw := io.NewOffsetWriter(f, from)
io.Copy(nw, io.LimitReader(resp.Body, n)) |
or
Helpful for concurrent writes.
The text was updated successfully, but these errors were encountered: