X Tutup
Skip to content

Commit 0809ffa

Browse files
committed
校订 附录新IO 完成80%
1 parent d2b56b5 commit 0809ffa

File tree

3 files changed

+56
-55
lines changed

3 files changed

+56
-55
lines changed

SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@
355355
* [转换数据](docs/book/Appendix-New-IO.md#数据转换)
356356
* [获取原始类型](docs/book/Appendix-New-IO.md#基本类型获取)
357357
* [视图缓冲区](docs/book/Appendix-New-IO.md#视图缓冲区)
358-
* [使用缓冲区进行数据操作](docs/book/Appendix-New-IO.md#使用缓冲区进行数据操作)
358+
* [使用缓冲区进行数据操作](docs/book/Appendix-New-IO.md#缓冲区数据操作)
359359
* [内存映射文件](docs/book/Appendix-New-IO.md#内存映射文件)
360360
* [文件锁定](docs/book/Appendix-New-IO.md#文件锁定)
361361
* [附录:理解equals和hashCode方法](docs/book/Appendix-Understanding-equals-and-hashCode.md)

docs/_sidebar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@
334334
* [转换数据](book/Appendix-New-IO.md#数据转换)
335335
* [获取原始类型](book/Appendix-New-IO.md#基本类型获取)
336336
* [视图缓冲区](book/Appendix-New-IO.md#视图缓冲区)
337-
* [使用缓冲区进行数据操作](book/Appendix-New-IO.md#使用缓冲区进行数据操作)
337+
* [使用缓冲区进行数据操作](book/Appendix-New-IO.md#缓冲区数据操作)
338338
* [内存映射文件](book/Appendix-New-IO.md#内存映射文件)
339339
* [文件锁定](book/Appendix-New-IO.md#文件锁定)
340340
* [附录:理解equals和hashCode方法](book/Appendix-Understanding-equals-and-hashCode.md)

docs/book/Appendix-New-IO.md

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
// 不同字节存储次序的存储
582585
import java.nio.*;
583586
import 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 了解更多书本信息。
655653
import java.nio.*;
656654

657655
public 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+
```
682685
UsingBuffers
683686
sUniBgfuefsr
684687
UsingBuffers
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
10461048
1. 您可以在附录:低级并发中找到关于线程的更多细节。
10471049
=======
10481050
<!-- 分页 -->
1049-
10501051
<div style="page-break-after: always;"></div>

0 commit comments

Comments
 (0)
X Tutup