模块 java.base

类 CharsetEncoder

java.lang.Object
java.nio.charset.CharsetEncoder

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

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

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

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

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

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

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

有两种一般类型的编码错误。如果输入字符序列不是合法的 16 位 Unicode 序列,则认为输入malformed.如果输入字符序列是合法的但不能映射到给定字符集中的有效字节序列,则不可映射的字符遇到过。

如何处理编码错误取决于为该类型错误请求的操作,这由 CodingErrorAction 类的实例描述。可能的错误操作是 忽略 错误输入, report 通过返回的 CoderResult 对象将错误发送给调用者,或 replace 错误输入与替换字节数组的当前值。替换初始设置为编码器的默认替换,通常(但不总是)具有初始值 { (byte)'?' } ;它的值可以通过replaceWith 方法改变。

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

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

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

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

    • CharsetEncoder

      protected CharsetEncoder(Charset  cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement)
      初始化一个新的编码器。新编码器将具有给定的每字符字节数和替换值。
      参数:
      cs - 创建此编码器的字符集
      averageBytesPerChar - 一个正浮点值,表示将为每个输入字符生成的预期字节数
      maxBytesPerChar - 一个正浮点值,表示将为每个输入字符生成的最大字节数
      replacement - 初始替换;不能是 null ,长度必须非零,不能长于 maxBytesPerChar,并且必须是 合法的
      抛出:
      IllegalArgumentException - 如果参数的先决条件不成立
    • CharsetEncoder

      protected CharsetEncoder(Charset  cs, float averageBytesPerChar, float maxBytesPerChar)
      初始化一个新的编码器。新编码器将具有给定的每字符字节值,其替换将是字节数组 { (byte)'?' }
      参数:
      cs - 创建此编码器的字符集
      averageBytesPerChar - 一个正浮点值,表示将为每个输入字符生成的预期字节数
      maxBytesPerChar - 一个正浮点值,表示将为每个输入字符生成的最大字节数
      抛出:
      IllegalArgumentException - 如果参数的先决条件不成立
  • 方法详情

    • charset

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

      public final byte[] replacement()
      返回此编码器的替换值。
      返回:
      此编码器的当前替换项,它永远不会是 null 并且永远不会为空
    • replaceWith

      public final CharsetEncoder  replaceWith(byte[] newReplacement)
      更改此编码器的替换值。

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

      参数:
      newReplacement - 新的替代品;不能是 null ,长度必须非零,不能长于 maxBytesPerChar 方法返回的值,并且必须是 legal
      返回:
      这个编码器
      抛出:
      IllegalArgumentException - 如果参数的前提条件不成立
    • implReplaceWith

      protected void implReplaceWith(byte[] newReplacement)
      报告此编码器替换值的更改。

      此方法的默认实现不执行任何操作。需要通知替换更改的编码器应重写此方法。

      参数:
      newReplacement - 重置值
    • isLegalReplacement

      public boolean isLegalReplacement(byte[] repl)
      告知给定字节数组是否是此编码器的合法替换值。

      当且仅当它是此编码器字符集中的合法字节序列时,替换才是合法的;也就是说,必须能够将替换解码为一个或多个 16 位 Unicode 字符。

      这个方法的默认实现不是很有效;通常应该重写它以提高性能。

      参数:
      repl - 要测试的字节数组
      返回:
      true 当且仅当给定字节数组是此编码器的合法替换值
    • malformedInputAction

      public CodingErrorAction  malformedInputAction()
      返回此编码器对格式错误的输入错误的当前操作。
      返回:
      当前格式错误的输入操作,永远不会是 null
    • onMalformedInput

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

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

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

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

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

      参数:
      newAction - 新动作
    • unmappableCharacterAction

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

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

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

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

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

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

      参数:
      newAction - 新动作
    • averageBytesPerChar

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

      public final float maxBytesPerChar()
      返回将为每个输入字符生成的最大字节数。该值可用于计算给定输入序列所需的输出缓冲区的最坏情况大小。该值考虑了任何必要的与内容无关的前缀或后缀字节,例如字节顺序标记。
      返回:
      每个输入字符将产生的最大字节数
    • encode

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

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

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

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

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

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

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

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

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

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

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

      public final CoderResult  flush(ByteBuffer  out)
      刷新此编码器。

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

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

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

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

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

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

      protected CoderResult  implFlush(ByteBuffer  out)
      刷新此编码器。

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

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

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

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

      返回:
      这个编码器
    • implReset

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

      此方法的默认实现不执行任何操作。此方法应由维护内部状态的编码器重写。

    • encodeLoop

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

      此方法封装了基本编码循环,对尽可能多的字符进行编码,直到用完输入、用完输出缓冲区中的空间或遇到编码错误。此方法由 encode 方法调用,该方法处理结果解释和错误恢复。

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

      此方法返回一个 CoderResult 对象来描述其终止原因,其方式与 encode 方法相同。此方法的大多数实现将通过返回适当的结果对象以供 encode 方法解释来处理编码错误。优化的实现可能会检查相关的错误操作并自己实现该操作。

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

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

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

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

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

      public boolean canEncode(char c)
      告知此编码器是否可以对给定字符进行编码。

      如果给定字符是代理字符,则此方法返回 false;只有当这些字符属于由高代理项和低代理项组成的一对中的成员时,才能解释这些字符。 canEncode(CharSequence) 方法可用于测试字符序列是否可以编码。

      此方法可能会修改此编码器的状态;因此,如果 编码操作 已经在进行中,则不应调用它。

      这个方法的默认实现不是很有效;通常应该重写它以提高性能。

      参数:
      c - 给定的字符
      返回:
      true 当且仅当此编码器可以编码给定字符
      抛出:
      IllegalStateException - 如果编码操作已经在进行中
    • canEncode

      public boolean canEncode(CharSequence  cs)
      告知此编码器是否可以对给定的字符序列进行编码。

      如果此方法针对特定字符序列返回 false,则可以通过执行完整的 编码操作 获得有关无法对序列进行编码的原因的更多信息。

      此方法可能会修改此编码器的状态;因此,如果编码操作已经在进行中,则不应调用它。

      这个方法的默认实现不是很有效;通常应该重写它以提高性能。

      参数:
      cs - 给定的字符序列
      返回:
      true 当且仅当此编码器可以在不抛出任何异常且不执行任何替换的情况下对给定字符进行编码
      抛出:
      IllegalStateException - 如果编码操作已经在进行中