2

エンコーディングがあるとします:

Encoding enc;

このエンコーディングが渡されると、BOM を発行するように設定されます。私は BOM には興味がありません。私のシステムのエンコーディングはヘッダーで処理されます。

エンコーディングが不変であると仮定すると... 既存のエンコーディングと完全に一致する新しいエンコーディングを作成したいのですが、BOM を発行しなくなります。

これは、次の不一致を回避できるようにするためです。

var data = "áéíóúñ";
var enc = Encoding.UTF8;
long count1 = (long) enc.GetByteCount(data);
long count2;
using(var ms = new MemoryStream())
using(var sw = new StreamWriter(ms, enc))
{
    sw.Write(data);
    sw.Flush();
    count2 = ms.Length;
}
count1.Dump(); //12
count2.Dump(); //15 , oops... BOM was also written
4

2 に答える 2

4
var enc = UTF8Encoding(false); // UTF-8 without BOM

事前にエンコーディングがわからない場合は、少し追加のロジックが必要です。

switch(enc.CodePage) {
case 65001:
    enc = UTF8Encoding(false);
    break;
case 1200:
    enc = UnicodeEncoding(false, false);
    break;
case 1201:
    enc = UnicodeEncoding(true, false);
    break;
case 12000:
    enc = UTF32Encoding(false, false);
    break;
case 12001:
    enc = UTF32Encoding(true, false);
    break;
default:
    // pass through the original enc unchanged
}
于 2013-01-09T11:19:18.587 に答える
1

@leppie のコメントによると、R# は BOM を抑制するラッパーを作成するのに役立ちました...誰かがこれが良い考えだと思う場合に備えて、ここで再現します... @ChristianHayter が明らかにより単純な (そして明らかに) 完全な回答を作成したことを考えると、代わりにそれを使用することをお勧めします。

public class EncodingWrapper : Encoding
{
    private readonly Encoding innerEncoding;
    private readonly bool suppressPreamble;
    private static readonly byte[] EmptyBuffer = new byte[0];

    public EncodingWrapper(Encoding innerEncoding, bool suppressPreamble)
    {
        this.innerEncoding = innerEncoding;
        this.suppressPreamble = suppressPreamble;
    }

    public override byte[] GetPreamble()
    {
        return suppressPreamble ? EmptyBuffer : innerEncoding.GetPreamble();
    }

    public override int CodePage
    {
        get { return innerEncoding.CodePage; }
    }
    public override bool IsSingleByte
    {
        get { return innerEncoding.IsSingleByte; }
    }

    public override bool IsMailNewsSave
    {
        get { return innerEncoding.IsMailNewsSave; }
    }

    public override bool IsMailNewsDisplay
    {
        get { return innerEncoding.IsMailNewsDisplay; }
    }

    public override bool IsBrowserSave
    {
        get { return innerEncoding.IsBrowserSave; }
    }

    public override bool IsBrowserDisplay
    {
        get { return innerEncoding.IsBrowserDisplay; }
    }

    public override int WindowsCodePage
    {
        get { return innerEncoding.WindowsCodePage; }
    }

    public override string WebName
    {
        get { return innerEncoding.WebName; }
    }

    public override string HeaderName
    {
        get { return innerEncoding.HeaderName; }
    }

    public override string EncodingName
    {
        get { return innerEncoding.EncodingName; }
    }

    public override string BodyName
    {
        get { return innerEncoding.BodyName; }
    }

    public override string GetString(byte[] bytes, int index, int count)
    {
        return innerEncoding.GetString(bytes, index, count);
    }

    public override string GetString(byte[] bytes)
    {
        return innerEncoding.GetString(bytes);
    }

    public override int GetMaxCharCount(int byteCount)
    {
        return innerEncoding.GetMaxCharCount(byteCount);
    }

    public override int GetMaxByteCount(int charCount)
    {
        return innerEncoding.GetMaxByteCount(charCount);
    }

    public override Encoder GetEncoder()
    {
        return innerEncoding.GetEncoder();
    }

    public override Decoder GetDecoder()
    {
        return innerEncoding.GetDecoder();
    }

    public override bool IsAlwaysNormalized(NormalizationForm form)
    {
        return innerEncoding.IsAlwaysNormalized(form);
    }


    //public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
    //{
    //    return innerEncoding.GetChars(bytes, byteCount, chars, charCount);
    //}

    public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
    {
        return innerEncoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex);
    }

    public override char[] GetChars(byte[] bytes, int index, int count)
    {
        return innerEncoding.GetChars(bytes, index, count);
    }

    public override char[] GetChars(byte[] bytes)
    {
        return innerEncoding.GetChars(bytes);
    }

    //public override int GetCharCount(byte* bytes, int count)
    //{
    //    return innerEncoding.GetCharCount(bytes, count);
    //}

    public override object Clone()
    {
        return new EncodingWrapper((Encoding)innerEncoding.Clone(), suppressPreamble);
    }

    public override int GetByteCount(string s)
    {
        return innerEncoding.GetByteCount(s);
    }

    public override int GetByteCount(char[] chars)
    {
        return innerEncoding.GetByteCount(chars);
    }

    public override int GetByteCount(char[] chars, int index, int count)
    {
        return innerEncoding.GetByteCount(chars, index, count);
    }

    //public override int GetByteCount(char* chars, int count)
    //{
    //    return innerEncoding.GetByteCount(chars, count);
    //}

    public override byte[] GetBytes(char[] chars)
    {
        return innerEncoding.GetBytes(chars);
    }

    public override byte[] GetBytes(char[] chars, int index, int count)
    {
        return innerEncoding.GetBytes(chars, index, count);
    }

    public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
    {
        return innerEncoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
    }

    public override byte[] GetBytes(string s)
    {
        return innerEncoding.GetBytes(s);
    }

    public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
    {
        return innerEncoding.GetBytes(s, charIndex, charCount, bytes, byteIndex);
    }

    //public override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
    //{
    //    return innerEncoding.GetBytes(chars, charCount, bytes, byteCount);
    //}

    public override int GetCharCount(byte[] bytes)
    {
        return innerEncoding.GetCharCount(bytes);
    }

    public override int GetCharCount(byte[] bytes, int index, int count)
    {
        return innerEncoding.GetCharCount(bytes, index, count);
    }
}
于 2013-01-09T12:13:55.417 に答える