您现在的位置是:网站首页>javajava

IO流介绍

deling2019年5月17日java448人已围观

简介IO流介绍,以及File类的基本使用!

IO中的四大抽象类

InputStream:

此抽象类是所有字节输入流的父类,数据单位为字节,因为是抽象类,所以不可以实例化,数据的读取只能通过它的子类来实现。例如: FileInputStream(文件字节输入流)

方法:

read(): 读取一个字节的数据,并将字节的值作为int类型返回(0-255之间的一个值)。如果未读出字节则返回-1(返回值为-1表示读取结束)。

close(): 关闭输入流,常用来关闭相关系统资源

OutputStream :

此抽象类是所有字节输出流的父类,数据单位为字节,因为是抽象类,所以不可以实例化,数据的读取只能通过它的子类来实现。例如: FileOutputStream(文件字节输出流)

方法 :

write(): 向目的地写入一个字节

close():  关闭输出流,常用来关闭相关系统资源

Reader :

此抽象类是用来读取的字符流,数据单元为字符,例如: FileReader(文件读取)

方法:

read(): 读取一个字符的数据,并将字符的值作为int类型返回(0-65535之间的一个值,即Unicode值)。如果未读出字符则返回-1(返回值为-1表示读取结束)。

close(): 关闭输入流,常用来关闭相关系统资源

Writer:

此抽象类是用来写入的字符流,数据单元为字符,例如: FileWriter(文件写入)

方法:

writer(): 向输入流写入一个字节

close(): 关闭输出流,常用来关闭相关系统资源

流的细分:

从流的方向:

输入流: InputStream Reader 从数据源输入到程序   例如: FileInputStream

输出流: OutputStream Writer 从程序输出到数据源  例如: FileOutStream

从流的数据单元:

字节流: 一般都是以Stream 结尾的,数据单位是字节,一般用来读取音频,图片  例如:FileInputStream

字符流: 一般都是Reader和Writer结尾的,数据单位是字符,一个字符占两个字节 例如:FileReader和 FileWriter 字符输入和字符输出流,一般用来读取纯文本文件

注意:

在java语言中,所有的字节流都以Steam结尾 所有的字符流都含有Reader和writer。

从流的功能:

节点流: 直接从数据源到程序读写程序

处理流: 不直接从数据源到程序,通过其他流的处理对程序提高性能或者提高程序的灵活型,又叫包装流

字符变换为字节的过程叫做编码

字节变换为字符的过程叫做解码

文件字节输入流(FileInputStream)

一个字节一个字节输入:

import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileInputStream fileInputStream = null;        
        //创建文件字节输入流,会出现文件不存在异常
        try {              
            // 输入流必须保证又这个文件,否则就会出现报错
            fileInputStream = new FileInputStream("java.txt");            
            // 操作流
            // 读流
            int temp = 0;  // 定义一个临时变量,来接收输入流
            //temp指的是本次读取的真实长度,temp等于-1时表示读取结束
            while ((temp = fileInputStream.read()) != -1) {            
            // 记得把临时变量的int类型变为char类型
                System.out.println((char) temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        // 做判断,只有当输入流不为空时,则才能关闭相关的系统资源
            if (fileInputStream != null) {                
            try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

通过字节数组,将文件中的内容用String读出来:

import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileInputStream fileInputStream = null;        
        try {            // 创建文件字节输入流
            // 创建FileInputStrream 会出现FileNotFoundException异常,需要对它做出处理
            fileInputStream = new FileInputStream("java.txt");  // 输入流必须保证又这个文件,否则就会出现报错
            // 操作流
            // 用字节数组读取,每次以2的长度来读取
            byte[] bytes = new byte[2];            
            // 定义一个临时变量
            int temp = 0;             //temp指的是本次读取的真实长度,temp等于-1时表示读取结束
            while ((temp = fileInputStream.read(bytes)) != -1) {                
            // 把字节数组通过字符串的方式输出
                // String的构造方法:数组,开始索引,数组长度
                String str = new String(bytes, 0, temp);
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        // 当输入流不为空时,执行相关系统资源的释放
            if (fileInputStream != null) {                
            try {                    // 因为相同系统文件的释放,会出现IOException异常,需要捕获
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件字节输出流(FileOutputStream)

以字节数组来写入:

import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileOutputStream fileOutputStream = null;        
        try {            
        // 创建文件字节输出流,会出现FileNotFoundException异常,需要对它做出处理
            fileOutputStream = new FileOutputStream("java.txt");
            // 输入流必须要有这个文件,不然报错误,但输出流,可以没有这个文件,它会帮你创建这个文件
            // 操作流   以字节数组来写入
            // 定义一个字符串
            String s = "pythonjava";            
            // 将字符串转换为byte字节数组
            byte[] bytes = s.getBytes();            
            // 将字节数组写入到java.txt中
            fileOutputStream.write(bytes);            
            //刷新flush,强制把输出流中输出,防止堵塞
            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        // 当输出流不为空时,则可以使用close方法
            if (fileOutputStream != null) {                
            // 调用close方法会出现IOException异常,需要对它做出处理
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

文件字节流的复制和粘贴:

import java.io.*;public class Demo1 {    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;        
        try {            
        // 创建文件字节输入流
            fileInputStream = new FileInputStream("java.txt");            
            // 创建文件字节输出流
            fileOutputStream = new FileOutputStream("D:/java.txt");            
            // 操作流
            // 定义一个临时变量,用来接受读取内容
            int temp = 0;             
            //temp指的是本次读取的真实长度,temp等于-1时表示读取结束
            while ((temp = fileInputStream.read()) != -1) {                
                // 边读编写
                fileOutputStream.write(temp);                
                // 刷新flush
                fileOutputStream.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (fileInputStream != null) {                
        try {                    
        // 关闭输出输入流
                    fileInputStream.close();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}
文件字符输入流:(FileReader)
import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileReader fileReader = null;       
        try {            
        // 创建文件字符读取流
            fileReader = new FileReader("java.txt");  // 文件必须存在
            // 创建字符数组来读取
            char[] chars = new char[6];                  
               //临时变量 接收读取 
            int temp = 0;                               
            // 当读取的内容返回-1时,就说明就已经读完,读完则需要退出
            while ((temp = fileReader.read(chars)) != -1) {
                System.out.println(new String(chars, 0, temp));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        // 只有当这个文件字符流不为空时,才释放系统相关的资源
            if (fileReader != null) {                
            try {            //  关闭系统资源
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
文件字符输出流(FileWriter)
import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileWriter fileWriter = null;        
        try {            // 创建文件字符写入流
            fileWriter = new FileWriter("D:/java.txt");  // 文件可以不存在,如果没有这个文件它将会在你指定的路径下创建文件
            String s = "pythonjavapython";
            fileWriter.write(s);            
            // 刷新
            fileWriter.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {

        } finally {            
        // 只有当这个文件字符流不为空时,才释放系统相关的资源
            if (fileWriter != null) {                
            try {       //  关闭系统资源
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
字符流的文件复制粘贴
import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        FileReader fileReader = null;
        FileWriter fileWriter = null;        
        try {            // 创建文件输出流
            fileReader = new FileReader("java.txt"); // 文件必须存在
            fileWriter = new FileWriter("D:/java.txt", true); // append true是追加文件内容,false是不追加
            // 操作流
            char[] chars = new char[5];            
            int temp = 0;//定义中间临时变量
            while ((temp = fileReader.read(chars)) != -1) {                
                // 打印输出
                System.out.println(new String(chars, 0, temp));                
                // 边读边写
                fileWriter.write(chars, 0, temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (fileReader != null) {                
            try {
                    fileReader.close();
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

处理流:

缓冲流: 当我们对文件进行读写频繁操作时,效率较低,这样推荐使用缓冲流,因为这样可以提高读写的效率,因为缓冲流是先将数组缓冲起来,然后当缓冲区存满后或者手动刷新再一次的读取到程序或者目的地,一般都是把缓冲流用来提高性能,例如:BufferedInputStream和BufferedOutputStream

注意:

在关闭流时,先关闭最外边的流,即后开的先关闭,缓存区的大小默认是8192字节,也可以使用其它的构造方法自己指定大小。

带有缓冲区的读流:
import java.io.*;
public class Demo1 {    
    public static void main(String[] args) {        
        BufferedReader bufferedReader = null;        
        try {            
            // 创建带有缓冲区的文件输入流
            // 因为处理流也叫包装类,将输入流通过处理,用来提高性能
            bufferedReader = new BufferedReader(new FileReader("java.txt"));            
            String temp = null;            
            while ((temp = bufferedReader.readLine()) != null) {
                System.out.println(temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (bufferedReader != null) {                
            try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
带有缓冲区的写流
import java.io.*;
public class Demo1 {    
public static void main(String[] args) {
        BufferedWriter bufferedWriter = null;        
        try {
            bufferedWriter = new BufferedWriter(new FileWriter("java.txt"));            
            String s = "pythonjavapython";
            bufferedWriter.write(s);
            bufferedWriter.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (bufferedWriter != null) {                
        try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

带有缓冲区的文件复制粘贴

import java.io.*;
public class Demo1 {    
    public static void main(String[] args) {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;        
        try {
            bufferedReader = new BufferedReader(new FileReader("java.txt"));
            bufferedWriter = new BufferedWriter(new FileWriter("D:/java.txt"));            
            String temp = null;            
            while ((temp = bufferedReader.readLine()) != null) {
                System.out.println(new String(temp));
                bufferedWriter.write(temp);
                bufferedWriter.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (bufferedReader != null) {                
            try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

数据写读流(DataOutputStream和DataInputStream)

注意:读的顺序要和写入的顺序要一模一样,否则不能正确读取数据。

import java.io.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class Demo {    
    public static void main(String[] args) {
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;        
        try {            
            // 写读都要同一个文件,不然就会报错
            // 创建数据读写流
            dataOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/java2.txt")));
            dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream("D:/java2.txt")));
            dataOutputStream.writeInt(10);
            dataOutputStream.writeChar('a');
            dataOutputStream.writeBoolean(true);            
            // 刷新
            dataOutputStream.flush();            
            // 读取
            System.out.println(dataInputStream.readInt());
            System.out.println(dataInputStream.readChar());
            System.out.println(dataInputStream.readBoolean());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
            if (dataOutputStream != null) {                
            try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            
            if (dataInputStream != null) {                
            try {
                    dataInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字节转换流:InputStreamReader(字节输入流转为字符输出流)和OutputStreamWriter(字节输出流转换为字符输出流)

import java.io.*;
public class Demo1 {    
    public static void main(String[] args) throws Exception {  // 抛出一个异常
        // 创建字节输入流
        FileInputStream fileInputStream = new FileInputStream("java.txt");        // 创建转换流(包装流),将字节输入流包装
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);        // 创建带有缓冲区的字符输入流
        // 只接受Reader类的参数
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);        // 创建字节输出流
        FileOutputStream fileOutputStream = new FileOutputStream("D:/java.txt");        // 创建转换流(包装流),将字节输出流包装
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);        // 创建带有缓冲区的字符输出流
        //只接受Writer类的参数
        BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
        char[] chars = new char[5];        
        String temp = null;        
        while ((temp = bufferedReader.readLine()) != null) {            
        // 为了测试,读入的内容可以输出一下
            System.out.println(temp);            // 边读编写()
            bufferedWriter.write(temp);            // 刷新flush()
            bufferedWriter.flush();
        }        // 关闭close()
        // 注意:关闭是最外面的流
        bufferedReader.close();
        bufferedWriter.close();
    }
}
对象流(序列化或者反序列化):

ObjectOutputStream: 序列化,将java堆中的对象序列化到硬盘中(Serial)

ObjectInputStream: 反序列化,将硬盘中的数据“反序列化”到java堆中(DeSerial)

序列化接口,是一个标识接口,该接口没有任何方法,起到标识接口的作用,java中的jvm看到此对象会特别的待遇

注意: 实现序列化的三要素:

  • 当在序列化添加新的属性等,就会出现新的序列化文件,如果想读写同一个序列化文件,我们可以自己动手写一个序列化ID,为了防止读和写的序列化ID不一致,一般指定一个固定的序列化ID。

例如:

private static final long serialVersionUID = 1L;
  • static属性不参与序列化。

  • 对象中的某些属性如果不想被序列化,不能使用static,而是使用transient修饰。

Demo类:

import java.io.Serializable; 
//序列化接口,是一个标识接口,改接口没有任何方法,起到标识接口的作用,java中的jvm看到此对象会特别的待遇
// java.lang.Cloneizable:可克隆的,也是一个标识接口public class Demo implements Serializable {
    String name;    
    // 无参构造方法
    public Demo() {
    }    
    // 带参构造方法
    public Demo(String name) {        
        this.name = name;
    }   
    @Override
    public String toString() {        
        return "name:" + name;
    }
}

对象实例化类:

import java.io.*;
public class Demo1 {    
    public static void main(String[] args) {
        ObjectOutputStream objectOutputStream = null;
        ObjectInputStream objectInputStream = null;        
        // 对象实例化
        Demo demo = new Demo("张三");        
        try {
            objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/java.txt"));
            objectInputStream = new ObjectInputStream(new FileInputStream("D:/java.txt"));            
            // 写
            objectOutputStream.writeObject(demo);            
            // 刷新
            objectOutputStream.flush();            
            // 读
            System.out.println(objectInputStream.readObject());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            
        if (objectOutputStream != null) {                
            try {
                    objectOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            
            if (objectInputStream != null) {               
            try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

装饰者模式

在java中,对方法的扩展,有两种方法:

  • 继承中的重写,但是继承具有低耦合型

  • 用装饰者模式

装饰者模式: 在Java中装饰者模式一般有装饰者和被装饰者

装饰者模式: 在装饰者类中需要有被装饰者的引用,装饰者中和被装饰者应该实现同一个类型

例如:

公共抽象类:

public abstract class C {    
    public abstract void m1();
}

被装饰者类

// 被装饰者类
   public class A extends C {
public void m1() {    
System.out.println("这是A类的m1方法!");
}
}

装饰者类

package charpter01;
public class B extends C {    
    C a;     // 被装饰者引用 
    // 无参构造方法
    public B() {
    
    }    
    // 带参构造方法
    public B(C a) {        
        this.a = a;
    }    
    // 扩展被装饰者中的m1方法
    public void m1() {        
        System.out.println("这是B类中的扩展m1方法");
        a.m1();        
        System.out.println("这是B类中的扩展m1方法");

    }
}

测试类:

public class TestDemo {    
    public static void main(String[] args) {        
        // 创建被装饰者
        A a = new A();        
        // 创建装饰者
        B b = new B(a);
        b.m1();        
        // 第二种方法
        B b1 = new B(new A());
        b1.m1();
    }
}

File类的基本使用

java.io.File类:代表文件和目录。 在开发中,读取文件、生成文件、删除文件、修改文件的属性时经常会用到本类。

File类的常见构造方法:public File(String pathname)

通过File对象可以访问文件的属性:

file.png

例如:

import java.io.File;
import java.io.IOException;
import java.util.Date;
public class Demo3 {    
    public static void main(String[] args) {        
        File file = new File("FileTest.txt");        // 创建file  需要抛出异常
        try {            
        file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }        
        // file是否是目录
        System.out.println(file.isDirectory());  // false
        // file是否是文件
        System.out.println(file.isFile());     // true
        // 判断file是不是存在
        System.out.println(file.exists());       // true
        // 获取file的绝对路径
        System.out.println(file.getAbsoluteFile());        
        // 获取file目录路径
        System.out.println(file.getPath());        
        // file的长度
        System.out.println(file.length());        
        // file最后修改的时间
        System.out.println(new Date(file.lastModified()));

    }
}
通过File对象创建空文件或目录(在该对象所指的文件或目录不存在的情况下)

fileMethod.png

例如:

import java.io.File;
import java.io.IOException;
public class Demo3 {    
    public static void main(String[] args) {        
        File file = new File("FileTest.txt");        // 创建file  需要抛出异常
        try {            
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }        
        // 获取文件名字
        System.out.println(file.getName());        
        // 删除file
        file.delete();        
        File file1 = new File("D:/IT/java.txt");        
        //目录结构中有一个不存在,则不会创建整个目录树
        System.out.println(file1.mkdir());        
        //目录结构中有一个不存在也没关系;创建整个目录树
        System.out.println(file1.mkdirs());        
        //循环遍历指定路径下的子目录  listFiles是目录才有的方法。
        File file2 = new File("D:/");        
        File[] files = file2.listFiles();        
        for (File f : files) {
            System.out.println(f);
    }
    }
}

例如: 用递归循环遍历某个目录下的所有子目录

import java.io.File;
public class Demo3 {    
public static void main(String[] args) {        
        /**
         * 使用递归找出D:\CloudMusic目录下的所有子目录
         */
        File f = new File("D:\\CloudMusic");        
        //  调用查找方法
        method1(f);

    }    
    // 查找方法
    public static void method1(File f) {        
    // 递归头(结束),如果是文件时,则停止
        if (f.isFile()) {            
            return;
        }        
        // 创建一个数组来接收当前目录下的子目录
        File[] files = f.listFiles();        
        // 循环遍历
        for (File fi : files) {            
        // 打印输出 当前目录的绝对路径
            System.out.println(fi.getAbsoluteFile());            
            // 递归体(循环)
            method1(fi);
        }
    }
}


Tags: java

很赞哦! (5)

留言

来说点儿什么吧...

您的姓名: *

选择头像: *

留言内容:

    2019年2月25日 13:35嘿嘿

    2019年2月26日 13:20ok

    可以可以!

    2019年3月18日 09:2311

    1

    2019年3月28日 09:24www.ikeguang.com

    可以可以

    2019年5月29日 18:47qwe

    666

    2019年5月30日 16:52BlankYk

    he,tui~

    2019年5月30日 17:04123

    321

    2019年6月26日 10:02周树人

    厉害厉害

    2019年6月26日 10:34sdlakrj

    sdaag

    2019年6月29日 15:31sdagafdbaf

    dgafdgdfh

    站长回复:你这是什么什么高级语言,我表示看不懂哈哈

    2019年7月6日 16:37啦啦

    写的真好!谢谢博主

    站长回复:谢谢!

    2019年8月14日 12:35傻傻

    厉害 小林

    2019年9月11日 20:05sdfw

    fgbhjksdgjdfhag

    2019年9月11日 22:18baba

    keke tui

    2019年11月5日 20:09666

    666