2016. július 2., szombat 8:15:19 UTC+2 időpontban Sri G a következőt írta: > > I'm working on receiving uploads through a form. > > The tricky part is validation. > > I attempt to read the first 1024 bytes to check the mime of the file and > then if valid read the rest and hash it and also save it to disk. Reading > the mime type is successful and I've gotten it to work by chaining > TeeReader but it seems very hackish. Whats the idiomatic way to do this? > > I'm trying something like this: > > > // Parse my multi part form > ... > // Get file handle > file, err := fh.Open() > > var a bytes.Buffer > > io.CopyN(&a, file, 1024) > > mime := mimemagic.Match("", a.Bytes()) > // Check mime type (this works fine) > > I'm trying to seek a stream so this should be no-op > file.Seek(0, 0) > > The file stored on disk is 1KB larger than the original so it appears to > be re-copying the entire file and appending it to bytes.Buffer > io.Copy(&a, file) > > checksum := md5.New() > b := io.TeeReader(&a, checksum) > > md5hex := hex.EncodeToString(checksum.Sum(nil)) > fmt.Println("md5=", md5hex) > > //Open file f for writing to disk > ... > //Save file > io.Copy(f, b) > > > Checked the md5 of (1KB of orig + orig), and (orginal - first 1 KB), > neither match the md5 of the file being hashed. > > Why can't I append the rest of the stream to the byte buffer to get the > complete file in memory and why is the byte buffer being "consumed"? > > I simply need to read the same array of byte multiple times, I don't need > to "copy" them. I'm coming from a C background so I'm wondering what is > going on behind the scenes as well. >
If you know you'll have to read the whole file into memory, then do that, and use bytes.NewReader to create a reader for that byte slice. If you read partly, to decide whether to go on, then use fh.Read or io.ReadAtLeast with a byte slice. If you read sth, then want to read the whole from the beginning, construct a Reader with io.MultiReader(bytes.NewReader(b), fh). You can combine these approaches, but if the while file size is less than a few KiB, I think it is easier, simpler and more performant (!) to read the whole file up into memory, into a bytes.Buffer, and construct the needed readers with bytes.NewReader(buf.Bytes()). -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.