Day14-Java I/O
Java I/O流
流的概念
内存与存储设备之间的通道
流的分类
按方向
- 输入流:将存储设备中的内容读取到内存中
- 输出流:将内存中的内容写入存储设备中
按单位
- 字节流:以字节为单位,可以读取数据(任意数据)
- 字符流:以字符为单位,只能读写文本数据
按功能
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础上增强了功能
字节流
两个抽象类,是所有输入输出类的超类,定义了一些方法
- InputStream
- OutputStream
文件字节流
-
FileInputStream
- public int read(byte[] b),从流中读取多个字节,将读取内容存入b数组,返回实际读到的字节数,如果达到文件底部,返回-1
package IIIOOO; import java.io.File; import java.io.FileInputStream; public class FiileInputStramT { public static void main(String[] args) throws Exception { //1.创建文本对象 FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\haha.txt"); //2.读取文件 //2.1单个字节读取 int data = 0; while ((data=fis.read())!=-1){ System.out.println((char)data); //效率慢,一次只能读取一个 } System.out.println("-------------------------"); //2.2多个字节读取 byte[] arr = new byte[3]; //2.1已经将文件读取完了,得注释后才有效果 int count = 0; while ((count=fis.read(arr))!=-1){ System.out.print(new String(arr,0,count)); //offset开始位置,count--->要解码的字节数 } fis.close(); } }
-
FileOutputStream
- public int write(byte[] b),一次性写入多个字节,将b数组中的所有字节写入输出流
package IIIOOO; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutStreamT { public static void main(String[] args) throws IOException { //1.创建对象 FileOutputStream fis = new FileOutputStream("D:\\code\\JavaSE\\files\\haha.txt",true); //添加true,写入字节时,追加而不是覆盖 //2.写入文件 //2.1单个字节写入 fis.write(98); fis.write('c'); fis.write('w'); //2.2多个字节书写 String s = "Hello World!"; fis.write(s.getBytes()); //3.关闭 fis.close(); } }
复制文件
package IIIOOO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\2.jpg");
FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\1.jpg");
//2.读取与写入
byte[] arr = new byte[1024];
int count = 0 ;
while ((count=fis.read(arr))!=0){
fos.write(arr,0,count);
}
//3.关闭
fis.close();
fos.close();
}
}
字节缓冲流
- BufferedInputStream/BufferedOutputStream,增强节点流或者底层流
1.减少访问磁盘的次数,提高i/o的效率
2.数据存储在缓冲区中,flush将缓冲区中的内容写入文件中,也可以直接close
package IIIOOO;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class BufferedInputStreamT {
public static void main(String[] args) throws Exception {
//1.创建对象
FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\haha.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.读取数据
byte[] arr = new byte[1024]; //自己写一个缓冲区为1k
int count=0;
while ((count=bis.read(arr))!=-1){
System.out.println(new String(arr,0,count));
}
while ((count=bis.read())!=-1){ //自带缓冲区为8k
System.out.println(new String(arr,0,count));
}
//3.关闭
fis.close();
bis.close();
}
}
package IIIOOO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class ObjectOutputStreamT {
public static void main(String[] args)throws Exception {
//1.创建对象流
FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student s1 = new Student("程晨橙",18); //利用transient修饰,可以让部分属性不被序列化
Student s2 = new Student("黄黄华南",24);
//2.写入对象
// oos.writeObject(s1);
// oos.writeObject(s2);
List<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
oos.writeObject(list);
//3.关闭
fos.close();
oos.close();
}
}
对象流
ObjectOutputStream/ObjectInputStream
特点:
1.增强了缓冲区功能
2.增强了读写八种基本数据类型和字符串功能
3.增强了读写对象的功能
4.写入的对象类必须实现一个接口Serializable(仅起标识可以序列化的作用)
使用流传输对象的过程称为序列化、反序列化
序列化
将对象写入存储设备中
package IIIOOO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamT {
public static void main(String[] args)throws Exception {
//1.创建对象流
FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student s1 = new Student("程晨橙",18);
Student s2 = new Student("黄黄华南",24);
//2.写入对象
oos.writeObject(s1);
oos.writeObject(s2);
//3.关闭
fos.close();
oos.close();
}
}
反序列化
从存储设备中读取对象
package IIIOOO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.List;
public class ObjectInputStramT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\对象文件.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取对象
// Student s =(Student)ois.readObject();
List<Student> list = (List<Student>)ois.readObject();
System.out.println(list.toString());
//3.关闭
ois.close();
}
}
注意事项
1.当创建对象的类中包含类时,该类也需要实现Serializable接口
2.序列化与反序列化类的版本号id需要相同,否则会报错
3.使用transient(瞬间的)修饰不想序列化的属性
4.静态属性不能序列化
5.可以使用集合放置对象,再将集合写入存储设备
字符流
UTF-8中汉字为三个字节一个字,如果使用字节流,则会出现乱码问题
- Reader:字符输入流
package IIIOOO;
import java.io.FileReader;
public class FileReaderT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileReader frd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");
//2.读取数据
// int data = 0;
// while ((data=frd.read())!=-1){
// System.out.print((char)data);
// }
char[] arr = new char[1024];
int count=0;
while ((count=frd.read(arr))!=-1){ //第一次直接读取1k的数据存放再arr中,后续在缓冲区中读取,提高i/o效率
System.out.println(new String(arr,0,count));
}
//3.关闭
frd.close();
}
}
- Writer:字符输出流
package IIIOOO;
import java.io.FileWriter;
public class FileWriterT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileWriter fwr= new FileWriter("D:\\code\\JavaSE\\files\\中文.txt",true);
//2.写入数据
String s = "\r\n早睡早起";
fwr.write(s);
//3.关闭
fwr.close();
}
}
复制文件
只能复制文本文件
package IIIOOO;
import java.io.FileReader;
import java.io.FileWriter;
public class CopyTxt {
public static void main(String[] args) throws Exception { //只能复制文本文件
//1.创建对象流
FileReader frd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");
FileWriter fwr = new FileWriter("D:\\code\\JavaSE\\files\\中文副本.txt");
//2.复制
char[] arr = new char[1024];
int count = 0;
while ((count=frd.read(arr))!=-1){
fwr.write(new String(arr,0,count));
fwr.flush();
}
//3.关闭
frd.close();
fwr.close();
}
}
字符缓冲流
- 缓冲流:BufferedReader/BufferedWriter
- 高效读写
- 支持输入换行符
- 可以一次写一行、读一行
package IIIOOO;
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReaderT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileReader fwd = new FileReader("D:\\code\\JavaSE\\files\\中文.txt");
BufferedReader bwd = new BufferedReader(fwd);
//2.读取数据
// char[] arr = new char[1024];
// int count = 0 ;
// while ((count=bwd.read(arr))!=-1){
// System.out.println(new String(arr,0,count));
// }
String line = null;
while ((line=bwd.readLine())!=null){
System.out.println(line);
}
}
}
package IIIOOO;
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferedWriterT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileWriter fwr = new FileWriter("D:\\code\\JavaSE\\files\\中文.txt");
BufferedWriter bwr = new BufferedWriter(fwr);
//2.写入数据
for (int i = 0; i <10 ; i++) {
bwr.write("勤勤恳恳");
bwr.newLine();
bwr.flush();
}
}
}
打印流
-
封装了print()/printn()方法,支持写入后换行
-
支持数据原样打印
打印会覆盖?
package IIIOOO;
import java.io.PrintWriter;
public class PrintWriterT {
public static void main(String[] args) throws Exception {
//1.创建对象流
PrintWriter pwr = new PrintWriter("D:\\code\\JavaSE\\files\\中文.txt");
//2.写入数据
pwr.println("尝试打印");
pwr.println(3.1415926);
pwr.println('x');
pwr.print("?");
pwr.write(98);
//3.关闭
pwr.close();
}
}
转换流
- 桥转换流:InputStreamReader/OutputStreamWriter
- 可以将字节流转换为字符流
- 可设置字符的编码方式
package IIIOOO;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class OutputStreamWriterT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileOutputStream fos = new FileOutputStream("D:\\code\\JavaSE\\files\\转换流.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
//2.写入数据
for (int i = 0; i <10 ; i++) {
osw.append("好好学习,天天向上\r\n");
}
//3.关闭
osw.close();
}
}
package IIIOOO;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class InputSteamReaderT {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileInputStream fis = new FileInputStream("D:\\code\\JavaSE\\files\\转换流.txt");
InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //字符编码
//2.读取数据
// byte[] arr = new byte[1]; //一个中文三个字节,所以一个字节时将会乱码
// int count =0;
// while ((count=fis.read(arr))!=-1){
// System.out.println(new String(arr,0,count));
// }
int data = 0;
while ((data=isr.read())!=-1){
System.out.print((char)data);
}
//3.关闭
isr.close();
}
}