auto commit

This commit is contained in:
CyC2018 2018-06-09 23:03:31 +08:00
parent 7545ae24b3
commit c3ee062a20

View File

@ -26,12 +26,12 @@
Java 的 I/O 大概可以分成以下几类:
1. 磁盘操作File
2. 字节操作InputStream 和 OutputStream
3. 字符操作Reader 和 Writer
4. 对象操作Serializable
5. 网络操作Socket
6. 新的输入/输出NIO
- 磁盘操作File
- 字节操作InputStream 和 OutputStream
- 字符操作Reader 和 Writer
- 对象操作Serializable
- 网络操作Socket
- 新的输入/输出NIO
# 二、磁盘操作
@ -51,39 +51,67 @@ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
DataInputStream 装饰者提供了对更多数据类型进行输入的操作,比如 int、double 等基本类型。
批量读入文件内容到字节数组
使用字节流操作进行文件复制
```java
byte[] buf = new byte[20*1024];
int bytes = 0;
// 最多读取 buf.length 个字节,返回的是实际读取的个数,返回 -1 的时候表示读到 eof即文件尾
while((bytes = in.read(buf, 0 , buf.length)) != -1) {
// ...
FileInputStream in = new FileInputStream("file/1.txt");
FileOutputStream out = new FileOutputStream("file/2.txt");
byte[] buffer = new byte[20 * 1024];
// read() 最多读取 buffer.length 个字节,返回的是实际读取的个数
// 返回 -1 的时候表示读到 eof即文件尾
while (in.read(buffer, 0, buffer.length) != -1) {
out.write(buffer);
}
in.close();
out.close;
```
# 四、字符操作
不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符,所以 I/O 操作的都是字节而不是字符。但是在程序中操作的通常是字符形式的数据,因此需要提供对字符进行操作的方法。
不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符。但是在程序中操作的通常是字符形式的数据,因此需要提供对字符进行操作的方法。
InputStreamReader 实现从文本文件的字节流解码成字符流OutputStreamWriter 实现字符流编码成为文本文件的字节流。它们继承自 Reader 和 Writer。
InputStreamReader 实现从文本文件的字节流解码成字符流OutputStreamWriter 实现字符流编码成为文本文件的字节流。它们分别继承自 Reader 和 Writer。
逐行输出文本文件的内容:
```java
FileReader fileReader = new FileReader("file/1.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 装饰者模式使得 BufferedReader 组合了一个 Reader 对象
// 在调用 BufferedReader 的 close() 方法时会去调用 fileReader 的 close() 方法,因此只要一个 close() 调用即可
bufferedReader.close();
```
编码就是把字符转换为字节,而解码是把字节重新组合成字符。
```java
byte[] bytes = str.getBytes(encoding); // 编码
String str = new String(bytes, encoding) // 解码
```
如果编码和解码过程使用不同的编码方式那么就出现了乱码。
- GBK 编码中,中文占 2 个字节,英文占 1 个字节;
- UTF-8 编码中,中文占 3 个字节,英文占 1 个字节;
- UTF-16be 编码中,中文和英文都占 2 个字节。
- GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节;
- UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节;
- UTF-16be 编码中,中文字符和英文字符都占 2 个字节。
UTF-16be 中的 be 指的是 Big Endian也就是大端。相应地也有 UTF-16lele 指的是 Little Endian也就是小端。
Java 使用双字节编码 UTF-16be这不是指 Java 只支持这一种编码方式,而是说 char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位也就是两个字节Java 使用这种双字节编码正是为了让一个中文或者一个英文都能使用一个 char 来存储。
Java 使用双字节编码 UTF-16be这不是指 Java 只支持这一种编码方式,而是说 char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位也就是两个字节Java 使用这种双字节编码是为了让一个中文或者一个英文都能使用一个 char 来存储。
String 可以看成一个字符序列,可以指定一个编码方式将它转换为字节序列,也可以指定一个编码方式将一个字节序列转换为 String。
```java
String str1 = "中文";
byte[] bytes = str1.getBytes("UTF-8");
String str2 = new String(bytes, "UTF-8");
System.out.println(str2);
```
在调用无参数 getBytes() 方法时,默认的编码方式不是 UTF-16be。双字节编码的好处是可以使用一个 char 存储中文和英文,而将 String 转为 bytes[] 字节数组就不再需要这个好处因此也就不再需要双字节编码。getBytes() 的默认编码方式与平台有关,一般为 UTF-8。
```java
byte[] bytes = str1.getBytes();
```
# 五、对象操作
@ -107,10 +135,10 @@ private transient Object[] elementData;
Java 中的网络支持:
1. InetAddress用于表示网络上的硬件资源即 IP 地址;
2. URL统一资源定位符通过 URL 可以直接读取或者写入网络上的数据;
3. Sockets使用 TCP 协议实现网络通信;
4. Datagram使用 UDP 协议实现网络通信。
- InetAddress用于表示网络上的硬件资源即 IP 地址;
- URL统一资源定位符通过 URL 可以直接读取或者写入网络上的数据;
- Sockets使用 TCP 协议实现网络通信;
- Datagram使用 UDP 协议实现网络通信。
## InetAddress
@ -466,3 +494,4 @@ NIO 与普通 I/O 的区别主要有以下两点:
- [NIO 与传统 IO 的区别](http://blog.csdn.net/shimiso/article/details/24990499)
- [Decorator Design Pattern](http://stg-tud.github.io/sedc/Lecture/ws13-14/5.3-Decorator.html#mode=document)
- [Socket Multicast](http://labojava.blogspot.com/2012/12/socket-multicast.html)
- [深入分析 Java 中的中文编码问题](https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/index.htm)