模块 java.base

类 CharsetDecoder

java.lang.Object
java.nio.charset.CharsetDecoder

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

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

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

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

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

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

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

有两种一般类型的解码错误。如果输入字节序列对该字符集不合法,则认为输入malformed.如果输入字节序列是合法的但不能映射到有效的 Unicode 字符,那么一个不可映射的字符遇到过。

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

对于格式错误的输入和不可映射的字符错误的默认操作是 report 它们。可以通过 onMalformedInput 方法更改格式错误的输入错误操作;无法映射的字符操作可以通过onUnmappableCharacter 方法更改。

此类旨在处理解码过程的许多细节,包括错误操作的实现。特定字符集的解码器是此类的具体子类,只需实现抽象的 decodeLoop 方法,该方法封装了基本的解码循环。维护内部状态的子类还应该覆盖 implFlush implReset 方法。

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

自从:
1.4
参见:
  • 构造方法详细信息

    • CharsetDecoder

      protected CharsetDecoder(Charset  cs, float averageCharsPerByte, float maxCharsPerByte)
      初始化一个新的解码器。新解码器将具有给定的每字节字符数值,其替换将是字符串 "\uFFFD"
      参数:
      cs - 创建此解码器的字符集
      averageCharsPerByte - 一个正浮点值,表示将为每个输入字节生成的预期字符数
      maxCharsPerByte - 一个正浮点值,表示将为每个输入字节生成的最大字符数
      抛出:
      IllegalArgumentException - 如果参数的先决条件不成立
  • 方法详情

    • charset

      public final 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
    • onMalformedInput

      public final CharsetDecoder  onMalformedInput(CodingErrorAction  newAction)
      更改此解码器对格式错误的输入错误的操作。

      此方法调用 implOnMalformedInput 方法,传递新操作。

      参数:
      newAction - 新动作;不能是null
      返回:
      这个解码器
      抛出:
      IllegalArgumentException - 如果参数的前提条件不成立
    • implOnMalformedInput

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

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

      参数:
      newAction - 新动作
    • unmappableCharacterAction

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

      public final CharsetDecoder  onUnmappableCharacter(CodingErrorAction  newAction)
      更改此解码器对不可映射字符错误的操作。

      此方法调用 implOnUnmappableCharacter 方法,传递新操作。

      参数:
      newAction - 新动作;不能是null
      返回:
      这个解码器
      抛出:
      IllegalArgumentException - 如果参数的前提条件不成立
    • 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 表示已解码尽可能多的输入缓冲区。如果没有进一步的输入,那么调用者可以继续执行 解码操作 的下一步。否则,应使用进一步的输入再次调用此方法。

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

      • 输入格式错误 结果表示检测到格式错误的输入错误。格式错误的字节从输入缓冲区的(可能递增的)位置开始;可以通过调用结果对象的 length 方法来确定格式错误的字节数。这种情况仅适用于此解码器的 畸形动作CodingErrorAction.REPORT ;否则,将根据要求忽略或替换格式错误的输入。

      • 不可映射的字符 结果表示检测到不可映射字符错误。解码不可映射字符的字节从输入缓冲区的(可能递增的)位置开始;此类字节的数量可以通过调用结果对象的 length 方法来确定。这种情况仅适用于此解码器的 无法映射的动作CodingErrorAction.REPORT ;否则,根据要求,不可映射的字符将被忽略或替换。

      在任何情况下,如果要在同一解码操作中重新调用此方法,则应注意保留输入缓冲区中剩余的任何字节,以便它们可用于下一次调用。

      endOfInput 参数建议此方法调用程序是否可以提供超出给定输入缓冲区中包含的输入的进一步输入。如果有可能提供额外的输入,那么调用者应该为这个参数传递false;如果不可能提供进一步的输入,那么调用者应该传递 true 。在一次调用中传递 false 并随后发现实际上没有进一步的输入可用,这并没有错,事实上这是很常见的。然而,至关重要的是,调用序列中此方法的最后一次调用始终传递 true,以便任何剩余的未解码输入都将被视为格式错误。

      此方法通过调用 decodeLoop 方法、解释其结果、处理错误情况并在必要时重新调用它来工作。

      参数:
      in - 输入字节缓冲区
      out - 输出字符缓冲区
      endOfInput - true 当且仅当调用程序不能提供超出给定缓冲区中的额外输入字节时
      返回:
      描述终止原因的编码器结果对象
      抛出:
      IllegalStateException - 如果解码操作已经在进行中,并且上一步既不是调用 reset 方法,也不是调用 endOfInput 参数值为 false 的方法,也不是调用 endOfInput 参数值为 true 的方法但返回值表示解码操作不完整
      CoderMalfunctionError - 如果 decodeLoop 方法的调用抛出意外异常
    • flush

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

      一些解码器维护内部状态,一旦整个输入序列被读取,可能需要将一些最终字符写入输出缓冲区。

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

      如果此方法成功完成,则返回 CoderResult.UNDERFLOW 。如果输出缓冲区空间不足,则返回 CoderResult.OVERFLOW 。如果发生这种情况,则必须使用具有更多空间的输出缓冲区再次调用此方法,以完成当前的 解码操作

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

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

      参数:
      out - 输出字符缓冲区
      返回:
      编码器结果对象,CoderResult.UNDERFLOW CoderResult.OVERFLOW
      抛出:
      IllegalStateException - 如果当前解码操作的前一步既不是 flush 方法的调用,也不是 endOfInput 参数的值为 true 的三参数 decode 方法的调用
    • implFlush

      protected CoderResult  implFlush(CharBuffer  out)
      刷新此解码器。

      此方法的默认实现不执行任何操作,并且始终返回 CoderResult.UNDERFLOW 。一旦读取了整个输入序列,可能需要将最终字符写入输出缓冲区的解码器应该覆盖此方法。

      参数:
      out - 输出字符缓冲区
      返回:
      编码器结果对象,CoderResult.UNDERFLOW CoderResult.OVERFLOW
    • reset

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

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

      返回:
      这个解码器
    • 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
      将单个输入字节缓冲区的剩余内容解码为新分配的字符缓冲区的便捷方法。

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

      参数:
      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 - 如果此解码器未实现自动检测字符集