获取 BinaryReader/Writer 的编码?
Get Encoding of BinaryReader/Writer?
.NET BinaryReader/BinaryWriter
classes 可以通过指定 Encoding
来构造,以用于 String
相关操作。
我正在使用扩展方法实现自定义字符串格式,但仍会以在实例化 BinaryReader/Writer
.
时尊重指定的 Encoding
的方式实现它们
似乎没有办法从 reader/writer 检索编码,即使从 class 继承时也是如此。我只能从他们那里继承来通过重新创建他们所有的构造函数来拦截传递的编码。我查看了 .NET source code,它仅用于实例化解码器 class(在 BinaryReader
的情况下),但我也无法访问该解码器。
我是不是输给了这里的class缺点?我可以通过反射侵入它们吗?
查看source code for BinaryReader,我看到构造函数定义如下:
public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
if (input==null) {
throw new ArgumentNullException("input");
}
if (encoding==null) {
throw new ArgumentNullException("encoding");
}
if (!input.CanRead)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
Contract.EndContractBlock();
m_stream = input;
m_decoder = encoding.GetDecoder();
m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
int minBufferSize = encoding.GetMaxByteCount(1); // max bytes per one char
if (minBufferSize < 16)
minBufferSize = 16;
m_buffer = new byte[minBufferSize];
// m_charBuffer and m_charBytes will be left null.
// For Encodings that always use 2 bytes per char (or more),
// special case them here to make Read() & Peek() faster.
m_2BytesPerChar = encoding is UnicodeEncoding;
// check if BinaryReader is based on MemoryStream, and keep this for it's life
// we cannot use "as" operator, since derived classes are not allowed
m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
m_leaveOpen = leaveOpen;
Contract.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
}
所以看起来编码本身实际上并没有保留在任何地方。 class 仅存储从编码派生的解码器。 m_decoder
在class中定义如下:
private Decoder m_decoder;
您无法访问私有变量。在 class 的其余部分搜索该变量显示它在内部的几个地方使用,但从未返回,所以我认为你不能在派生 class 的任何地方访问它而不做某种疯狂的 reflection/disassembly 事情。必须将其定义为 protected
才能访问它。对不起。
编辑:
几乎肯定有比使用反射访问私有 m_decoder
变量更好的方法来解决您的问题。即使您这样做了,它也可能无法为您提供编码,正如您在评论中指出的那样。但是,如果您仍然想这样做,请参阅 this Whosebug answer on how to access private members with reflection。
如果在构造函数中子class编码和拦截编码在你的场景中甚至是远程可行的,我更喜欢它而不是潜在的不稳定的反射黑客。
但是,如果您必须出于某种原因走反思路线,这里有一些我从the BinaryReader source code you referenced:
中找到的建议
-
Decoder
class 本身显然不包含对 Encoding
的任何引用,但是:
Decoder
实例是通过调用 encoding.GetDecoder()
(第 65 行) 创建的
- 哪个returns an instance of an internal class
DefaultDecoder
- does hold the
Encoding
m_encoding
.NET BinaryReader/BinaryWriter
classes 可以通过指定 Encoding
来构造,以用于 String
相关操作。
我正在使用扩展方法实现自定义字符串格式,但仍会以在实例化 BinaryReader/Writer
.
Encoding
的方式实现它们
似乎没有办法从 reader/writer 检索编码,即使从 class 继承时也是如此。我只能从他们那里继承来通过重新创建他们所有的构造函数来拦截传递的编码。我查看了 .NET source code,它仅用于实例化解码器 class(在 BinaryReader
的情况下),但我也无法访问该解码器。
我是不是输给了这里的class缺点?我可以通过反射侵入它们吗?
查看source code for BinaryReader,我看到构造函数定义如下:
public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
if (input==null) {
throw new ArgumentNullException("input");
}
if (encoding==null) {
throw new ArgumentNullException("encoding");
}
if (!input.CanRead)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
Contract.EndContractBlock();
m_stream = input;
m_decoder = encoding.GetDecoder();
m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
int minBufferSize = encoding.GetMaxByteCount(1); // max bytes per one char
if (minBufferSize < 16)
minBufferSize = 16;
m_buffer = new byte[minBufferSize];
// m_charBuffer and m_charBytes will be left null.
// For Encodings that always use 2 bytes per char (or more),
// special case them here to make Read() & Peek() faster.
m_2BytesPerChar = encoding is UnicodeEncoding;
// check if BinaryReader is based on MemoryStream, and keep this for it's life
// we cannot use "as" operator, since derived classes are not allowed
m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
m_leaveOpen = leaveOpen;
Contract.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
}
所以看起来编码本身实际上并没有保留在任何地方。 class 仅存储从编码派生的解码器。 m_decoder
在class中定义如下:
private Decoder m_decoder;
您无法访问私有变量。在 class 的其余部分搜索该变量显示它在内部的几个地方使用,但从未返回,所以我认为你不能在派生 class 的任何地方访问它而不做某种疯狂的 reflection/disassembly 事情。必须将其定义为 protected
才能访问它。对不起。
编辑:
几乎肯定有比使用反射访问私有 m_decoder
变量更好的方法来解决您的问题。即使您这样做了,它也可能无法为您提供编码,正如您在评论中指出的那样。但是,如果您仍然想这样做,请参阅 this Whosebug answer on how to access private members with reflection。
如果在构造函数中子class编码和拦截编码在你的场景中甚至是远程可行的,我更喜欢它而不是潜在的不稳定的反射黑客。
但是,如果您必须出于某种原因走反思路线,这里有一些我从the BinaryReader source code you referenced:
中找到的建议-
Decoder
class 本身显然不包含对Encoding
的任何引用,但是: Decoder
实例是通过调用encoding.GetDecoder()
(第 65 行) 创建的
- 哪个returns an instance of an internal class
DefaultDecoder
- does hold the
Encoding
m_encoding