ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# package multipart `import "mime/multipart"` multipart实现了MIME的multipart解析,参见[RFC 2046](http://tools.ietf.org/html/rfc2046)。该实现适用于HTTP([RFC 2388](http://tools.ietf.org/html/rfc2388))和常见浏览器生成的multipart主体。 ## Index * [type File](#File) * [type FileHeader](#FileHeader) * [func (fh \*FileHeader) Open() (File, error)](#FileHeader.Open) * [type Part](#Part) * [func (p \*Part) FileName() string](#Part.FileName) * [func (p \*Part) FormName() string](#Part.FormName) * [func (p \*Part) Read(d []byte) (n int, err error)](#Part.Read) * [func (p \*Part) Close() error](#Part.Close) * [type Form](#Form) * [func (f \*Form) RemoveAll() error](#Form.RemoveAll) * [type Reader](#Reader) * [func NewReader(r io.Reader, boundary string) \*Reader](#NewReader) * [func (r \*Reader) ReadForm(maxMemory int64) (f \*Form, err error)](#Reader.ReadForm) * [func (r \*Reader) NextPart() (\*Part, error)](#Reader.NextPart) * [type Writer](#Writer) * [func NewWriter(w io.Writer) \*Writer](#NewWriter) * [func (w \*Writer) FormDataContentType() string](#Writer.FormDataContentType) * [func (w \*Writer) Boundary() string](#Writer.Boundary) * [func (w \*Writer) SetBoundary(boundary string) error](#Writer.SetBoundary) * [func (w \*Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error)](#Writer.CreatePart) * [func (w \*Writer) CreateFormField(fieldname string) (io.Writer, error)](#Writer.CreateFormField) * [func (w \*Writer) CreateFormFile(fieldname, filename string) (io.Writer, error)](#Writer.CreateFormFile) * [func (w \*Writer) WriteField(fieldname, value string) error](#Writer.WriteField) * [func (w \*Writer) Close() error](#Writer.Close) ### Examples * [NewReader](#example-NewReader) ## type [File](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L142 "View Source") ``` type File interface { io.Reader io.ReaderAt io.Seeker io.Closer } ``` File是一个接口,实现了对一个multipart信息中文件记录的访问。它的内容可以保持在内存或者硬盘中,如果保持在硬盘中,底层类型就会是\*os.File。 ## type [FileHeader](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L122 "View Source") ``` type FileHeader struct { Filename string Header textproto.MIMEHeader // 内含隐藏或非导出字段 } ``` FileHeader描述一个multipart请求的(一个)文件记录的信息。 ### func (\*FileHeader) [Open](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L131 "View Source") ``` func (fh *FileHeader) Open() (File, error) ``` Open方法打开并返回其关联的文件。 ## type [Part](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L28 "View Source") ``` type Part struct { // 主体的头域,如果存在,是按Go的http.Header风格标准化的,如"foo-bar"改变为"Foo-Bar"。 // 有一个特殊情况,如果"Content-Transfer-Encoding"头的值是"quoted-printable"。 // 该头将从本map中隐藏,而主体会在调用Read时透明的解码。 Header textproto.MIMEHeader // 内含隐藏或非导出字段 } ``` Part代表multipart主体的单独一个记录。 ### func (\*Part) [FileName](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L68 "View Source") ``` func (p *Part) FileName() string ``` 返回Part 的Content-Disposition 头的文件名参数。 ### func (\*Part) [FormName](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L54 "View Source") ``` func (p *Part) FormName() string ``` 如果p的Content-Disposition头值为"form-data",则返回名字参数;否则返回空字符串。 ### func (\*Part) [Read](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L131 "View Source") ``` func (p *Part) Read(d []byte) (n int, err error) ``` Read方法读取一个记录的主体,也就是其头域之后到下一记录之前的部分。 ### func (\*Part) [Close](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L200 "View Source") ``` func (p *Part) Close() error ``` ## type [Form](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L100 "View Source") ``` type Form struct { Value map[string][]string File map[string][]*FileHeader } ``` Form是一个解析过的multipart表格。它的File参数部分保存在内存或者硬盘上,可以使用\*FileHeader类型属性值的Open方法访问。它的Value 参数部分保存为字符串,两者都以属性名为键。 ### func (\*Form) [RemoveAll](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L106 "View Source") ``` func (f *Form) RemoveAll() error ``` 删除Form关联的所有临时文件。 ## type [Reader](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L208 "View Source") ``` type Reader struct { // 内含隐藏或非导出字段 } ``` Reader是MIME的multipart主体所有记录的迭代器。Reader的底层会根据需要解析输入,不支持Seek。 ### func [NewReader](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L90 "View Source") ``` func NewReader(r io.Reader, boundary string) *Reader ``` 函数使用给出的MIME边界和r创建一个multipart读取器。 边界一般从信息的"Content-Type" 头的"boundary"属性获取。可使用mime.ParseMediaType函数解析这种头域。 Example ``` msg := &mail.Message{ Header: map[string][]string{ "Content-Type": []string{"multipart/mixed; boundary=foo"}, }, Body: strings.NewReader( "--foo\r\nFoo: one\r\n\r\nA section\r\n" + "--foo\r\nFoo: two\r\n\r\nAnd another\r\n" + "--foo--\r\n"), } mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type")) if err != nil { log.Fatal(err) } if strings.HasPrefix(mediaType, "multipart/") { mr := multipart.NewReader(msg.Body, params["boundary"]) for { p, err := mr.NextPart() if err == io.EOF { return } if err != nil { log.Fatal(err) } slurp, err := ioutil.ReadAll(p) if err != nil { log.Fatal(err) } fmt.Printf("Part %q: %q\n", p.Header.Get("Foo"), slurp) } } ``` Output: ``` Part "one": "A section" Part "two": "And another" ``` ### func (\*Reader) [ReadForm](https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L23 "View Source") ``` func (r *Reader) ReadForm(maxMemory int64) (f *Form, err error) ``` ReadForm解析整个multipart信息中所有Content-Disposition头的值为"form-data"的记录。它会把最多maxMemory字节的文件记录保存在内存里,其余保存在硬盘的临时文件里。 ### func (\*Reader) [NextPart](https://github.com/golang/go/blob/master/src/mime/multipart/multipart.go#L222 "View Source") ``` func (r *Reader) NextPart() (*Part, error) ``` NextPart返回multipart的下一个记录或者返回错误。如果没有更多记录会返回io.EOF。 ## type [Writer](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L18 "View Source") ``` type Writer struct { // 内含隐藏或非导出字段 } ``` Writer类型用于生成multipart信息。 ### func [NewWriter](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L26 "View Source") ``` func NewWriter(w io.Writer) *Writer ``` NewWriter函数返回一个设定了一个随机边界的Writer,数据写入w。 ### func (\*Writer) [FormDataContentType](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L67 "View Source") ``` func (w *Writer) FormDataContentType() string ``` 方法返回w对应的HTTP multipart请求的Content-Type的值,多以multipart/form-data起始。 ### func (\*Writer) [Boundary](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L34 "View Source") ``` func (w *Writer) Boundary() string ``` 方法返回该Writer的边界。 ### func (\*Writer) [SetBoundary](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L43 "View Source") ``` func (w *Writer) SetBoundary(boundary string) error ``` SetBoundary方法重写Writer默认的随机生成的边界为提供的boundary参数。方法必须在创建任何记录之前调用,boundary只能包含特定的ascii字符,并且长度应在1-69字节之间。 ### func (\*Writer) [CreatePart](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L84 "View Source") ``` func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) ``` CreatePart方法使用提供的header创建一个新的multipart记录。该记录的主体应该写入返回的Writer接口。调用本方法后,任何之前的记录都不能再写入。 ### func (\*Writer) [CreateFormField](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L134 "View Source") ``` func (w *Writer) CreateFormField(fieldname string) (io.Writer, error) ``` CreateFormField方法使用给出的属性名调用CreatePart方法。 ### func (\*Writer) [CreateFormFile](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L123 "View Source") ``` func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error) ``` CreateFormFile是CreatePart方法的包装, 使用给出的属性名和文件名创建一个新的form-data头。 ### func (\*Writer) [WriteField](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L142 "View Source") ``` func (w *Writer) WriteField(fieldname, value string) error ``` WriteField方法调用CreateFormField并写入给出的value。 ### func (\*Writer) [Close](https://github.com/golang/go/blob/master/src/mime/multipart/writer.go#L153 "View Source") ``` func (w *Writer) Close() error ``` Close方法结束multipart信息,并将结尾的边界写入底层io.Writer接口。