In/Out: 相对于程序而言的输入(读取)和输出(写出)的过程。
即: 通过java程序到磁盘读取数据的过程, 我们称为In的过程, 也就是读取(输入)
将java程序中的数据写入磁盘的过程, 我们称为Out的过程, 也就是写出(输出)
在Java中,根据处理的数据单位不同,分为字节流和字符流。
字节流: 一个字节(byte)一个字节的去读取, 或者写出
字符流: 一个字符一个字符的去读取, 或者写出
JDK核心类库中提供了IO流相关的类, 这些类都在
程序中数据的读取和写入, 可以想象成水流在管道中流动。
– 流只能单方向流动
– 输入流用来读取in
– 输出流用来写出Out
– 数据只能从头到尾顺序的读取一次或写出一次
节点流和处理流按照流是否直接与特定的地方(如磁盘,内存,设备等)相连,分为节点流和处理流两类
节点流可以从或向一个特定的地方(节点)读写数据
处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写
处理流特点处理流的构造方法总是要带一个其他的流对象做参数,一个流对象经过其他流的多次包装,成为流的链接.
通常节点流也被称之为低级流.处理流也被称之为高级流或者过滤流
节点流 OutputStream抽象类此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。
FileOutputStream字节输出流直接插在文件上,直接写出文件数据
创建对象:
FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。 FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 FileOutputStream(File file, boolean append) –追加 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
注意: 以上构造方法中, 如果参数指向的文件以及父目录都不存在, 将会抛出FileNotFoundException异常!
如果参数指向的文件不存在, 但文件的所在目录存在, 将不会抛异常, 程序会自动创建该文件!
FileOutputStream代码案例package io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class FOSDemo {
public static void main(String[] args) throws Exception {
//1.创建一个FileOutputStream流,将数据输出到./test.dat文件中
//File file = new File("./test.dat");
//如果没有该文件,会自动创建文件
//true 表示开启流的追加模式,就不会覆盖原有的内容了
//默认是false,是覆盖模式
OutputStream out =
new FileOutputStream("./test.dat",true);
//2.开始向文件写入数据
//write写出一个字节
//此处写入的是一个int,int占4字节
// x x x x
//1个字节等于8个二进制位
//0 1 10 11 100
//00000000 00000000 00000000 00000001
//00000000 00000000 00000001 00000001
out.write(1);//00000001
out.write(97);//a
out.write(98);//b
out.write(99);//c
out.write(100);//d
out.write(255);
out.write(257);//1
//write写一个byte数组
//getBytes将字符串转成字节数组
out.write("ABCDE".getBytes());
//输出byte数组的一部分 表示从下标1处(G)开始,输出后面的3个字节(包括G,GHI)
//out.write("FGHIJ".getBytes(),1,3);
//3.关闭流(释放资源)
System.out.println("成功的将数据写入到了test.dat中");
out.close();
}
}
InputStream抽象类
此抽象类是表示字节输入流的所有类的超类/抽象类。
FileInputStream子类直接插在文件上,直接读取文件数据。
创建对象
FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String pathname)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
FileInputStream代码案例package io;
import java.io.FileInputStream;
import java.io.InputStream;
public class FISDemo {
public static void main(String[] args) throws Exception {
//File file = new File("./test.dat");
//FileInputStream in = new FileInputStream(file);
InputStream in =
new FileInputStream("./test.dat");
// System.out.println(in.read());//a
// System.out.println(in.read());//b
// System.out.println(in.read());//c
// System.out.println(in.read());//d
// System.out.println(in.read());//e
// System.out.println(in.read());//f
// System.out.println(in.read());//g
// System.out.println(in.read());//h
// System.out.println(in.read());//-1 表示没有内容啦
//重复的读取可以利用循环来完成
//定义变量,用于存储每次从文件中读取的数据(1个字节)
int data;
while ((data = in.read())!=-1){
System.out.println(data);
}
//关闭流
in.close();
}
}
复制文件
复制文件代码案例
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class CopyDemo {
public static void main(String[] args) throws Exception {
//1.创建读取要复制的文件的流
FileInputStream fis =
new FileInputStream("./DAY02/demo.jpg");
//2.创建输入要创建的目标文件
FileOutputStream fos =
new FileOutputStream("./DAY02/demo_cp.jpg");
long start = System.currentTimeMillis();
//3.利用输入流,将demo.jpg的字节读取到内存中
int data;
while ((data=fis.read())!=-1){
//4.每读取一个字节,要将字节写入到目标文件中
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕,共花费了:"+(end-start)+"ms");//16882ms
//5.关闭流
fis.close();
fos.close();
}
}
快读写优化代码案例
package io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyDemo2 {
public static void main(String[] args) throws Exception {
//1.创建读取要复制的文件的流
FileInputStream fis =
new FileInputStream("./DAY02/demo.jpg");
//2.创建输入要创建的目标文件
FileOutputStream fos =
new FileOutputStream("./DAY02/demo_cp.jpg");
//3.利用输入流,将demo.jpg的字节读取到内存中
byte[] data = new byte[1024*10];//10kb
int len;
long start = System.currentTimeMillis();
while ((len = fis.read(data))!=-1){
//fos.write(data);
fos.write(data,0,len);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕,共花费了:"+(end-start)+"ms");//3ms
//5.关闭流
fis.close();
fos.close();
}
}
写入字符串
package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
public class WriterStringDemo {
public static void main(String[] args) throws Exception {
//向demo.txt文件写入字符串
FileOutputStream fos =
new FileOutputStream("./DAY02/demo.txt");
String line = "bi,bi,im' sheep~bi,bi,im' sheep~";
fos.write(line.getBytes(StandardCharsets.UTF_8));
fos.write("比,比,安慕希~比,比,安慕希~".getBytes(StandardCharsets.UTF_8));
fos.close();
}
}
简易笔记本
package io;
import javax.sound.sampled.Line;
import javax.swing.text.html.StyleSheet;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class TestNotes {
public static void main(String[] args) throws Exception {
System.out.println("请开始输入内容,单独输入exit退出");
FileOutputStream fos = new FileOutputStream("./DAY02/note.txt");
Scanner scanner = new Scanner(System.in);
//构建一个死循环
//for(;;) for循环的死循环
while (true) {
//每次循环都接受在控制台输入的一句字符串
String line = scanner.nextLine();
//先判断line是否是exit,如果是,停止录入
//String类中已经帮我们重写了equals方法
//if("exit".equals(line)){
//equalsIgnoreCase 忽略大小写
if ("exit".equalsIgnoreCase(line)) {
System.out.println("录入已停止");
break;
}
fos.write(line.getBytes(StandardCharsets.UTF_8));
}
fos.close();
}
}
文件追加模式案例
package io;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class TestNotes2 {
public static void main(String[] args) throws Exception {
System.out.println("请开始输入内容,单独输入exit退出");
FileOutputStream fos =
new FileOutputStream("./DAY02/note.txt",true);
Scanner scanner = new Scanner(System.in);
while (true) {
String line = scanner.nextLine();
if ("exit".equalsIgnoreCase(line)) {
System.out.println("录入已停止");
break;
}
fos.write(line.getBytes(StandardCharsets.UTF_8));
}
fos.close();
}
}
处理流
缓冲流
- BufferedOutputStream缓冲输出流
- BufferedInputStream 缓冲输入流
package io;
import java.io.*;
public class CopyDemo3 {
public static void main(String[] args) throws Exception {
//给源文件插上低级流,文件输入字节流
FileInputStream fis = new FileInputStream("./DAY02/demo.jpg");
//为fis插上高级流,缓冲字节输入流
BufferedInputStream bis = new BufferedInputStream(fis);
//给目标文件插上低级流,文件输出字节流
FileOutputStream fos = new FileOutputStream("./DAY02/demo_cpp.jpg");
//为fos插上高级流,缓冲字节输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);
//测试单字节的读写
int d;
long start = System.currentTimeMillis();
//由于此处读的字节是经过高级流处理过的,所以使用高级流读
while((d=bis.read())!=-1){
bos.write(d);
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start)+"毫秒");//69ms
//关闭流,只需要关闭高级流即可会自动关闭和他相连的低级流
bis.close();
bos.close();
}
}
flush代码案例
package io;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
public class BOSFlushDemo {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("./DAY02/bos.txt");
//缓冲流内部默认是一个8K的字节数组,写出的数据会先存入到数组中,知道数组装满了才会写出
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("我们的祖国是花园".getBytes(StandardCharsets.UTF_8));
System.out.println("写出完毕");
bos.close();
}
}
对象流
Person代码
package io;
import java.io.Serializable;
import java.util.Arrays;
public class Person implements Serializable {
static final long serialVersionUID = 42L;
private String name;//姓名
private Integer age;//年龄
private String gender;//性别
private transient String[] otherInfo;//其他信息
private int salary;//薪资
//生成全参构造,set,get,toString
//alt+insert
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
", gender='" + gender + ''' +
", otherInfo=" + Arrays.toString(otherInfo) +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String[] getOtherInfo() {
return otherInfo;
}
public void setOtherInfo(String[] otherInfo) {
this.otherInfo = otherInfo;
}
public Person(String name, Integer age, String gender, String[] otherInfo) {
this.name = name;
this.age = age;
this.gender = gender;
this.otherInfo = otherInfo;
}
}
OOSDemo案例
package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class OOSDemo {
public static void main(String[] args) throws Exception {
String name="冯翔";
int age = 24;
String gender = "男";
String[] otherInfo = {"是一个男的","来自北京","爱好女","是个帅气的海王"};
Person p = new Person(name, age, gender, otherInfo);
//Person中重写了toString方法
System.out.println(p);
//将Person对象写入到person.obj文件中
FileOutputStream fos = new FileOutputStream("./DAY02/person.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
System.out.println("写出完毕");
oos.close();
}
}
OISDemo案例
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.ObjectInputStream;
public class OISDemo {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("./DAY02/person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
//readObject 读取文件中的对象,返回的是Object类型
Person p = (Person) ois.readObject();
p.setAge(18);
System.out.println(p);
ois.close();
}
}
字节流和字符流
在Java中,根据处理的数据单位不同,分为字节流和字符流。
字节流: 一个字节(byte)一个字节的去读取, 或者写出
字符流: 一个字符一个字符的去读取, 或者写出
字节流字节流(stream):针对二进制文件(文本,图片,音频,视频…等)
InputStream(包含input都是输入流)
– FileInputStream
– BufferedInputStream
– ObjectInputStream
OutputStream(包含output都是输出流)
– FileOutputStream
– BufferedOutputStream
– ObjectOutputStream
字符流字符流(Reader,Writer):针对文本文件,读写容易发生乱码现象,在读写时最好指定编码集为utf-8
Reader(Reader结尾的都是字符输入流)
– FileReader
– BufferedReader
– InputStreamReader
Writer(Writer结尾的都是字符输出流)
– FileWriter
– BufferedWriter
– OutputStreamWriter
– PrintWriter/PrintStream
转换字符流 OutputStreamWriter 代码案例package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
public class OSWDemo {
public static void main(String[] args) throws Exception {
//向osw.txt中写入字符串
FileOutputStream fos = new FileOutputStream("./DAY02/osw.txt");
//在创建转换流时,通常需要指定第二个参数,明确使用的编码
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
osw.write("我可以接收你的所有的小脾气");
osw.write("我可以带你吃很多的好东西");
System.out.println("写出完毕");
osw.close();
}
}
InputStreamReader
代码案例
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class ISRDemo {
public static void main(String[] args) throws Exception {
//将osw.txt的内容读取出来
FileInputStream fis = new FileInputStream("./DAY02/osw.txt");
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
int d;
while((d=isr.read())!=-1){
System.out.print((char)d);
}
isr.close();
}
}
缓冲字符流
PrintWriter
代码案例
package io;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
public class PwDemo {
public static void main(String[] args) throws Exception {
PrintWriter pw = new PrintWriter("./DAY02/pw.txt","UTF-8");
pw.println("大河向东流");
pw.println("天上的星星参北斗啊~~~");
System.out.println("写出完毕");
pw.close();
}
}
代码案例2
package io;
import java.io.*;
import java.util.Scanner;
public class PWDemo2 {
public static void main(String[] args) throws Exception {
//向pw2.txt文件写入内容
//1.创建文件字节输出流,是一个低级流
//加上true可以将当前的流改为追加模式
FileOutputStream fos = new FileOutputStream("./DAY02/pw2.txt",true);
//2.创建一个转换字符输出流,是一个高级流,
//衔接字符与字节的流,将写出的字符串转换为字节
OutputStreamWriter oos = new OutputStreamWriter(fos);
//3.缓冲输出流,是一个高级流,块写入到文件中
BufferedWriter bw = new BufferedWriter(oos);
//4.缓冲字符输出流
PrintWriter pw = new PrintWriter(bw,true);
Scanner scanner = new Scanner(System.in);
System.out.println("请输入想要录入到文档中的内容");
//接收控制台输入字符串
//完成简易的记事本,控制台输入每行字符串,按行写入文件,单独输入exit,退出
while(true){
//crtl+shift+↑↓ 可以上下移动当前行代码
String s = scanner.nextLine();
//equalsIgnoreCase 忽略大小写比较
if("exit".equalsIgnoreCase(s)){
break;
}
pw.println(s);
}
pw.close();
}
}



