我已经下载了一个HttpHandler类,它将JS文件连接成一个文件,并且它会
在它连接的每个文件的开头附加字符.
关于是什么导致这个的任何想法?是否可以将处理的文件写入缓存,缓存是如何存储/渲染的?
任何投入将不胜感激.
using System; using System.Net; using System.IO; using System.IO.Compression; using System.Text; using System.Configuration; using System.Web; public class HttpCombiner : IHttpHandler { private const bool DO_GZIP = false; private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays(30); public void ProcessRequest (HttpContext context) { HttpRequest request = context.Request; // Read setName, contentType and version. All are required. They are // used as cache key string setName = request["s"] ?? string.Empty; string contentType = request["t"] ?? string.Empty; string version = request["v"] ?? string.Empty; // Decide if browser supports compressed response bool isCompressed = DO_GZIP && this.CanGZip(context.Request); // Response is written as UTF8 encoding. If you are using languages // like Arabic, you should change this to proper encoding UTF8Encoding encoding = new UTF8Encoding(false); // If the set has already been cached, write the response directly // from cache. Otherwise generate the response and cache it if (!this.WriteFromCache(context, setName, version, isCompressed, contentType)) { using (MemoryStream memoryStream = new MemoryStream(5000)) { // Decide regular stream or GZipStream based on whether the // response can be cached or not using (Stream writer = isCompressed ? (Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) : memoryStream) { // Load the files defined inand process // each file string setDefinition = System.Configuration .ConfigurationManager.AppSettings[setName] ?? ""; string[] fileNames = setDefinition.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string fileName in fileNames) { byte[] fileBytes = this.GetFileBytes( context, fileName.Trim(), encoding); writer.Write(fileBytes, 0, fileBytes.Length); } writer.Close(); } // Cache the combined response so that it can be directly // written in subsequent calls byte[] responseBytes = memoryStream.ToArray(); context.Cache.Insert( GetCacheKey(setName, version, isCompressed), responseBytes, null, System.Web.Caching.Cache.NoAbsoluteExpiration, CACHE_DURATION); // Generate the response this.WriteBytes(responseBytes, context, isCompressed, contentType); } } } private byte[] GetFileBytes(HttpContext context, string virtualPath, Encoding encoding) { if (virtualPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) { using (WebClient client = new WebClient()) { return client.DownloadData(virtualPath); } } else { string physicalPath = context.Server.MapPath(virtualPath); byte[] bytes = File.ReadAllBytes(physicalPath); // TODO: Convert unicode files to specified encoding. // For now, assuming files are either ASCII or UTF8 return bytes; } } private bool WriteFromCache(HttpContext context, string setName, string version, bool isCompressed, string contentType) { byte[] responseBytes = context.Cache[GetCacheKey(setName, version, isCompressed)] as byte[]; if (null == responseBytes || 0 == responseBytes.Length) return false; this.WriteBytes(responseBytes, context, isCompressed, contentType); return true; } private void WriteBytes(byte[] bytes, HttpContext context, bool isCompressed, string contentType) { HttpResponse response = context.Response; response.AppendHeader("Content-Length", bytes.Length.ToString()); response.ContentType = contentType; if (isCompressed) response.AppendHeader("Content-Encoding", "gzip"); context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION)); context.Response.Cache.SetMaxAge(CACHE_DURATION); context.Response.Cache.AppendCacheExtension( "must-revalidate, proxy-revalidate"); response.OutputStream.Write(bytes, 0, bytes.Length); response.Flush(); } private bool CanGZip(HttpRequest request) { string acceptEncoding = request.Headers["Accept-Encoding"]; if (!string.IsNullOrEmpty(acceptEncoding) && (acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate"))) return true; return false; } private string GetCacheKey(string setName, string version, bool isCompressed) { return "HttpCombiner." + setName + "." + version + "." + isCompressed; } public bool IsReusable { get { return true; } } }
Stefan.. 21
字符是UTF BOM标记.
字符是UTF BOM标记.
它的UTF 字节顺序标记(BOM).
它将在每个文件的开头,但您的编辑器将在那里忽略它们.连接时它们最终位于中间,所以你看到它们.
我认为这是具有UTF-8编码的文件的字节顺序标记(BOM).此标记允许确定文件的存储编码.
好的,我调试了你的代码.
从磁盘读取文件时,BOM标记出现在源流中:
byte[] bytes = File.ReadAllBytes(physicalPath); // TODO: Convert unicode files to specified encoding. For now, assuming // files are either ASCII or UTF8
如果你正确阅读文件,你可以摆脱标记.