using System.IO; 
 | 
  
 | 
namespace Top.Api.Util 
 | 
{ 
 | 
    /// <summary> 
 | 
    /// 文件元数据。 
 | 
    /// 可以使用以下几种构造方法: 
 | 
    /// 本地路径:new FileItem("C:/temp.jpg"); 
 | 
    /// 本地文件:new FileItem(new FileInfo("C:/temp.jpg")); 
 | 
    /// 字节数组:new FileItem("abc.jpg", bytes); 
 | 
    /// 输入流:new FileItem("abc.jpg", stream); 
 | 
    /// </summary> 
 | 
    public class FileItem 
 | 
    { 
 | 
        private Contract contract; 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于本地文件的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="fileInfo">本地文件</param> 
 | 
        public FileItem(FileInfo fileInfo) 
 | 
        { 
 | 
            this.contract = new LocalContract(fileInfo); 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于本地文件全路径的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="filePath">本地文件全路径</param> 
 | 
        public FileItem(string filePath) : this(new FileInfo(filePath)) 
 | 
        { 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于文件名和字节数组的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="fileName">文件名称(服务端持久化字节数组到磁盘时的文件名)</param> 
 | 
        /// <param name="content">文件字节数组</param> 
 | 
        public FileItem(string fileName, byte[] content) : this(fileName, content, null) 
 | 
        { 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于文件名、字节数组和媒体类型的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="fileName">文件名(服务端持久化字节数组到磁盘时的文件名)</param> 
 | 
        /// <param name="content">文件字字节数组</param> 
 | 
        /// <param name="mimeType">媒体类型</param> 
 | 
        public FileItem(string fileName, byte[] content, string mimeType) 
 | 
        { 
 | 
            this.contract = new ByteArrayContract(fileName, content, mimeType); 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于文件名和输入流的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="fileName">文件名称(服务端持久化输入流到磁盘时的文件名)</param> 
 | 
        /// <param name="content">文件输入流</param> 
 | 
        public FileItem(string fileName, Stream stream) : this(fileName, stream, null) 
 | 
        { 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 基于文件名、输入流和媒体类型的构造器。 
 | 
        /// </summary> 
 | 
        /// <param name="fileName">文件名(服务端持久化输入流到磁盘时的文件名)</param> 
 | 
        /// <param name="content">文件输入流</param> 
 | 
        /// <param name="mimeType">媒体类型</param> 
 | 
        public FileItem(string fileName, Stream stream, string mimeType) 
 | 
        { 
 | 
            this.contract = new StreamContract(fileName, stream, mimeType); 
 | 
        } 
 | 
  
 | 
        public bool IsValid() 
 | 
        { 
 | 
            return this.contract.IsValid(); 
 | 
        } 
 | 
  
 | 
        public long GetFileLength() 
 | 
        { 
 | 
            return this.contract.GetFileLength(); 
 | 
        } 
 | 
  
 | 
        public string GetFileName() 
 | 
        { 
 | 
            return this.contract.GetFileName(); 
 | 
        } 
 | 
  
 | 
        public string GetMimeType() 
 | 
        { 
 | 
            return this.contract.GetMimeType(); 
 | 
        } 
 | 
  
 | 
        public void Write(Stream output) 
 | 
        { 
 | 
            this.contract.Write(output); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    internal interface Contract 
 | 
    { 
 | 
        bool IsValid(); 
 | 
        string GetFileName(); 
 | 
        string GetMimeType(); 
 | 
        long GetFileLength(); 
 | 
        void Write(Stream output); 
 | 
    } 
 | 
  
 | 
    internal class LocalContract : Contract 
 | 
    { 
 | 
        private FileInfo fileInfo; 
 | 
  
 | 
        public LocalContract(FileInfo fileInfo) 
 | 
        { 
 | 
            this.fileInfo = fileInfo; 
 | 
        } 
 | 
  
 | 
        public long GetFileLength() 
 | 
        { 
 | 
            return this.fileInfo.Length; 
 | 
        } 
 | 
  
 | 
        public string GetFileName() 
 | 
        { 
 | 
            return this.fileInfo.Name; 
 | 
        } 
 | 
  
 | 
        public string GetMimeType() 
 | 
        { 
 | 
            return Constants.CTYPE_DEFAULT; 
 | 
        } 
 | 
  
 | 
        public bool IsValid() 
 | 
        { 
 | 
            return this.fileInfo != null && this.fileInfo.Exists; 
 | 
        } 
 | 
  
 | 
        public void Write(Stream output) 
 | 
        { 
 | 
            using (BufferedStream bfs = new BufferedStream(this.fileInfo.OpenRead())) 
 | 
            { 
 | 
                int n = 0; 
 | 
                byte[] buffer = new byte[Constants.READ_BUFFER_SIZE]; 
 | 
                while ((n = bfs.Read(buffer, 0, buffer.Length)) > 0) 
 | 
                { 
 | 
                    output.Write(buffer, 0, n); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    internal class ByteArrayContract : Contract 
 | 
    { 
 | 
        private string fileName; 
 | 
        private byte[] content; 
 | 
        private string mimeType; 
 | 
  
 | 
        public ByteArrayContract(string fileName, byte[] content, string mimeType) 
 | 
        { 
 | 
            this.fileName = fileName; 
 | 
            this.content = content; 
 | 
            this.mimeType = mimeType; 
 | 
        } 
 | 
  
 | 
        public bool IsValid() 
 | 
        { 
 | 
            return this.content != null && this.fileName != null; 
 | 
        } 
 | 
  
 | 
        public long GetFileLength() 
 | 
        { 
 | 
            return this.content.Length; 
 | 
        } 
 | 
  
 | 
        public string GetFileName() 
 | 
        { 
 | 
            return this.fileName; 
 | 
        } 
 | 
  
 | 
        public string GetMimeType() 
 | 
        { 
 | 
            if (string.IsNullOrEmpty(this.mimeType)) 
 | 
            { 
 | 
                return Constants.CTYPE_DEFAULT; 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                return this.mimeType; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        public void Write(Stream output) 
 | 
        { 
 | 
            output.Write(this.content, 0, this.content.Length); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    internal class StreamContract : Contract 
 | 
    { 
 | 
        private string fileName; 
 | 
        private Stream stream; 
 | 
        private string mimeType; 
 | 
  
 | 
        public StreamContract(string fileName, Stream stream, string mimeType) 
 | 
        { 
 | 
            this.fileName = fileName; 
 | 
            this.stream = stream; 
 | 
            this.mimeType = mimeType; 
 | 
        } 
 | 
  
 | 
        public long GetFileLength() 
 | 
        { 
 | 
            return 0L; 
 | 
        } 
 | 
  
 | 
        public string GetFileName() 
 | 
        { 
 | 
            return this.fileName; 
 | 
        } 
 | 
  
 | 
        public string GetMimeType() 
 | 
        { 
 | 
            if (string.IsNullOrEmpty(mimeType)) 
 | 
            { 
 | 
                return Constants.CTYPE_DEFAULT; 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                return this.mimeType; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        public bool IsValid() 
 | 
        { 
 | 
            return this.stream != null && this.fileName != null; 
 | 
        } 
 | 
  
 | 
        public void Write(Stream output) 
 | 
        { 
 | 
            using (this.stream) 
 | 
            { 
 | 
                int n = 0; 
 | 
                byte[] buffer = new byte[Constants.READ_BUFFER_SIZE]; 
 | 
                while ((n = this.stream.Read(buffer, 0, buffer.Length)) > 0) 
 | 
                { 
 | 
                    output.Write(buffer, 0, n); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 |