func FromStream(reader io.Reader, name string) *FileBox {
	return newFileBox(&OptionsCommon{
		Name:    name,
		BoxType: TypeStream,
	}, newFileBoxStream(reader))
}
FromStream from io.Reader
package filebox
import (
	"bufio"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/bitly/go-simplejson"
	"github.com/tuotoo/qrcode"
	helper_functions "github.com/wechaty/go-wechaty/wechaty-puppet/helper"
	"io"
	"io/ioutil"
	"mime"
	"net/http"
	"net/url"
	"os"
	path2 "path"
	"path/filepath"
)
var ErrToJSON = errors.New("FileBox.toJSON() only support TypeUrl,TypeQRCode,TypeBase64")
type fileImplInterface interface {
	toJSONMap() map[string]interface{}
	toReader() (io.Reader, error)
}
type FileBox struct {
	fileImpl  fileImplInterface
	Name      string
	metadata  map[string]interface{}
	boxType   Type
	mimeType  string
}
func newFileBox(common *OptionsCommon, fileImpl fileImplInterface) *FileBox {
	return &FileBox{
		fileImpl: fileImpl,
		Name:     common.Name,
		metadata: common.Metadata,
		boxType:  common.BoxType,
		mimeType: mime.TypeByExtension(filepath.Ext(common.Name)),
	}
}
func FromJSON(s string) (*FileBox, error) {
	newJson, err := simplejson.NewJson([]byte(s))
	if err != nil {
		return nil, err
	}
	boxType, err := newJson.Get("boxType").Int64()
	if err != nil {
		return nil, err
	}
	options := new(Options)
	if err := json.Unmarshal([]byte(s), options); err != nil {
		return nil, err
	}
	switch boxType {
	case TypeBase64:
		return FromBase64(options.Base64, options.Name), nil
	case TypeQRCode:
		return FromQRCode(options.QrCode), nil
	case TypeUrl:
		return FromUrl(options.RemoteUrl, options.Name, nil)
	default:
		return nil, errors.New("invalid value boxType")
	}
}
func FromBase64(base64 string, name string) *FileBox {
	return newFileBox(&OptionsCommon{
		Name:    name,
		BoxType: TypeBase64,
	}, newFileBoxBase64(base64))
}
func FromUrl(urlString string, name string, headers http.Header) (*FileBox, error) {
	if name == "" {
		u, err := url.Parse(urlString)
		if err != nil {
			return nil, err
		}
		name = u.Path
	}
	return newFileBox(&OptionsCommon{
		Name:    name,
		BoxType: TypeUrl,
	}, newFileBoxUrl(urlString, headers)), nil
}
func FromFile(path, name string) *FileBox {
	if name == "" {
		name = path2.Base(path)
	}
	return newFileBox(&OptionsCommon{
		Name:    name,
		BoxType: TypeFile,
	}, newFileBoxFile(path))
}
func FromQRCode(qrCode string) *FileBox {
	return newFileBox(&OptionsCommon{
		Name:    "qrcode.png",
		BoxType: TypeQRCode,
	}, newFileBoxQRCode(qrCode))
}