質問

私は1つのファイルにJSファイルを連結し、それが連結し、各ファイルの先頭に文字を追加し続けるのHttpHandlerクラスをダウンロードします。

これを引き起こしているものを上の任意のアイデア?それはそれは、彼らがキャッシュに書き込まれ、キャッシュが保存されてどのようにそれをレンダリング/です処理されたファイルをoncesだろうか?

任意の入力が非常に高く評価されるだろう。

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 in <appSettings> and 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; }
    }
}
役に立ちましたか?

解決

OK、私はあなたのコードをデバッグしてきます。

ファイルがディスクから読み込まれているとき、BOMマークがソースストリームに表示されます:

byte[] bytes = File.ReadAllBytes(physicalPath);
// TODO: Convert unicode files to specified encoding. For now, assuming
// files are either ASCII or UTF8

あなたが適切にファイルを読めば、あなたがマークを取り除くことができます。

他のヒント

文字がマーカーを UTF BOMされます。

そのUTF バイトオーダーマーク(BOM)にます。

これは、各ファイルの先頭になりますが、あなたのエディタがあり、それらを無視します。連結されたとき、彼らは途中で終わるので、あなたはそれらを参照してください。

私は、これはUTF-8でのファイルのためのバイトオーダーマーク(BOM)のだと思いますエンコーディング。このマークが保存されているどのファイルをコードに決定することができます。

あなたは、文字列内のファイルの内容を持っている場合は、

、.Trim()は非常に手際よく「BOM」を切り落とすされます。

あなたはそれを行うことができない場合があります。または、のファイルの端での空白場合がありますが、それは確かにオプションです。

の.js空白の場合は重要ではありませんので、これは仕事ができるます。

あなたのjsファイルがエンコードされているかチェックして、読書や連結を行うコードで同じエンコーディングを提供します。これらの2つの文字は、通常、ユニコードを指します。

これらの文字は、UTF-8 BOMです。彼らはgzip圧縮されたストリームから来ているようには思えません。それは彼らが応答ストリームに挿入されている可能性が高いですので、私はそれを使用する前に応答をクリアすることをお勧めします:

context.Response.Clear();

あなたは、実際のソリューションが何であったか投稿していませんでした。ここに私のsoulutionです。それはメモリにファイルを読み込む行目では、私は、BOMを削除するには奇妙な方法のようなものを見つけます:

byte[] bytes = File.ReadAllBytes(physicalPath);
String ss = new StreamReader(new MemoryStream(bytes), true).ReadToEnd();
byte[] b = StrToByteArray(ss);
return b;  

そして、あなたもこの機能が必要になります:

public static byte[] StrToByteArray(string str)
{
    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    return encoding.GetBytes(str);
} 

Nitech

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top