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