C# ???附加到每个文件开头的字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/466653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
??? characters appended to the beginning of each file
提问by IEnumerator
I've downloaded an HttpHandler class that concatenates JS files into one file and it keeps appending the ???
characters at the start of each file it concatenates.
我下载了一个 HttpHandler 类,该类将 JS 文件连接到一个文件中,并且它一直???
在它连接的每个文件的开头附加字符。
Any ideas on what is causing this? Could it be that onces the files processed they are written to the cache and that's how the cache is storing/rendering it?
关于是什么导致这种情况的任何想法?可能是一旦处理过的文件被写入缓存,这就是缓存存储/渲染它的方式吗?
Any inputs would be greatly appreciated.
任何输入将不胜感激。
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; }
}
}
采纳答案by DreamSonic
OK, I've debugged your code.
好的,我已经调试了你的代码。
BOM marks appear in the source stream when the files are being read from the disk:
当从磁盘读取文件时,BOM 标记出现在源流中:
byte[] bytes = File.ReadAllBytes(physicalPath);
// TODO: Convert unicode files to specified encoding. For now, assuming
// files are either ASCII or UTF8
If you read the files properly, you can get rid of the marks.
如果您正确阅读文件,则可以消除标记。
回答by Stefan
The ??? characters are the UTF BOM markers.
这 ???字符是UTF BOM 标记。
回答by M4N
I think this is the Byte Order Mark (BOM)for files with UTF-8 encoding. This mark allows to determine in what encoding the file is stored.
我认为这是UTF-8 编码文件的字节顺序标记 (BOM)。此标记允许确定文件以何种编码存储。
回答by Greg
Its the UTF Byte Order Mark (BOM).
它是 UTF字节顺序标记 (BOM)。
It will be at the start of each file, but your editor will ignore them there. When concatenated they end up in the middle, so you see them.
它将在每个文件的开头,但您的编辑器会在那里忽略它们。连接后,它们最终位于中间,因此您可以看到它们。
回答by Boris Pavlovi?
Check how your js files are encoded and provide the same encoding in the code which does the reading and concatenation. These two characters usually point to unicode.
检查您的 js 文件是如何编码的,并在执行读取和连接的代码中提供相同的编码。这两个字符通常指向 unicode。
回答by DreamSonic
Those characters are UTF-8 BOM. It doesn't seem like they're coming from the gzipped stream. It's more likely they are inserted to the response stream, so I would suggest clearing the response before working with it:
这些字符是 UTF-8 BOM。它们似乎不是来自 gzip 压缩流。它们更有可能被插入到响应流中,所以我建议在使用它之前清除响应:
context.Response.Clear();
回答by nitech
You didn't post what the actual solution was. Here's my soulution. On the line where it reads the file into memory, I found a kind of strange way to remove the BOM:
您没有发布实际解决方案是什么。这是我的灵魂。在它把文件读入内存的那一行,我发现了一种移除BOM的奇怪方法:
byte[] bytes = File.ReadAllBytes(physicalPath);
String ss = new StreamReader(new MemoryStream(bytes), true).ReadToEnd();
byte[] b = StrToByteArray(ss);
return b;
And you also need this function:
你还需要这个功能:
public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
Nitech
尼泰克
回答by Broam
If you have the file's contents in a string, .Trim() will lop off the "BOM" quite handily.
如果您将文件内容放在一个字符串中,.Trim() 将非常方便地删除“BOM”。
You may not be able to do that, or you may wantthe whitespace at the ends of the file, but it's certainly an option.
您可能无法这样做,或者您可能想要文件末尾的空格,但这当然是一种选择。
For .js whitespace isn't significant, so this could work.
对于 .js 空白并不重要,所以这可以工作。