检查字符是否可以使用特定编码进行编码

本文关键字:编码 字符 是否 可以使 检查 | 更新日期: 2023-09-27 17:58:33

我在这里问了一个问题,得到了答案,但把话题改向了另一个方向。这就是为什么我新提出这个问题。我的老问题是:文件编码;t工作

我的新问题是:如何检查字符串中的字符是否可以用特定的编码进行编码?我想知道是哪个字符在我的原始代码中造成了问题。我尝试了一种方法来回答我的老问题,但这只是产生了一个似乎没有意义的错误信息。

消息是,在大约10个字符的行中出现了"索引262处的错误"。

这就是代码:

string[] Lines = reactor.GetMergedLines();
string fileName = "foo.bar";
try 
{           
    Encoding encoding = Encoding.GetEncoding(28605, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
    for (int i = 0; i < Lines.Length; i++)
    {
        File.WriteAllLines(fileName, Lines, encoding);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

检查字符是否可以使用特定编码进行编码

不使用EncoderFallback.ExceptionFallback,而是可以使用EncoderFallback.ReplacementFallback并指定在不可映射字符的情况下使用的DefaultString

为了得到问题的答案,您可以滚动自己的EncoderFallback子类,该子类提供自己的EncoderFallbackBuffer。该缓冲区在处理字符编码时被赋予字符和位置。

这是一个快速而肮脏的实现。

class MyEncoderFallback: EncoderFallback
{
    public override int MaxCharCount { get { return 11; } }
    public override EncoderFallbackBuffer CreateFallbackBuffer()
    {
        return new MyEncoderFallbackBuffer();
    }
}
class MyEncoderFallbackBuffer: EncoderFallbackBuffer
{
    private List<char> _encoded = new List<char>();
    private int _nextIndex = 0;
    public override int Remaining { get { return _encoded.Count - _nextIndex; } }
    public override bool Fallback(char unknownChar, int index)
    {
        var encoded = String.Format("#{0:d4}:{1:x4}#", index, (int)unknownChar);
        _encoded.Clear();
        _encoded.AddRange(encoded.AsEnumerable());
        _nextIndex = 0;
        return true;
    }
    public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
    {
        return false;
    }
    public override char GetNextChar()
    {
        char next;
        if(_nextIndex < _encoded.Count)
        {
            next = _encoded[_nextIndex];
            _nextIndex += 1;
        }
        else 
        {
            next = default(char);
        }
        return next;
    }
    public override bool MovePrevious()
    {
        bool result;
        if(_nextIndex > 0)
        {
            _nextIndex -= 1;
            result = true;
        }
        else
        {
            result = false;
        }
        return result;
    }
    public override void Reset()
    {
        _encoded.Clear();
        _nextIndex = 0;     
    }
}

用以下内容替换encoding

Encoding encoding = Encoding.GetEncoding(28605, new MyEncoderFallback(), DecoderFallback.ExceptionFallback);

在我的测试中,"abcdおはようefgh"被编码为"abcd#0004:304a##005:306f##006:308##007:346#efgh"