Java基础总结---IO流
来源:互联网 发布:金钻淘宝店有哪些 编辑:程序博客网 时间:2024/06/05 11:58
二. IO流
一. 自己的理解
1.IO流的分类(比较熟悉的)
1. 字节流和字符流--最开始是字节流,也就是二进制流.但是为了便于人的读写,使用字符流将其转化为可读的Unicode编码 字节流--(抽象父类)InputStream,OutputStream. (具体子类) : 对象IO流-- ObjectInputStream,ObjectOutputStream. 文件IO流--FileInputStream,FileOutputStream. // 太久没用都忘了 字符流--Reader,Writer.(抽象类) (具体子类):文件IO流--FileReader,FileWriter2. 处理流--对上面流进行包装包装流--BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter. 转换流--InputStreamReader,OutputStreamWriter.
二. 不熟悉的地方
1.字节流的使用
1. 字节输出流的使用
class OStream { // 这里直接抛出IOException,抛出异常,为了版面整洁,下面也一样 public static void main(String[] args) throws IOException{ // 创建一个新文件 File file = new File("/home/z/IOStream.txt"); // OutputStream是一个抽象类,不能创建具体实例. // 创建字节输出流对象OutputStream OutputStream os = new FileOutputStream(file); // 创建一个字节数组,字节数组会转换成什么. byte[] b = new byte[]{49,65,97}; // 开始写入 os.write(b); // 关闭资源 os.close(); }}
2. 字节输入流的使用
class IStream{ public static void main(String[] args) throws IOException{ // 获取文件位置 File file = new File("/home/z/IOStream.txt"); // 创建对象 InputStream is = new FileInputStream(file); // 创建一个 字节数组用来读取文件内容,如果文件很大,byte数组可以设置很大. byte[] b = new byte[8]; int i; // 这里用i去接收读取的返回值,但是直接判断is.read(b)!=-1也可以. // 读文件的时候如果到达最后没有内容,read()方法会返回-1,所以用这个来作为条件 while(( i = is.read(b)) != -1){ // 输出到控制台,也可以运用上输出流将其写入文件 // 因为i是int型,所以输出来是一个Unicode整数.要用char来强转 System.out.print((char)i+" "); } // 关闭资源 is.close(); } }
输出结果:1 A a
2.字符流的使用
1. 字符输出流的使用
class CharWriter{ public static void main(String[] args) throws IOException{ // 创建文件对象 File file = new File("/home/z/writer.txt"); // 创建字符输出流Writer对象,这里Writer也是一个抽象类,只能new具体子类实例 Writer writer = new FileWriter(file); // 之前的字节流只能将ASCII的字符写出,不能写出中文. //本来想尝试是否能写出字符串形式的中文,结果发现OutputStream的write()方法参数只能传输字节数组,一个int值 OutputStream os = new FileOutputStream(file); // 这里int值超过byte的范围0~127,在char的范围类.在String的 os.write(34443); // 在文件中查看会是一个\8B 或者是一个乱码.所以字节流是不能写出中文的 os.close(); // 使用Writer向文件中写出字符串形式的中文 writer.write("你好"); // 关闭资源 writer.close(); }}
writer.txt中的内容是:你好
2. 字符输入流的使用
class CharReader{ public static void main(String[] args) throws IOException{ //创建文件对象 File file = new File("/home/z/writer.txt"); // 创建字符输入流Reader对象,Reader也是一个抽象类 Reader reader = new FileReader(file); // 从文件中读取内容,读取的内容都是整数,都是需要强转成char类型,才能变成字符. int i; while((i = reader.read()) != -1){ System.out.println((char)i); } // 关闭资源 reader.close(); }}
输出结果是:
你
好
3.对象字节流的使用
1. 对象输出流
/** * 创建一个类,如果要实现写出对象,则类需要实现Serializable借口 */class Animal implements Serializable{ private int age; private String name; public Animal(int age, String name){ this.age = age; this.name = name; } public int getAge(){ return age; } // 重写toString()方法. @Override public String toString() { return "Animal [age=" + age + ", name=" + name + "]"; }}class ObOStream{ public static void main(String[] args) throws IOException{ // 创建一个对象 Animal animal = new Animal(10,"cat"); // 创建一个对象输出流ObjectOutputStream // 无参构造器是protected,一般是不能访问的.所以需要用到下面的构造器 // public ObjectOutputStream(OutputStream out) FileOutputStream fos = new FileOutputStream(new File("/home/z/object.txt")); ObjectOutputStream oos = new ObjectOutputStream(fos); // 这么写出到文件中会出现乱码,刚开始想可能是缓存的问题,但这里是没有用到缓冲区的. // 这里是一个经常犯错的地方. oos.writeObject(animal); oos.close(); }}
百度之后,才发现写出对象的时候用的是字节流,之前说过,字节流是二进制的,所以我们写出数据的时候是用二进制写出的.当我们去用文本编辑器打开时,是不能将二进制类型转换成Unicode类型的.只有当用字符流写出时文本编辑器才会分辨出Unicode编码.
所以在进行纯文本的输入输出的时候,一般是使用字符流,其余的例如音频,视频,图片等都使用字节流
2. 对象输出流下面用输入流读取.虽然写出的是二进制,不能识别.但是用输入流读取的时候也是二进制流,所以读出的时候就是写入的时候的样子.
class ObIStream{ public static void main(String[] args) throws IOException,ClassNotFoundException{ // 创建文件输入流 FileInputStream fis = new FileInputStream(new File("/home/z/object.txt")); // 创建对象输入流,并将fis作为参数传入 ObjectInputStream ois = new ObjectInputStream(fis); // 从文件中读取数据.转换为Animal对象对象, // 读取多个对象的话怎么去判断结束条件. Animal animal = (Animal)ois.readObject(); ois.close(); // 直接调用重写的toString()方法.显示在控制台 System.out.println(animal.toString()); }}
输出结果:
Animal [age=10, name=cat]
3. 多个对象的输出流.
class ManyObOStream{ public static void main(String[] args) throws IOException{ // 两种思路是一样的,因为这个对象都能存储多个对象,且只持有一个引用. // 1.用一个对象数组将同一个类型的数组存储起来,写入到文件中 // 2.用一个list将对象加入到集合中,下面使用list ArrayList<Animal> list = new ArrayList<>(); // 产生多个不同的对象,使用for循环来产生下标 for(int i = 0; i < 10; i++){ int age = i; String name = "cat"+i; // 创建不同的Animal对象 Animal a = new Animal(age, name); // 添加到list中 list.add(a); } // 创建对象输出流对象 FileOutputStream fos = new FileOutputStream(new File("/home/z/manyObject.txt")); ObjectOutputStream oos = new ObjectOutputStream(fos); // 将list写出到文件中 oos.writeObject(list); oos.close(); }}
4. 多个对象输入流,将其显示到控制台
class ManyObIStream{ public static void main(String[] args) throws IOException,ClassNotFoundException{ // 这里输入流与之前的没有什么区别,只是将之前的读出的对象改为ArrayList类型 FileInputStream fis = new FileInputStream(new File("/home/z/manyObject.txt")); ObjectInputStream ois = new ObjectInputStream(fis); ArrayList<Animal> list = (ArrayList<Animal>) ois.readObject(); ois.close(); // 将list里面数据输出 for(int i = 0; i < list.size(); i++){ System.out.println(list.get(i).toString()); } }}
输出结果:
Animal [age=0, name=cat0]
Animal [age=1, name=cat1]
Animal [age=2, name=cat2]
Animal [age=3, name=cat3]
Animal [age=4, name=cat4]
Animal [age=5, name=cat5]
Animal [age=6, name=cat6]
Animal [age=7, name=cat7]
Animal [age=8, name=cat8]
Animal [age=9, name=cat9]
当需要将多个对象输出到文件中时,可以将多个对象封装到一个数组或者集合中,这样写出一个数组或者集合时,将多个对象一起写出到文件中.
有个问题:ArrayList是一个引用指向它,用下标去维护.写出到文件的时候,根据输出的结果可以看出, Java 将当前引用的所有引用指向的对象都写出到了文件中.所以这里也可以实现Java中的深克隆.即内容相同,引用却不同,也就是产生了一个新的对象. 浅克隆是指只复制了引用,实际的对象是没有变的.
// TODO
为什么要定义一个int i ;(i= is.read()) != -1, 可以直接用 is.read() != -1 来判断的.
4. 处理流的使用
比较熟悉的主要是缓冲流:
字节流:BufferedInputStream,BufferedOutputStream.
字符流:BufferedReader,BufferedWriter.
class BufferedChar{ public static void main(String[] args) throws IOException{ public static void main(String[] args) throws IOException { // 重复写入一个txt文件,使用字符流,计算时间,看缓冲流和不用缓冲流的时间差 int c1 = 0; // 用来计算不用缓冲读取的次数 int c2 = 0; // 用来计算用缓冲读取的次数 // 创建字符输出流对象 FileWriter fw = new FileWriter(new File("/home/z/buffer.txt")); FileReader fr = new FileReader(new File("/home/z/buffer.txt")); // 获取系统的当前时间 long start1 = System.currentTimeMillis(); // 使用for循环来不停的写入 for(int i = 0; i < 100000; i++){ fw.write("你好,我是一个字符"); } while((fr.read()) != -1) { c1++; fr.read(); } long end1 = System.currentTimeMillis(); BufferedWriter bw = new BufferedWriter(new FileWriter(new File("/home/z/buffer2.txt"))); BufferedReader br = new BufferedReader(new FileReader(new File("/home/z/buffer2.txt"))); char[] c = new char[1024]; long start2 = System.currentTimeMillis(); for(int i = 0; i < 100000; i++) { bw.write("你好,我是一个字符"); } while(br.read() != -1) { c2++; br.read(c);// 但是这里不能输出实际读取的字符 } long end2 = System.currentTimeMillis(); System.out.println("不用缓冲的读写总时间="+(end1-start1)+"c1="+c1); System.out.println("使用缓冲区的读写时间="+(end2-start2)+"c2="+c2); } }}
输出结果:
不用缓冲的读写总时间=95 c1=449666
使用缓冲区的读写时间=46 c2=869
最开始在读取的时候将读取的内容在控制台输出,如果次数过多,会造成时间差很大.所以去掉输出语句后,发现差距并不大,但是从c1 和 c2可以看出来,次数明显的减少.不过使用缓冲区的时候不能将读取的内容显示出来,只有一个readLine()方法,能够将读取的内容显示,不过readLine()是一个无参构造参数,只能根据一行来读取.
主要是在进行IO读取的时候如果数据比较大,那么对IO流的访问会很频繁,而IO流的访问时间一般会很长,所以为了降低对IO流的访问,所以将数据先存储在缓冲流里面,等读取的数据满了之后一次性写出.
5.转换流的使用
InputStreamReader:将字节流转换为字符流(An InputStreamReader is a bridge from byte streams to character streams)
OutputStreamWriter:将字符流转换为字节流(An OutputStreamWriter is a bridge from character streams to byte streams)
这里为什么会有区别?个人理解是:一般读取数据的时候用的比较多的是输入流,即InputStream,比如从网络获取的数据都是字节流.但是读取来的数据需要进行解析,就是将字节流转换为字符流,这样人们就能获取到里面的字符型数据. 而输出流的时候是人们写入字符型的数据,写出的时候将其转换为字节流,相当于二进制流,传输比较方便.所以输出流的时候需要字符转字节.
6.流的混合使用
在别的博客上看到了一个总结:
1. 用InputStream去获取输入流2. 用InputStreamReader将字节流转换为字符流3. 用BufferedReader开始一次性读取多个字符.
7.一些见过的流
1. DataInputStream,DataOutputStream: 不知道和其他流的区别在哪.
2. PrintStream: 标准输出流,System.out就是一个PrintStream. 不仅可以将内容输出到控制台,也可以将内容输出到文件中.
- java基础IO流总结
- Java基础总结---IO流
- 【Java基础】IO总结
- 黑马程序员---Java基础总结--IO流
- 黑马程序员-java基础-IO流总结
- 黑马程序员---java基础---IO流总结
- Java基础之IO流学习总结
- Java基础-20总结,递归,IO流
- Java基础学习之io流总结
- Java IO 基础总结(一)
- java IO基础 学习总结
- JAVA 基础IO流
- java基础:IO流
- Java基础-->IO流
- Java IO流基础
- java基础---IO流
- Java基础:IO流
- Java基础---IO流
- POJ3617
- python协程与异步I/O
- leetcode 26. Remove Duplicates from Sorted Array
- mysql-jdbc 6.0 serverTimezone参数详解
- 抓取360图片
- Java基础总结---IO流
- 俄国资安服务商发现可关闭英特尔管理引擎的方式
- VMware共享文件夹
- Python3之阻塞I/O,非阻塞I/O及I/O多路复用
- pdf在线预览
- HOSTOJ 1101: 那些四位数
- 阿里云视频技术专家柿蒂:视频AI in传媒九大业务场景解析
- 事件绑定
- Why is Java Future.get(timeout) & httpclient Not Reliable?