public abstract class CharsetDecoder extends Object
输入字节序列被提供在一个字节缓冲器或一系列这样的缓冲器中。 输出字符序列被写入字符缓冲区或一系列这样的缓冲区。 应通过下列方法调用顺序来始终使用解码器,以下称为解码操作 :
通过reset
方法复位解码器,除非以前没有使用过;
调用decode
方法零次或更多次,只要附加输入可用,通过false为endOfInput参数,填充输入缓冲区并在调用之间刷新输出缓冲区;
最后一次调用decode
方法,通过true的endOfInput论证; 接着
调用flush
方法,使解码器可以将任何内部状态刷新到输出缓冲区。
decode
方法的每次调用都会从输入缓冲区解码尽可能多的字节,将生成的字符写入输出缓冲区。
当需要更多输入时,输出缓冲区中没有足够的空间,或者发生解码错误时, decode
方法返回。
在每种情况下,返回一个CoderResult
对象来描述终止的原因。
调用者可以检查此对象并填写输入缓冲区,刷新输出缓冲区,或尝试从解码错误中恢复,并重试。
有两种一般类型的解码错误。 如果输入字节序列对于此字符集不合法,那么输入被认为是格式错误的 。 如果输入字节序列是合法的,但不能映射到有效的Unicode字符,则遇到不可映射的字符。
如何处理解码错误取决于为该类型的错误所请求的操作,由CodingErrorAction
类的实例描述 。 可能的错误动作是ignore错误的输入, report的错误通过返回的CoderResult
对象给调用者,或replace的错误输入与替换字符串的当前值。 替换的初始值为"\uFFFD" ; 其值可以通过replaceWith
方法更改。
对格式错误的输入和不可映射的字符错误的默认操作是它们的report 。 畸形输入错误动作可以通过onMalformedInput
方法更改; 可以通过onUnmappableCharacter
方法更改不可映射字符动作。
该类旨在处理解码过程的许多细节,包括执行错误操作。 特定字符集的解码器是该类的具体子类,仅需实现封装基本解码循环的抽象decodeLoop
方法。 维护内部状态的子类应另外覆盖implFlush
和implReset
方法。
此类的实例不能安全地被多个并发线程使用。
ByteBuffer
, CharBuffer
, Charset
, CharsetEncoder
Modifier | Constructor and Description |
---|---|
protected |
CharsetDecoder(Charset cs, float averageCharsPerByte, float maxCharsPerByte)
初始化一个新的解码器。
|
Modifier and Type | Method and Description |
---|---|
float |
averageCharsPerByte()
返回每个字节输入的平均字符数。
|
Charset |
charset()
返回创建此解码器的字符集。
|
CharBuffer |
decode(ByteBuffer in)
将单个输入字节缓冲器的剩余内容解码为新分配的字符缓冲区的方便方法。
|
CoderResult |
decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
从给定的输入缓冲区解码尽可能多的字节,将结果写入给定的输出缓冲区。
|
protected abstract CoderResult |
decodeLoop(ByteBuffer in, CharBuffer out)
将一个或多个字节解码为一个或多个字符。
|
Charset |
detectedCharset()
检索该解码器检测到的字符集
(可选操作) 。
|
CoderResult |
flush(CharBuffer out)
刷新此解码器。
|
protected CoderResult |
implFlush(CharBuffer out)
刷新此解码器。
|
protected void |
implOnMalformedInput(CodingErrorAction newAction)
报告对此解码器的格式错误的输入操作的更改。
|
protected void |
implOnUnmappableCharacter(CodingErrorAction newAction)
报告该解码器的不可映射角色动作的变化。
|
protected void |
implReplaceWith(String newReplacement)
报告对该解码器的替换值的更改。
|
protected void |
implReset()
重置此解码器,清除特定于字符集的内部状态。
|
boolean |
isAutoDetecting()
告知该解码器是否实现自动检测字符集。
|
boolean |
isCharsetDetected()
告知该解码器是否还检测到字符集
(可选操作) 。
|
CodingErrorAction |
malformedInputAction()
返回此解码器当前的格式输入错误的操作。
|
float |
maxCharsPerByte()
返回每个字节输入的最大字符数。
|
CharsetDecoder |
onMalformedInput(CodingErrorAction newAction)
更改此解码器的错误格式输入错误的操作。
|
CharsetDecoder |
onUnmappableCharacter(CodingErrorAction newAction)
更改此解码器的操作为不可映射的字符错误。
|
String |
replacement()
返回此解码器的替换值。
|
CharsetDecoder |
replaceWith(String newReplacement)
更改此解码器的替换值。
|
CharsetDecoder |
reset()
复位该解码器,清除任何内部状态。
|
CodingErrorAction |
unmappableCharacterAction()
返回此解码器当前的不可映射字符错误的操作。
|
protected CharsetDecoder(Charset cs, float averageCharsPerByte, float maxCharsPerByte)
cs
- 创建此解码器的字符集
averageCharsPerByte
- 一个正的浮点值,表示将为每个输入字节产生的预期字符数
maxCharsPerByte
- 一个正值,表示将为每个输入字节产生的最大字符数
IllegalArgumentException
- 如果参数的前提条件不成立
public final Charset charset()
public final String replacement()
public final CharsetDecoder replaceWith(String newReplacement)
此方法调用implReplaceWith
方法,通过新的替换,检查新的替换是否可以接受。
newReplacement
- 替换值新替换;
不能为null ,且必须具有非零长度
IllegalArgumentException
- 如果参数的前提条件不成立
protected void implReplaceWith(String newReplacement)
这种方法的默认实现什么都不做。 这个方法应该被需要通知更换更改的解码器所覆盖。
newReplacement
- 替换值
public CodingErrorAction malformedInputAction()
public final CharsetDecoder onMalformedInput(CodingErrorAction newAction)
此方法调用implOnMalformedInput
方法,传递新的动作。
newAction
- 新动作
不能是null
IllegalArgumentException
- 如果参数的前提条件不成立
protected void implOnMalformedInput(CodingErrorAction newAction)
这种方法的默认实现什么都不做。 应该通过需要通知变更输入错误的操作的解码器覆盖此方法。
newAction
- 新的动作
public CodingErrorAction unmappableCharacterAction()
public final CharsetDecoder onUnmappableCharacter(CodingErrorAction newAction)
此方法调用implOnUnmappableCharacter
方法,传递新的动作。
newAction
- 新动作
不能是null
IllegalArgumentException
- 如果参数的前提条件不成立
protected void implOnUnmappableCharacter(CodingErrorAction newAction)
这种方法的默认实现什么都不做。 应该通过需要通知不可映射角色动作更改的解码器覆盖此方法。
newAction
- 新的动作
public final float averageCharsPerByte()
public final float maxCharsPerByte()
public final CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
缓冲区从其当前位置开始读取并写入。 将最多读取in.remaining()
个字节,最多写入out.remaining()
个字符。 缓冲区的位置将被提前以反映读取的字节和写入的字符,但是它们的标记和限制将不被修改。
除了从输入缓冲区读取字节并将字符写入输出缓冲区之外,此方法返回一个CoderResult
对象来描述其终止原因:
CoderResult.UNDERFLOW
表示尽可能多的输入缓冲器被解码。 如果没有进一步的输入,那么调用者可以进行到decoding operation的下一步 。 否则,此方法应再次调用再输入。
CoderResult.OVERFLOW
表示输出缓冲区中没有足够的空间来解码任何更多的字节。 应该使用具有更多remaining个字符的输出缓冲区再次调用此方法。 这通常通过从输出缓冲器中排出任何解码的字符来完成。
A malformed-input结果表示已检测到错误输入错误。 格式错误的字节从输入缓冲区(可能递增)的位置开始; 可以通过调用结果对象的length
方法来确定格式错误的字节数。 这种情况只适用于当malformed action此解码器是CodingErrorAction.REPORT
; 否则,将根据要求忽略或替换格式错误的输入。
unmappable-character结果表示检测到不匹配的字符错误。 解码不可映射字符的字节从输入缓冲区(可能递增)的位置开始; 可以通过调用结果对象的length
方法来确定这样的字节的数量。 这种情况只适用于当unmappable action此解码器是CodingErrorAction.REPORT
; 否则不可映射的字符将被忽略或替换,根据要求。
endOfInput参数建议使用此方法来确定调用者是否可以提供超出给定输入缓冲区中的输入。 如果提供附加输入的可能性,则调用应该传递false为此参数; 如果不可能提供进一步的输入,那么调用者应该通过true 。 这并不是错误的,实际上很常见的是在一次调用中传递false,后来发现没有进一步的输入实际上可用。 然而,至关重要的是,以一系列调用方式最终调用此方法总是通过true ,以便任何剩余的未解码输入将被视为格式错误。
此方法通过调用decodeLoop
方法,解释其结果,处理错误条件以及根据需要重新启动。
in
- 输入字节缓冲区
out
- 输出字符缓冲区
endOfInput
-
true如果且仅当调用者不能提供除了给定缓冲区之外的额外输入字节
IllegalStateException
-如果解码操作已在进行中和之前的步骤是一个调用既不的
reset
方法,也没有该方法与用于
endOfInput参数a的
false值,也没有该方法与用于
endOfInput参数a的
true值的而是指示不完整的解码操作的返回值
CoderMalfunctionError
- 如果对decodeLoop方法的调用会引发意外的异常
public final CoderResult flush(CharBuffer out)
一些解码器保持内部状态,并且可能需要在读取总体输入序列后将一些最终字符写入输出缓冲区。
任何额外的输出从其当前位置开始写入输出缓冲区。 将写入最多out.remaining()
个字符。 缓冲区的位置将适当地提前,但其标记和限制将不会被修改。
如果此方法成功完成,则返回CoderResult.UNDERFLOW
。 如果输出缓冲区的空间不足,则返回CoderResult.OVERFLOW
。 如果发生这种情况,则必须再次调用此方法,输出缓冲区有更多的空间,以便完成当前的decoding operation 。
如果该解码器已被刷新,则调用此方法没有任何作用。
此方法调用implFlush
方法来执行实际的刷新操作。
out
- 输出字符缓冲区
CoderResult.UNDERFLOW
或
CoderResult.OVERFLOW
IllegalStateException
-如果当前解码操作的前一步骤是的调用既不
flush
方法也不三个参数的
decode
方法与用于
endOfInput参数a的值
true
protected CoderResult implFlush(CharBuffer out)
这个方法的默认实现什么都不做,总是返回CoderResult.UNDERFLOW
。 一旦读取了整个输入序列,这个方法就应该被解码器所覆盖。
out
- 输出字符缓冲区
CoderResult.UNDERFLOW
或
CoderResult.OVERFLOW
public final CharsetDecoder reset()
此方法重置与字符集无关的状态,并且还调用implReset
方法以执行任何特定于字符集的重置操作。
protected void implReset()
这种方法的默认实现什么都不做。 该方法应由维护内部状态的解码器覆盖。
protected abstract CoderResult decodeLoop(ByteBuffer in, CharBuffer out)
该方法封装了基本的解码循环,解码尽可能多的字节,直到其用完输出,在输出缓冲区中用完,或遇到解码错误。 该方法由decode
方法调用,处理结果解释和错误恢复。
缓冲区从其当前位置开始读取并写入。 将最多读取in.remaining()
个字节,最多写入out.remaining()
个字符。 缓冲区的位置将被提前以反映读取的字节和写入的字符,但是它们的标记和限制将不被修改。
该方法返回一个CoderResult
对象来描述其终止原因,与decode
方法相同。 该方法的大多数实现由返回合适的结果对象用于解释处理解码错误decode
方法。 优化的实现可能会检查相关的错误操作,并实现该操作本身。
这种方法的实施方案可以通过返回执行任意的先行CoderResult.UNDERFLOW
直到它接收到足够的输入。
in
- 输入字节缓冲区
out
- 输出字符缓冲区
public final CharBuffer decode(ByteBuffer in) throws CharacterCodingException
该方法实现整个decoding operation ; 也就是说,它复位该解码器,然后解码给定字节缓冲器中的字节,最后它刷新该解码器。 因此,如果解码操作已经进行,则不应该调用此方法。
in
- 输入字节缓冲
IllegalStateException
- 如果解码操作已经进行中
MalformedInputException
- 如果从输入缓冲区的当前位置开始的字节序列对于此字符集不合法,并且当前格式错误的输入操作是
CodingErrorAction.REPORT
UnmappableCharacterException
- 如果从输入缓冲区的当前位置开始的字节序列不能映射到等效的字符序列,并且当前的不可映像字符操作是
CodingErrorAction.REPORT
CharacterCodingException
public boolean isAutoDetecting()
此方法的默认实现始终返回false ; 它应该被自动检测解码器覆盖,以返回true 。
public boolean isCharsetDetected()
如果该解码器在解码操作期间在单个点实现自动检测字符集,则该方法可以开始返回true以指示在输入字节序列中检测到特定字符集。 一旦发生这种情况,可以调用detectedCharset
方法来检索检测到的字符集。
该方法返回false并不意味着没有字节尚未解码。 一些自动检测解码器能够解码输入字节序列的一些或甚至全部,而不固定在特定字符集上。
这种方法的默认实现总是抛出一个UnsupportedOperationException
; 输入字符集确定后,自动检测解码器将被覆盖返回true。
UnsupportedOperationException
- 如果该解码器没有实现自动检测字符集
public Charset detectedCharset()
如果该解码器实现了自动检测字符集,则该方法一旦检测到该字符集即返回实际的字符集。 此后,该方法在当前解码操作的持续时间内返回相同的值。 如果还没有足够的输入字节读取来确定实际的字符集,那么这个方法会抛出一个IllegalStateException
。
这种方法的默认实现总是抛出一个UnsupportedOperationException
; 应该通过自动检测解码器来覆盖,以返回适当的值。
IllegalStateException
- 如果读取不足够的字节来确定字符集
UnsupportedOperationException
- 如果该解码器不实现自动检测字符集