模块  java.base
软件包  java.nio.charset

Class CharsetDecoder


  • public abstract class CharsetDecoder
    extends Object
    一种引擎,可以将特定字符集中的字节序列转换为16位Unicode字符序列。

    输入字节序列在字节缓冲区或一系列这样的缓冲区中提供。 输出字符序列被写入字符缓冲区或一系列此类缓冲区。 应始终通过进行以下方法调用序列来使用解码器,以下称为解码操作

    1. 通过reset方法重置解码器,除非之前没有使用过;

    2. 只要有额外的输入可用,就调用decode方法零次或多次,为endOfInput参数传递false并填充输入缓冲区并在调用之间刷新输出缓冲区;

    3. 最后一次调用decode方法,为endOfInput参数传递true ; 然后

    4. 调用flush方法,以便解码器可以将任何内部状态刷新到输出缓冲区。

    每次调用decode方法都会从输入缓冲区中解码尽可能多的字节,并将结果字符写入输出缓冲区。 当需要更多输入,输出缓冲区中没有足够空间或发生解码错误时, decode方法返回。 在每种情况下, 都会返回CoderResult对象来描述终止的原因。 调用者可以检查此对象并填充输入缓冲区,刷新输出缓冲区,或尝试从解码错误中恢复,并再次尝试。

    有两种一般类型的解码错误。 如果输入字节序列对于此字符集不合法,则认为输入格式不正确 如果输入字节序列合法但无法映射到有效的Unicode字符,则会遇到不可映射的字符

    如何处理解码错误取决于为该类型的错误请求的操作,该操作由CodingErrorAction类的实例描述。 可能的错误操作是ignore错误输入, report通过返回的CoderResult对象向调用者发出错误,或replace错误输入与替换字符串的当前值。 更换的初始值为"\uFFFD" ; 其值可以通过replaceWith方法更改。

    malformed -input和unmappable-character错误的默认操作是report 可以通过onMalformedInput方法更改格式错误的输入错误操作; 可以通过onUnmappableCharacter方法更改不可映射的字符操作。

    此类旨在处理解码过程的许多细节,包括错误操作的实现。 用于特定字符集的解码器(该类的具体子类)仅需要实现抽象decodeLoop方法,该方法封装基本解码循环。 另外,维护内部状态的子类应该覆盖implFlushimplReset方法。

    多个并发线程使用此类的实例是不安全的。

    从以下版本开始:
    1.4
    另请参见:
    ByteBufferCharBufferCharsetCharsetEncoder
    • 构造方法详细信息

      • CharsetDecoder

        protected CharsetDecoder​(Charset cs,
                                 float averageCharsPerByte,
                                 float maxCharsPerByte)
        初始化一个新的解码器。 新的解码器将具有给定的每字节字符值,并且其替换将是字符串"\uFFFD"
        参数
        cs - 创建此解码器的charset
        averageCharsPerByte - 正浮点值,指示将为每个输入字节生成的预期字符数
        maxCharsPerByte - 正浮点值,指示将为每个输入字节生成的最大字符数
        异常
        IllegalArgumentException - 如果参数的前提条件不成立
    • 方法详细信息

      • charset

        public final Charset charset()
        返回创建此解码器的charset。
        结果
        这个解码器的字符集
      • replacement

        public final String replacement()
        返回此解码器的替换值。
        结果
        这个解码器的当前替换,永远不会是 null并且永远不会是空的
      • replaceWith

        public final CharsetDecoder replaceWith​(String newReplacement)
        更改此解码器的替换值。

        在检查新替换是否可接受之后,此方法调用implReplaceWith方法,传递新替换。

        参数
        newReplacement - 新的替代品; 不得为null ,必须具有非零长度,且不得长于maxCharsPerByte方法返回的值
        结果
        这个解码器
        异常
        IllegalArgumentException - 如果参数的前提条件不成立
      • implReplaceWith

        protected void implReplaceWith​(String newReplacement)
        报告此解码器替换值的更改。

        此方法的默认实现不执行任何操作。 解码器应该覆盖此方法,该解码器需要通知替换的更改。

        参数
        newReplacement - 替换值
      • malformedInputAction

        public CodingErrorAction malformedInputAction()
        返回此解码器对格式错误输入错误的当前操作。
        结果
        当前的畸形输入动作,永远不会是 null
      • implOnMalformedInput

        protected void implOnMalformedInput​(CodingErrorAction newAction)
        报告对此解码器的错误输入操作的更改。

        此方法的默认实现不执行任何操作。 解码器应该覆盖此方法,该解码器需要通知对格式错误的输入操作进行更改。

        参数
        newAction - 新动作
      • unmappableCharacterAction

        public CodingErrorAction unmappableCharacterAction()
        返回此解码器对不可映射字符错误的当前操作。
        结果
        当前不可映射的字符操作,永远不会是 null
      • implOnUnmappableCharacter

        protected void implOnUnmappableCharacter​(CodingErrorAction newAction)
        报告对此解码器的不可映射字符操作的更改。

        此方法的默认实现不执行任何操作。 解码器应该重写此方法,该解码器需要通知对不可映射字符操作的更改。

        参数
        newAction - 新动作
      • averageCharsPerByte

        public final float averageCharsPerByte()
        返回将为每个输入字节生成的平均字符数。 该启发式值可用于估计给定输入序列所需的输出缓冲器的大小。
        结果
        每个输入字节产生的平均字符数
      • maxCharsPerByte

        public final float maxCharsPerByte()
        返回将为每个输入字节生成的最大字符数。 该值可用于计算给定输入序列所需的输出缓冲器的最坏情况大小。
        结果
        每个输入字节将产生的最大字符数
      • decode

        public final CoderResult decode​(ByteBuffer in,
                                        CharBuffer out,
                                        boolean endOfInput)
        从给定的输入缓冲区中解码尽可能多的字节,将结果写入给定的输出缓冲区。

        从当前位置开始读取和写入缓冲区。 最多将读取in.remaining()个字节,最多将写入out.remaining()字符。 缓冲区的位置将被提前以反映读取的字节数和写入的字符数,但不会修改它们的标记和限制。

        除了从输入缓冲区读取字节并将字符写入输出缓冲区之外,此方法还返回CoderResult对象以描述其终止原因:

        • CoderResult.UNDERFLOW表示已解码尽可能多的输入缓冲区。 如果没有进一步的输入,则调用者可以继续进行decoding operation的下一步骤。 否则,应该使用进一步的输入再次调用此方法。

        • CoderResult.OVERFLOW表示输出缓冲区中没有足够的空间来解码更多字节。 应使用具有更多remaining字符的输出缓冲区再次调用此方法。 这通常通过从输出缓冲器中排出任何解码的字符来完成。

        • 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方法,也没有这种方法具有的值的 falseendOfInput参数,也不该方法具有的值的 trueendOfInput参数但是返回值表示不完整的解码操作
        CoderMalfunctionError - 如果decodeLoop方法的调用引发了意外异常
      • flush

        public final CoderResult flush​(CharBuffer out)
        刷新此解码器。

        一些解码器保持内部状态,并且一旦读取了整个输入序列,可能需要将一些最终字符写入输出缓冲器。

        任何其他输出都从其当前位置开始写入输出缓冲区。 最多将写入out.remaining()字符。 缓冲区的位置将适当提前,但不会修改其标记和限制。

        如果此方法成功完成,则返回CoderResult.UNDERFLOW 如果输出缓冲区中没有足够的空间,则返回CoderResult.OVERFLOW 如果发生这种情况,则必须再次调用此方法,并使用具有更多空间的输出缓冲区,以便完成当前的decoding operation

        如果此解码器已被刷新,则调用此方法无效。

        此方法调用implFlush方法来执行实际的刷新操作。

        参数
        out - 输出字符缓冲区
        结果
        编码器结果对象, CoderResult.UNDERFLOWCoderResult.OVERFLOW
        异常
        IllegalStateException -如果当前解码操作的前一步骤既不是的调用 flush方法也不三个参数的 decode具有的值的方法 trueendOfInput参数
      • reset

        public final CharsetDecoder reset()
        重置此解码器,清除任何内部状态。

        此方法重置与charset无关的状态,并调用implReset方法以执行任何特定于charset的重置操作。

        结果
        这个解码器
      • implReset

        protected void implReset()
        重置此解码器,清除任何特定于字符集的内部状态。

        此方法的默认实现不执行任何操作。 应该由维护内部状态的解码器覆盖此方法。

      • decodeLoop

        protected abstract CoderResult decodeLoop​(ByteBuffer in,
                                                  CharBuffer out)
        将一个或多个字节解码为一个或多个字符。

        此方法封装基本解码循环,解码尽可能多的字节,直到它用完输出,用完输出缓冲区中的空间或遇到解码错误。 此方法由decode方法调用,该方法处理结果解释和错误恢复。

        从当前位置开始读取和写入缓冲区。 最多将读取in.remaining()个字节,最多将写入out.remaining()字符。 缓冲区的位置将被提前以反映读取的字节数和写入的字符数,但不会修改它们的标记和限制。

        此方法返回CoderResult对象以描述其终止原因,方法与decode方法相同。 此方法的大多数实现将通过返回适当的结果对象来处理解码错误,以便通过decode方法进行解释。 优化的实现可以改为检查相关的错误操作并自己实现该操作。

        此方法的实现可以通过返回CoderResult.UNDERFLOW来执行任意前瞻,直到它收到足够的输入。

        参数
        in - 输入字节缓冲区
        out - 输出字符缓冲区
        结果
        描述终止原因的编码器结果对象
      • decode

        public final CharBuffer decode​(ByteBuffer in)
                                throws CharacterCodingException
        将单个输入字节缓冲区的剩余内容解码为新分配的字符缓冲区的便捷方法。

        这个方法实现了整个decoding operation ; 也就是说,它重置这个解码器,然后它解码给定字节缓冲区中的字节,最后它刷新这个解码器。 因此,如果解码操作已在进行中,则不应调用此方法。

        参数
        in - 输入字节缓冲区
        结果
        包含解码操作结果的新分配字符缓冲区。 缓冲区的位置将为零,其限制将遵循写入的最后一个字符。
        异常
        IllegalStateException - 如果解码操作已在进行中
        MalformedInputException - 如果从输入缓冲区的当前位置开始的字节序列对于此字符集不合法,并且当前格式错误的输入操作是 CodingErrorAction.REPORT
        UnmappableCharacterException - 如果从输入缓冲区当前位置开始的字节序列无法映射到等效字符序列,并且当前的不可映射字符操作是 CodingErrorAction.REPORT
        CharacterCodingException
      • isAutoDetecting

        public boolean isAutoDetecting()
        判断此解码器是否实现了自动检测字符集。

        此方法的默认实现始终返回false ; 它应该被自动检测解码器覆盖以返回true

        结果
        true当且仅当此解码器实现自动检测字符集时
      • isCharsetDetected

        public boolean isCharsetDetected()
        判断此解码器是否检测到字符集(可选操作)

        如果该解码器实现自动检测字符集,则在解码操作期间的单个点处,该方法可以开始返回true以指示在输入字节序列中已检测到特定字符集。 一旦发生这种情况,可以调用detectedCharset方法来检索检测到的字符集。

        该方法返回false并不意味着尚未解码任何字节。 一些自动检测解码器能够解码一些或甚至所有输入字节序列而无需固定在特定字符集上。

        此方法的默认实现始终抛出UnsupportedOperationException ; 一旦确定了输入字符集,它应该被自动检测解码器覆盖以返回true

        结果
        true当且仅当此解码器检测到特定字符集时
        异常
        UnsupportedOperationException - 如果此解码器未实现自动检测字符集
      • detectedCharset

        public Charset detectedCharset()
        检索此解码器检测到的字符集(可选操作)

        如果此解码器实现自动检测字符集,则此方法一旦检测到就会返回实际字符集。 在该点之后,该方法在当前解码操作的持续时间内返回相同的值。 如果尚未读取足够的输入字节来确定实际的字符集,则此方法将抛出IllegalStateException

        此方法的默认实现始终抛出UnsupportedOperationException ; 它应该被自动检测解码器覆盖以返回适当的值。

        结果
        此自动检测解码器检测到的字符集,如果字符集尚未确定, null
        异常
        IllegalStateException - 如果读取的字节数不足以确定字符集
        UnsupportedOperationException - 如果此解码器未实现自动检测字符集