目录
Writer抽象类OutputStreamWriter 实现类
1. 直接读取(以二进制数据的方式读取,表现在代码中 byte为单位)
2. 文本读取
1. java.io.InputStream 输入流2. 本身是一个抽象类,真正使用过程中要依赖这个抽象的具体实现子类
FilelnputStream关于文件的输入流
3. 抽象模型
4.要记得关闭
is.close()
import java.io.FileInputStream; import java.io.InputStream; import java.util.Arrays; public class Demo4 { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream("./hello.txt"); // FileInputStream 赋值给 InputStream,是因为有继承关系 // FileInputStream是InputStream的下级类 // 准备水桶 // 1024 代表能接 1024 滴(字节)水,我们准备好桶的容量 byte[] buf = new byte[1024]; // n是真正接到多少(字节)的水 // n >= 0&& n < 1024 int n = is.read(buf); //12 System.out.println(n); // 真正的数据放在 buf 从 [0, 12) byte[] bytes = Arrays.copyOf(buf, n); for (byte b : bytes) { System.out.printf("%02x\n", b); } is.close(); } }windows 上的换行默认是“\r\n"也写作CRLF
如何利用InputStream进行二进制数据的直接读取
1)一个字节
2)一次读一批
理解EOS (-1)
除了要接水之外,我们还需要一个明确的信号(说明肯定不会有新的数据了)
End Of Stream(EOS)
如果这次接了0滴水
A.是暂时现在没水了?——0B.还是以后永远没水了?—— -1
一次读一滴
import java.io.FileInputStream; import java.io.InputStream; public class Demo5 { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream("./hello.txt"); while (true) { int data = is.read(); if (data == -1) { // 所有数据都被读完了 break; } // 否则,data 就是我们取到的数据 byte b = (byte) data; System.out.printf("%02x\n", b); } is.close(); } }
一次读一桶
import java.io.FileInputStream; import java.io.InputStream; public class Demo6 { public static void main(String[] args) throws Exception { InputStream is = new FileInputStream("./hello.txt"); byte[] buf = new byte[5]; while (true) { int n = is.read(buf); // n == 0 只是本次没数据,以后还有 // n == -1 本次没数据,以后也没数据了 if (n == -1) { // 代表数据全部读完 break; } for (int i = 0; i < buf.length; i++) { byte b = buf[i]; System.out.printf("%02x\n", b); } } is.close(); } }
处理文本数据(字符数据)
ASCII、Unicode、UTF-8、GBK (GB18030、GB2312)
字符集(char set)
字符编码规则(char encoding)
计算机中的数据<->数字(有范围的整数)
图像、声音、文字->数字
如果每个人都定义自己的字符集,实际上没有任何的意义。
所以,总是由标准委员会来规定好一个字符集,大家一起遵守!
所以才有各种各样的标准字符集的出现!
public class Demo8 { public static void main(String[] args) throws Exception { try (InputStream is = new FileInputStream("./test.txt")) { byte[] bytes = new byte[1024]; int n = is.read(bytes); String s = new String(bytes, 0, n, "UTF-8"); System.out.println(s); } } }
Scanner scanner = new Scanner(System.in);
import java.io.FileInputStream; import java.io.InputStream; import java.util.Scanner; public class Demo8 { public static void main(String[] args) throws Exception { try (InputStream is = new FileInputStream("./test.txt")) { try (Scanner scanner = new Scanner(is, "UTF-8")) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println("|" + line + "|"); } } } } }
内存的写速度远远快于硬盘的写速度。
所以,为了平衡这个速度之差,一般通过“缓冲区buffer”来处理
之前文件不存在,直接写入
import java.io.FileOutputStream; import java.io.OutputStream; public class Demo10 { public static void main(String[] args) throws Exception { // OutputStream -> FileOutputStream // 所以很少用 file.createNewFile() // 如果文件之前不存在,则会进行创建(创建可能失败: 1. 权限、2. 路径上的目录还不存在) // 如果文件之前存在,会清空之前的文件内容,重新写入 try (OutputStream os = new FileOutputStream("./out.txt")) { // 空格// 0xe6 0x88 0x91 是 "我" 的 UTF-8 编码的字节序列 os.write(0xe6); os.write(0x88); os.write(0x91); // 确保把缓冲区内可能遗留的数据全部写入 Output 设备中 os.flush(); } } }
之前文件存在,清空内容,重新写入
import java.io.FileOutputStream; import java.io.OutputStream; public class Demo10 { public static void main(String[] args) throws Exception { // OutputStream -> FileOutputStream // 所以很少用 file.createNewFile() // 如果文件之前不存在,则会进行创建(创建可能失败: 1. 权限、2. 路径上的目录还不存在) // 如果文件之前存在,会清空之前的文件内容,重新写入 try (OutputStream os = new FileOutputStream("./out.txt")) { // 空格// 0xe6 0x88 0x91 是 "我" 的 UTF-8 编码的字节序列 // os.write(0xe6); // os.write(0x88); // os.write(0x91); os.write(0x20); os.write(0x0d); // '\r' os.write(0x0a); // '\n' os.write(0x65); os.write(0x65); os.write(0x65); // 确保把缓冲区内可能遗留的数据全部写入 Output 设备中 os.flush(); } } }
连续写入
import java.io.FileOutputStream; import java.io.OutputStream; public class Demo11 { public static void main(String[] args) throws Exception { try(OutputStream os = new FileOutputStream("./out.txt")) { byte[] buf = {0x65,0x65,0x20,0x65,0x0d,0x0a,(byte) 0xe6,(byte)0x88,(byte)0x91}; // 整个 buf 的数据全部写入 os.write(buf); // os.write(buf,2,4); os.flush(); } } }
import java.io.*; public class Demo12 { public static void main(String[] args) throws Exception { try (OutputStream os = new FileOutputStream("./word.txt")) { try (Writer writer = new OutputStreamWriter(os, "UTF-8")) { writer.write("你好\r\n"); writer.write("哈哈"); writer.flush(); } } } }
PrintWriter
printIn(...)print(...)
printf(fmt, ...)
import java.io.*; public class Demo12 { public static void main(String[] args) throws Exception { try (OutputStream os = new FileOutputStream("./printWriter.txt")) { try (Writer writer = new OutputStreamWriter(os, "UTF-8")) { try (PrintWriter printWriter = new PrintWriter(writer)) { printWriter.println(1+1); printWriter.print(3); printWriter.printf("%s+%d","我",10); printWriter.flush(); } } } } }
InputStream输入流,背后就是输入设备(模拟的输入设备)
1.read() 、read(byte[])
2.EOS(-1)
3.Scanner(is, "UTF-8");
OutputStream输出流,背后就是输出设备(模拟的输出设备)1. write(int)、write(byte[])
2. flush()缓冲区(buffer)平衡写入次数
3.OutputStreamWriter(做字符集编码处理) + PrintWriter(使用我们熟悉的print/println/printf)