# package multipart

`import "mime/multipart"`

multipart实现了MIME的multipart解析，参见RFC 2046。该实现适用于HTTP（RFC 2388）和常见浏览器生成的multipart主体。

## type File

    type File interface {
        io.Reader
        io.ReaderAt
        io.Seeker
        io.Closer
    }

File是一个接口，实现了对一个multipart信息中文件记录的访问。它的内容可以保持在内存或者硬盘中，如果保持在硬盘中，底层类型就会是*os.File。

## type FileHeader

    type FileHeader struct {
        Filename string
        Header   textproto.MIMEHeader
        // 内含隐藏或非导出字段
    }

FileHeader描述一个multipart请求的（一个）文件记录的信息。

### func (*FileHeader) Open

    func (fh *FileHeader) Open() (File, error)

Open方法打开并返回其关联的文件。

## type Part

    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

    func (p *Part) FileName() string

返回Part 的Content-Disposition 头的文件名参数。

### func (*Part) FormName

    func (p *Part) FormName() string

如果p的Content-Disposition头值为"form-data"，则返回名字参数；否则返回空字符串。

### func (*Part) Read

    func (p *Part) Read(d []byte) (n int, err error)

Read方法读取一个记录的主体，也就是其头域之后到下一记录之前的部分。

### func (*Part) Close

    func (p *Part) Close() error

## type Form

    type Form struct {
        Value map[string][]string
        File  map[string][]*FileHeader
    }

Form是一个解析过的multipart表格。它的File参数部分保存在内存或者硬盘上，可以使用*FileHeader类型属性值的Open方法访问。它的Value 参数部分保存为字符串，两者都以属性名为键。

### func (*Form) RemoveAll

    func (f *Form) RemoveAll() error

删除Form关联的所有临时文件。

## type Reader

    type Reader struct {
        // 内含隐藏或非导出字段
    }

Reader是MIME的multipart主体所有记录的迭代器。Reader的底层会根据需要解析输入，不支持Seek。

### func NewReader

    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

    func (r *Reader) ReadForm(maxMemory int64) (f *Form, err error)

ReadForm解析整个multipart信息中所有Content-Disposition头的值为"form-data"的记录。它会把最多maxMemory字节的文件记录保存在内存里，其余保存在硬盘的临时文件里。

### func (*Reader) NextPart

    func (r *Reader) NextPart() (*Part, error)

NextPart返回multipart的下一个记录或者返回错误。如果没有更多记录会返回io.EOF。

## type Writer

    type Writer struct {
        // 内含隐藏或非导出字段
    }

Writer类型用于生成multipart信息。

### func NewWriter

    func NewWriter(w io.Writer) *Writer

NewWriter函数返回一个设定了一个随机边界的Writer，数据写入w。

### func (*Writer) FormDataContentType

    func (w *Writer) FormDataContentType() string

方法返回w对应的HTTP multipart请求的Content-Type的值，多以multipart/form-data起始。

### func (*Writer) Boundary

    func (w *Writer) Boundary() string

方法返回该Writer的边界。

### func (*Writer) SetBoundary

    func (w *Writer) SetBoundary(boundary string) error

SetBoundary方法重写Writer默认的随机生成的边界为提供的boundary参数。方法必须在创建任何记录之前调用，boundary只能包含特定的ascii字符，并且长度应在1-69字节之间。

### func (*Writer) CreatePart

    func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error)

CreatePart方法使用提供的header创建一个新的multipart记录。该记录的主体应该写入返回的Writer接口。调用本方法后，任何之前的记录都不能再写入。

### func (*Writer) CreateFormField

    func (w *Writer) CreateFormField(fieldname string) (io.Writer, error)

CreateFormField方法使用给出的属性名调用CreatePart方法。

### func (*Writer) CreateFormFile

    func (w *Writer) CreateFormFile(fieldname, filename string) (io.Writer, error)

CreateFormFile是CreatePart方法的包装， 使用给出的属性名和文件名创建一个新的form-data头。

### func (*Writer) WriteField

    func (w *Writer) WriteField(fieldname, value string) error

WriteField方法调用CreateFormField并写入给出的value。

### func (*Writer) Close

    func (w *Writer) Close() error

Close方法结束multipart信息，并将结尾的边界写入底层io.Writer接口。