I/O
什么是I/O
- 生活中,当你电脑插上一个U盘,可以把一个视频拷贝到你的电脑时,这个数据传输过程
- 我们把这种数据的传输,可以看作一种数据流动,按照流动方向,以内存为基准,分为输入(input) 和 输出(output),即流向内存时输入流,流出内存的输出流
- Java中IO操作主要是指java.io包下的内容,进行输入,输出操作,输入也叫做读取数据,输出也叫做写出数据
如下图,展示了硬盘和内存的操作关系!!!
I/O的分类
根据数据的流方向:输入流和输出流
- 输入流:把数据从其他设备上读取到内存当中的流
- 输出流:把数据从内存当中写出到其他设备上的流
根据数据的类型分为:字节流和字符流
下图是它们的顶级父类
字节输出流 【OutputStream】
一切文件数据(文本,图片,视频)再存储时,都以二进制数字形式保存,都一个一个字节,传输时候一样,所以字节流可以传输任意文件数据
再操作流的是偶,我们需要时刻明确,无论使用什么杨的流对象,底层传输的始终为二进制数据
java.io.OutputStream 抽象类时表示字节输出流的所有类的父类,将指定的字节信息写出到目的地,定义了字节流基本共性功能方法
注意: close方法,当完成流的操作时,必须调用此方法,释放系统资源!
public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("F:\\ziwozongjie.txt");
String content = "囧囧,囧囧是世界上好看的女人!!!";
out.write(content.getBytes());
out.close();
}
}
看F盘会给你创建一个 ziwozongjie.txt文件,并将下面的那句话写入到该文件中
写出数据的原理(内存—> 硬盘)
- java程序–> JVM(java虚拟机–> OS(操作系统) --> OS调用写数据的方法 --> 把数据写入到文件中
存出数据的原理
public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("F:\\jiongjiong.txt");
out.write(97);
out.close();
}
}
写数据的时候,会把10进制转换成2进制,对应存储的就是2进制的97 也就是 1100001
当我们打开文本编辑器的时候(任何文本编辑器,记事本或nodepad++) 都会查询编码表,把字节转换成字符
如果存储的是0-127 会查询ASCII码表 而我们的97对应的是英文字母a ,如果是其他值,查询的系统默认码表(中文系统GBK或UTF-8)
结果就是 小写a
!!!注意!!!
- 当我们调用一次写多个字节的方法 void write(byte[] b)
- 如果第一个字节是正数(0-127) 那么显示的时候会查询ASCII码表
- 如果第一个字节是负数,那么第一个字节和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("F:\\jiongjiong.txt");
byte[] b = {-65, -66, -67, 68, 79};
out.write(b);
out.close();
}
}
结果并非乱码,而是对应GBK表中的汉字
追加写和续写
- String name,File file 写入数据的目的地
- boolean append true:不会覆盖原文件,继续再文件的末尾追加 false:创建一个新文件,覆盖原文件
!!!上代码!!!
public class Demo02OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fot = new FileOutputStream("F:\\cccc.txt", true);
String content = "您好!豆豆";
for (int i = 0; i < 10; i++) {
fot.write(content.getBytes("utf-8"));
fot.write("\r\n".getBytes());
}
fot.close();
}
}
字节输入流 【InputStream】
java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中,定义了字节输入流的基本共享功能方法
注意: close方法,当完成流的操作时,必须调用此方法,释放系统资源!
!!!上代码!!!
public class Demo03FileInputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("F:\\cccc.txt");
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
}
}
!!!结果!!!
Demo 文件复制
public class Demo04FileInputStream {
public static void main(String[] args) throws IOException {
try (
FileInputStream fis = new FileInputStream("F:\\cccc.txt");
FileOutputStream fos = new FileOutputStream("F:\\dddd.txt");
) {
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("复制成功");
}
}
复制文件成功
注意: 这里我用了jdk8的特性 Lambda表达式 try…with…resource 所以不用再finally块中关闭流,jdk会帮我们把这段代码优化成try…catch…finally