@@ -561,24 +561,27 @@ Double Buffer 0 -> 4.8E-322,
561561![ 1554546258113] ( ../images/1554546258113.png )
562562
563563<!-- Endians -->
564- ### 端
564+ ### 字节存储次序
565565
566- 不同的机器可以使用不同的字节顺序方法来存储数据。“Big endian”将最重要的字节(the most significant byte)放在最低内存地址中 ,而“little endian” 将最重要的字节放在最高内存地址中。
566+ 不同的机器可以使用不同的字节存储顺序( * Endians * )来存储数据。“高位优先”( * Big Endian * ):将最重要的字节放在最低内存地址中 ,而“低位优先”( * Little Endian * ): 将最重要的字节放在最高内存地址中。
567567
568- 当存储一个大于一个字节的量时,例如 ** int** 、** float** 等,您可能需要考虑字节排序。字节缓冲区以大端字节形式存储数据,通过网络发送的数据总是使用大端字节顺序。您可以使用 ** order() ** 和 ** ByteOrder** 参数来更改 ** ByteBuffer ** 端,可选参数只有2个: ** ByteOrder.BIG_ENDIAN** 或 ** ByteOrder.LITTLE_ENDIAN** 。
568+ 当存储大于单字节的数据时,如 ** int** 、** float** 等,我们可能需要考虑字节排序问题。 ** ByteBuffer ** 以“高位优先”形式存储数据;通过网络发送的数据总是使用“高位优先”形式。我们可以 使用 ** ByteOrder** 的 ` order() ` 方法和参数 ** ByteOrder.BIG_ENDIAN** 或 ** ByteOrder.LITTLE_ENDIAN** 来改变它的字节存储次序 。
569569
570- 考虑一个包含以下两个字节的 ** ByteBuffer** :将数据作为一个 ** short ** ( ** ByteBuffer. asshortbuffer() ** ) 读取,生成数字 97 (00000000 01100001)。更改为 little endian 将生成数字 24832 (01100001 00000000)。
570+ 下例是一个包含两个字节的 ** ByteBuffer** :
571571
572572![ 1554546378822] ( ../images/1554546378822.png )
573573
574- 这显示了字节顺序的变化取决于 endian 设置:
574+
575+ 将数据作为 ** short** 型来读取(** ByteBuffer.asshortbuffer()** )),生成数字 97 (00000000 01100001)。更改为“低位优先”后 将生成数字 24832 (01100001 00000000)。
576+
577+ 这显示了字节顺序的变化取决于字节存储次序设置:
575578
576579``` java
577580// newio/Endians.java
578581// (c)2017 MindView LLC: see Copyright.txt
579- // We make no guarantees that this code is fit for any purpose.
580- // Visit http://OnJava8.com for more book information.
581- // Endian differences and data storage
582+ // 我们无法保证该代码是否适用于其他用途。
583+ // 访问 http://OnJava8.com 了解更多书本信息。
584+ // 不同字节存储次序的存储
582585import java.nio.* ;
583586import java.util.* ;
584587
@@ -597,61 +600,56 @@ public class Endians {
597600 System . out. println(Arrays . toString(bb. array()));
598601 }
599602}
600- /* Output:
603+ ```
604+
605+ 输出结果:
606+
607+ ```
601608[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
602609[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
603610[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
604- */
605-
606611```
607612
608- ** ByteBuffer** 分配空间将 ** charArray** 中的所有字节作为外部缓冲区保存,因此可以调用 ** array()** 方法来显示底层字节。** array()** 方法是“可选的”,您只能在数组支持的缓冲区上调用它 ,否则您将得到一个 ** UnsupportedOperationException** 。
613+ ** ByteBuffer** 分配空间将 ** charArray** 中的所有字节作为外部缓冲区保存,因此可以调用 ` array() ` 方法来显示底层字节。` array() ` 方法是“可选的”,你只能在数组支持的缓冲区上调用它,否则将抛出 ** UnsupportedOperationException** 异常 。
609614
610- ** charArray** 通过 ** CharBuffer** 视图插入到 ** ByteBuffer ** 中。当显示底层字节时,默认顺序与随后的大端序相同,而小端序则交换字节。
615+ ** charArray** 通过 ** CharBuffer** 视图插入到 ** ByteBuffer** 中。当显示底层字节时,默认排序与后续“高位”相同,而“地位”交换字节
611616
612617<!-- Data Manipulation with Buffers -->
613- ## 使用缓冲区进行数据操作
618+ ## 缓冲区数据操作
614619
615620
616- 下图说明了 nio 类之间的关系,展示了如何移动和转换数据。例如,要将字节数组写入文件,使用ByteBuffer. wrap() 方法包装字节数组,使用 ** getChannel()** 在 ** FileOutputStream** 上打开通道,然后从 ** ByteBuffer** 将数据写入 ** FileChannel** 。
621+ 下图说明了 ** nio** 类之间的关系,展示了如何移动和转换数据。例如,要将字节数组写入文件,使用 ** ByteBuffer. ** ` wrap() ` 方法包装字节数组,使用 ` getChannel() ` 在 ** FileOutputStream** 上打开通道,然后从 ** ByteBuffer** 将数据写入 ** FileChannel** 。
617622
618623![ 1554546452861] ( ../images/1554546452861.png )
619624
620- ** ByteBuffer** 是将数据移入和移出通道的唯一方法,您只能创建一个独立的原始类型的缓冲区 ,或者使用“as”方法从ByteBuffer获得一个新缓冲区 。也就是说,不能将基元类型的缓冲区转换为ByteBuffer。但您能够通过视图缓冲区将原始数据移动到 ** ByteBuffer** 中或移出 ** ByteBuffer** 。
625+ ** ByteBuffer** 是将数据移入和移出通道的唯一方法,我们只能创建一个独立的基本类型缓冲区 ,或者使用 ` as ` 方法从 ** ByteBuffer ** 获得一个新缓冲区 。也就是说,不能将基本类型缓冲区转换为 ** ByteBuffer ** 。但我们能够通过视图缓冲区将基本类型数据移动到 ** ByteBuffer** 中或移出 ** ByteBuffer** 。
621626
622627
623628
624- ### 缓冲区的细节
625-
626- 缓冲区由数据和四个索引组成,以有效地访问和操作该数据: 标记、位置、限制 和 容量(mark, position, limit and capacity)。有一些方法可以设置和重置这些索引并查询它们的值。
627-
628- ** capacity()** 返回缓冲区的 capacity。
629-
630- ** clear()** 清除缓冲区,将 position 设置为零并 设 limit 为 capacity。您可以调用此方法来覆盖现有缓冲区。
631-
632- ** flip()** 将 limit 设置为位置,并将 position 设置为零。此方法用于准备缓冲区,以便在数据写入缓冲区后进行读取。
633-
634- ** limit()** 返回 limit 的值。
629+ ### 缓冲区细节
635630
636- ** limit(int lim) ** 重设 limit
631+ 缓冲区由数据和四个索引组成,以有效地访问和操作该数据: * mark * 、 * position * 、 * limit* 和 * capacity * (标记、位置、限制 和 容量)。有一些方法可以设置和重置这些索引并查询它们的值。
637632
638- ** mark()** 设置 mark 为当前的 position
633+ | | |
634+ | :----- | :----- |
635+ | ** capacity()** | 返回缓冲区的 * capacity* |
636+ | ** clear()** | 清除缓冲区,将 * position* 设置为零并 设 * limit* 为 * capacity* ;可调用此方法来覆盖现有缓冲区|
637+ | ** flip()** | 将 * limit* 设置为 * position* ,并将 * position* 设置为 0;此方法用于准备缓冲区,以便在数据写入缓冲区后进行读取|
638+ | ** limit()** | 返回 * limit* 的值|
639+ | ** limit(int limit)** | 重设 * limit* |
640+ | ** mark()** | 设置 * mark* 为当前的 * position* |
641+ | ** position()** | 返回 * position* |
642+ | ** position(int pos)** | 设置 * position* |
643+ | ** remaining()** | 返回 * limit* 到 * position* |
644+ | ** hasRemaining()** | 如果在 * position* 与 * limit* 中间有元素,返回 ` true ` |
639645
640- ** position()** 返回 position
641-
642- ** position(int pos) ** 设置 position
643-
644- ** remaining()** 返回 limit - position 。
645-
646- ** hasRemaining()** 如果在 position 与 limit 中间有元素,返回 ** true**
647-
648- 从缓冲区插入和提取数据的方法更新这些索引来反映所做的更改。这个例子使用了一个非常简单的算法(交换相邻的字符)来打乱和整理字符在CharBuffer:
646+ 从缓冲区插入和提取数据的方法通过更新索引来反映所做的更改。下例使用一种非常简单的算法(交换相邻字符)来对 ** CharBuffer** 中的字符进行加扰和解扰。代码示例:
649647
650648``` java
651649// newio/UsingBuffers.java
652650// (c)2017 MindView LLC: see Copyright.txt
653- // We make no guarantees that this code is fit for any purpose.
654- // Visit http://OnJava8.com for more book information.
651+ // 我们无法保证该代码是否适用于其他用途。
652+ // 访问 http://OnJava8.com 了解更多书本信息。
655653import java.nio.* ;
656654
657655public class UsingBuffers {
@@ -665,6 +663,7 @@ public class UsingBuffers {
665663 buffer. put(c2). put(c1);
666664 }
667665 }
666+
668667 public static void main (String [] args ) {
669668 char [] data = " UsingBuffers" . toCharArray();
670669 ByteBuffer bb =
@@ -678,51 +677,54 @@ public class UsingBuffers {
678677 System . out. println(cb. rewind());
679678 }
680679}
681- /* Output:
680+ ```
681+
682+ 输出结果:
683+
684+ ```
682685UsingBuffers
683686sUniBgfuefsr
684687UsingBuffers
685- */
686688```
687689
688- 虽然可以通过使用 ** char** 数组调用 ** wrap()** 直接生成 ** CharBuffer** ,但是底层的 ** ByteBuffer** 将被分配,而 ** CharBuffer** 将作为 ** ByteBuffer** 上的视图生成。这强调了目标始终是操作 ** ByteBuffer** ,因为它与通道交互。
690+ 虽然可以通过使用 ** char** 数组调用 ` wrap() ` 直接生成 ** CharBuffer** ,但是底层的 ** ByteBuffer** 将被分配,而 ** CharBuffer** 将作为 ** ByteBuffer** 上的视图生成。这强调了目标始终是操作 ** ByteBuffer** ,因为它与通道交互。
689691
690692下面是程序在 ** symmetricgrab()** 方法入口时缓冲区的样子:
691693
692694![ 1554546627710] ( ../images/1554546627710.png )
693695
694- position 指向缓冲区中的第一个元素,capacity 和 limie 紧接在最后一个元素之后。在** symmetricgrab()** 中,while循环迭代到 position 等于 limit。当在缓冲区上调用相对位置的 get() 或 put() 函数时,缓冲区的位置会发生变化。您还可以调用绝对位置的 get() 和 put() 方法,它们包含索引参数 : get()或put() 发生的位置。这些方法不修改缓冲区 position 的值。
696+ * position* 指向缓冲区中的第一个元素,* capacity* 和 * limit * 紧接在最后一个元素之后。在` symmetricgrab() ` 中,** while ** 循环迭代到 * position* 等于 * limit* 。当在缓冲区上调用相对位置的 ` get() ` 或 ` put() ` 函数时,缓冲区的位置会发生变化。你可以调用绝对位置的 ` get() ` 和 ` put() ` 方法,它们包含索引参数: ` get() ` 或 ` put() ` 发生的位置。这些方法不修改缓冲区 * position* 的值。
695697
696- 当控件进入while循环时,使用 ** mark()** 调用设置 mark 的值。缓冲区的状态为:
698+ 当控件进入 ** while ** 循环时,使用 ` mark() ` 设置 * mark* 的值。缓冲区的状态为:
697699
698700![ 1554546666685] ( ../images/1554546666685.png )
699701
700- 两个相对 get() 调用将前两个字符的值保存在变量c1和c2中 。在这两个调用之后,缓冲区看起来是这样的 :
702+ 两个相对 * get()* 调用将前两个字符的值保存在变量 ` c1 ` 和 ` c2 ` 中 。在这两个调用之后,缓冲区看起来是这样的:
701703
702704![ 1554546693664] ( ../images/1554546693664.png )
703705
704- 为了执行交换,我们在位置0处编写c2,在位置1处编写c1。我们可以使用绝对put方法来实现这一点 ,或者用 reset() 方法,将 position 的值设置为 mark 。
706+ 为了执行交换,我们在位置 0 处编写 ` c2 ` ,在位置 1 处编写 ` c1 ` 。我们可以使用绝对 ` put() ` 方法来实现这一点 ,或者用 ` reset() ` 方法,将 * position* 的值设置为 * mark* :
705707
706708![ 1554546847181] ( ../images/1554546847181.png )
707709
708- 两个put()方法分别编写c2和c1 :
710+ 两个 ` put() ` 方法分别编写 ` c2 ` 和 ` c1 ` :
709711
710712![ 1554546861836] ( ../images/1554546861836.png )
711713
712- 在循环的下一次迭代中,将mark设置为position的当前值 :
714+ 在下一次循环中,将 * mark * 设置为 * position * 的当前值:
713715
714716![ 1554546881189] ( ../images/1554546881189.png )
715717
716- 该过程将继续,直到遍历整个缓冲区为止。在while循环的末尾,position位于缓冲区的末尾 。如果显示缓冲区,则只显示位置和限制之间的字符。因此,要显示缓冲区的全部内容,必须使用 rewind() 将位置设置为缓冲区的开始位置 。这是 rewind() 调用后 buffer 的状态(mark的值变成undefined):
718+ 该过程将继续,直到遍历整个缓冲区为止。在 ** while ** 循环的末尾, * position * 位于缓冲区的末尾 。如果显示缓冲区,则只显示位置和限制之间的字符。因此,要显示缓冲区的全部内容,必须使用 ` rewind() ` 将 * position * 设置为缓冲区的开始位置 。这是 ` rewind() ` 调用后缓冲区的状态( * mark * 的值变成未定义):
717719
718720![ 1554546890132] ( ../images/1554546890132.png )
719721
720- 再次调用 ** symmetricgrab()** 函数时,** CharBuffer** 将经历相同的过程并恢复到原始状态。
722+ 再次调用 ` symmetricgrab() ` 方法时,** CharBuffer** 将经历相同的过程并恢复到原始状态。
723+
721724
722725<!-- Memory-Mapped Files -->
723726## 内存映射文件
724727
725-
726728内存映射文件允许您创建和修改太大而无法放入内存的文件。使用内存映射文件,您可以假装整个文件都在内存中,并将其视为一个非常大的数组来访问它。这种方法大大简化了您编写的修改文件的代码:
727729
728730``` java
@@ -1046,5 +1048,4 @@ Released: 0 to 50331647
104610481 . 您可以在附录:低级并发中找到关于线程的更多细节。
10471049=======
10481050<!-- 分页 -->
1049-
10501051<div style =" page-break-after : always ;" ></div >
0 commit comments