JavaTM Platform
Standard Ed. 6

java.nio.charset
类 CharsetEncoder

java.lang.Object
  继承者 java.nio.charset.CharsetEncoder

public abstract class CharsetEncoder
extends Object

能够把 16 位 Unicode 字符序列转换成特定 charset 中字节序列的引擎。

输入字符序列由字符缓冲区或一系列这样的缓冲区提供。输出字节序列写入字节缓冲区或一系列这样的缓冲区。应该始终通过下面的方法调用序列使用编码器,下文称为编码操作

  1. 通过 reset 方法重置编码器,除非以前未使用过;

  2. 只要有其他的输入数据就应零次或多次调用 encode,为 endOfInput 参数传递 false,在调用之间填充输入缓冲区并刷新输出缓冲区。

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

  4. 调用 flush 方法,这样编码器能够将任何内部状态刷新到输出缓冲区。

每次调用 encode 方法将编码尽可能多的输入缓冲区中的字符,将得到的字节写入输出缓冲区。当需要更多的输入时、输出缓冲区没有足够的空间或出现编码错误时,encode 方法返回。在每种情况下都返回用于描述终止原因的 CoderResult 对象。调用者可根据相应的状况检查此对象并填充输入缓冲区、刷新输出缓冲区或尝试从编码错误中恢复,并再次进行尝试。

有两种常规编码错误类型。如果输入字符序列不是合法的 16 位 Unicode 序列,那么就认为输入是错误的。如果输入字符序列是合法的,但不能映射为给定 charset 中的有效字节序列,那么就出现了不可映射的字符

如何处理编码错误取决于为该错误类型所请求的操作,在 CodingErrorAction 类的实例中描述了该类型的错误。可能的错误操作是忽略错误的输入、通过返回的 CoderResult 对象将错误报告给调用者,或者用当前的替换 byte 数组值替换错误的输入。 该替换值初始设置为编码器的默认替换值,这个值通常(但并非总是)具有初始值 { (byte)'?' }; 可通过 replaceWith 方法更改此值。

对于错误输入和不可映射的字符错误的默认操作是报告它们。可通过 onMalformedInput 方法更改针对错误输入的错误操作;可通过 onUnmappableCharacter 方法更改不可映射的字符错误的操作。

此类设计用来处理编码过程中的许多细节问题,包括错误操作的实现。一个特定 charset 的编码器是此类的具体子类,它只需要实现抽象的 encodeLoop 方法,这个方法封装了基本的编码循环。另外,维护内部状态的子类应该重写 implFlushimplReset 方法。

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

从以下版本开始:
1.4
另请参见:
ByteBuffer, CharBuffer, Charset, CharsetDecoder

构造方法摘要
protected CharsetEncoder(Charset cs, float averageBytesPerChar, float maxBytesPerChar)
          初始化新的编码器。
protected CharsetEncoder(Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement)
          初始化新的编码器。
 
方法摘要
 float averageBytesPerChar()
          返回为每个输入字符生成的平均字节数。
 boolean canEncode(char c)
          通知此编码器是否能够编码给定的字符。
 boolean canEncode(CharSequence cs)
          通过此编码器是否能够编码给定的字符序列。
 Charset charset()
          返回创建此编码器的 charset。
 ByteBuffer encode(CharBuffer in)
          把单个输入字符缓冲区的剩余内容编码到新分配的字节缓冲区的便捷方法。
 CoderResult encode(CharBuffer in, ByteBuffer out, boolean endOfInput)
          从给定输入缓冲区中编码尽可能多的字符,把结果写入给定的输出缓冲区。
protected abstract  CoderResult encodeLoop(CharBuffer in, ByteBuffer out)
          将一个或多个字符编码为一个或多个字节。
 CoderResult flush(ByteBuffer out)
          刷新此编码器。
protected  CoderResult implFlush(ByteBuffer out)
          刷新此编码器。
protected  void implOnMalformedInput(CodingErrorAction newAction)
          报告此编码器的错误输入操作的更改。
protected  void implOnUnmappableCharacter(CodingErrorAction newAction)
          报告此编码器的不可映射的字符操作的更改。
protected  void implReplaceWith(byte[] newReplacement)
          报告此编码器替换值的更改。
protected  void implReset()
          重置此编码器,清除所有特定于 charset 的内部状态。
 boolean isLegalReplacement(byte[] repl)
          通知给定的 byte 数组是否为此编码器的合法替换值。
 CodingErrorAction malformedInputAction()
          返回此编码器对错误输入错误的当前操作。
 float maxBytesPerChar()
          返回为每个输入字符生成的最大字节数。
 CharsetEncoder onMalformedInput(CodingErrorAction newAction)
          更改此编码器对错误输入错误的操作。
 CharsetEncoder onUnmappableCharacter(CodingErrorAction newAction)
          更改此编码器对不可映射的字符错误的操作。
 byte[] replacement()
          返回此编码器的替换值。
 CharsetEncoder replaceWith(byte[] newReplacement)
          更改此编码器的替换值。
 CharsetEncoder reset()
          重置此编码器,清除所有内部状态。
 CodingErrorAction unmappableCharacterAction()
          返回此编码器对不可映射的字符错误的当前操作。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

构造方法详细信息

CharsetEncoder

protected CharsetEncoder(Charset cs,
                         float averageBytesPerChar,
                         float maxBytesPerChar,
                         byte[] replacement)
初始化新的编码器。新编码器具有给定的每字符多少个字节 (chars-per-byte) 值和替换值。

参数:
averageBytesPerChar - 一个正的 float 值,指示为每个输入字符所生成的字节数
maxBytesPerChar - 一个正的 float 值,指示为每个输入字符所生成的最大字节数
replacement - 初始替换值;一定不能为 null、必须具有非零长度、必须小于 maxBytesPerChar,并且必须为 legal
抛出:
IllegalArgumentException - 如果参数有关的前提不成立

CharsetEncoder

protected CharsetEncoder(Charset cs,
                         float averageBytesPerChar,
                         float maxBytesPerChar)
初始化新的编码器。新编码器具有给定的每字符多少个字节值,它的替换值为 byte 数组 { (byte)'?' }

参数:
averageBytesPerChar - 一个正的 float 值,指示为每个输入字符所生成的字节数
maxBytesPerChar - 一个正的 float 值,指示为每个输入字符所生成的最大字节数
抛出:
IllegalArgumentException - 如果参数有关的前提不成立
方法详细信息

charset

public final Charset charset()
返回创建此编码器的 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)
通知给定的 byte 数组是否为此编码器的合法替换值。

当且仅当替换值是此编码器的 charset 中合法的字节序列时才是合法的;也就是说,能够把替换值解码成一个或多个 16 位 Unicode 字符。

此方法的默认实现效率不是很高;为了提高性能通常应该重写它。

参数:
repl - 要被测试的 byte 数组
返回:
当且仅当给定的 byte 数组是此编码器的合法替换值时才返回 true

malformedInputAction

public CodingErrorAction malformedInputAction()
返回此编码器对错误输入错误的当前操作。

返回:
当前的错误输入操作,它永远不能为 null

onMalformedInput

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

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

参数:
newAction - 新的操作;一定不能为 null
返回:
此编码器
抛出:
IllegalArgumentException - 如果参数有关的前提不成立

implOnMalformedInput

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

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


unmappableCharacterAction

public CodingErrorAction unmappableCharacterAction()
返回此编码器对不可映射的字符错误的当前操作。

返回:
当前的不可映射的字符操作,它永远不能为 null

onUnmappableCharacter

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

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

参数:
newAction - 新的操作;一定不能为 null
返回:
此编码器
抛出:
IllegalArgumentException - 如果参数有关的前提不成立

implOnUnmappableCharacter

protected void implOnUnmappableCharacter(CodingErrorAction 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 对象来描述它终止的原因:

在任一情况下,如果在相同的编码操作中调用此方法,则要注意保留输入缓冲区中剩余的所有字符,以便可提供给下一次调用使用。

endOfInput 参数通知此方法除了给定输入缓冲区包含的内容,调用者是否能提供更多的输入。如果可能提供其他的输入,则调用者应该为此参数传递 false;如果不能提供更多的输入,则调用者应该传递 true。实际上在一次调用中传递 false,但后来发现实际上没有更多的输入可用是相当普遍的,这不是错误。但关键是,在此方法的一系列调用中,最后一次调用总是传递 true,这样所有剩余的未编码输入都作为错误输入处理。

此方法通过调用 encodeLoop 方法、解释它的结果、处理错误情况并重新调用(如有必要)来完成其工作。

参数:
in - 输入字符缓冲区
out - 输出字节缓冲区
endOfInput - 当且仅当调用者除了给定缓冲区中的内容外不提供其他输入字符时才为 true
返回:
描述终止原因的 CoderResult 对象
抛出:
IllegalStateException - 如果编码操作已在进行中并且前面的步骤不是调用 reset 方法,也不是为 endOfInput 参数使用 false 来调用此方法,也不是为 endOfInput 参数使用 true 来调用此方法,而是一个指示未完成编码操作的返回值
CoderMalfunctionError - 如果对 encodeLoop 方法的调用抛出不可预料的异常

flush

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

一些编码器维护内部状态,并且一旦读取完所有的输入序列后,可能需要向输出缓冲区写入一些最终字节。

任何其他输出写入输出缓冲区时都要从缓冲区的当前位置开始。最多将写入 out.remaining() 个字节。缓冲区的位置要相应地向前移动,但是其标记和界限将无法修改。

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

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

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

参数:
out - 输出字节缓冲区
返回:
一个 CoderResult 对象,可能是 CoderResult.UNDERFLOWCoderResult.OVERFLOW
抛出:
IllegalStateException - 如果当前编码操作的前一步既不是调用 flush 方法,也不是为 endOfInput 参数使用 true 来调用三参数的 encode 方法

implFlush

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

此方法的默认实现不执行任何操作,并且始终返回 CoderResult.UNDERFLOW。对于那些一旦读取完整个的输入序列后,可能需要向输出缓冲区写入最终字节的编码器而言,应该重写此方法。

参数:
out - 输出字节缓冲区
返回:
一个 CoderResult 对象,可能是 CoderResult.UNDERFLOWCoderResult.OVERFLOW

reset

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

此方法重置与 charset 无关的状态,并且为了执行所有特定于 charset 的重置操作,还会调用 implReset 方法。

返回:
此编码器

implReset

protected void implReset()
重置此编码器,清除所有特定于 charset 的内部状态。

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


encodeLoop

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

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

应该从各缓冲区的当前位置开始进行读取和写入。最多将读取 in.remaining() 个字符,最多将写入 out.remaining() 个字节。前移缓冲区的位置,以反映字符读取和写入字节,但是其标记和界限将无法修改。

此方法返回一个 CoderResult 对象描述它终止的原因,其方式和 encode 方法的相同。大多数此方法的实现处理编码错误的方式是由 encode 方法返回一个用来解释错误的相应结果对象。最优的实现可能是检查相关的错误操作并且自己实现该操作。

此方法的一种实现可能在接收到足够的输入之前,通过返回 CoderResult.UNDERFLOW 来执行任意的 lookahead。

参数:
in - 输入字符缓冲区
out - 输出字节缓冲区
返回:
描述终止原因的 CoderResult 对象

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) 方法来检测是否能够编码某个字符序列。

此方法可以修改此编码器的状态;因此如果正在进行编码操作,则不应该调用此方法。

此方法的默认实现效率不是很高;为了提高性能通常应该重写它。

返回:
当且仅当此编码器能够编码给定字符时才返回 true
抛出:
IllegalStateException - 如果已经进行编码操作

canEncode

public boolean canEncode(CharSequence cs)
通过此编码器是否能够编码给定的字符序列。

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

此方法可以修改此编码器的状态;因此如果正在进行编码操作,则不应该调用此方法。

此方法的默认实现效率不是很高;为了提高性能通常应该重写它。

返回:
当且仅当此编码器在既不抛出任何异常也不执行任何替换的情况下就能编码给定的字符时才返回 true
抛出:
IllegalStateException - 如果已经进行编码操作

JavaTM Platform
Standard Ed. 6

提交错误或意见
有关更多的 API 参考资料和开发人员文档,请参阅 Java SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。

版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策