IO流、字节输入输出流、字符输入输出流

IO流、字节输入输出流、字符输入输出流

IO概述

I:input
O:output
流:数据传输(字符、字节)
IO根据数据的流向分为输入流、输出流(以内存为主体,数据流向硬盘为内存输出,数据流向内存为内存输入。)IO主要执行的操作为read-读取、write-写出(以内存为主体,读取是内存读取硬盘数据,写出是内存写出数据到硬盘)。
根据数据类型分为:字符流,字节流

输入流输出流
字节流字节输入流
InputStream
字节输出流
OutputStream
字符流字符输入流
Reader
字符输出流
Writer

java.io.OutputStream字节输出流

java.io.OutputStream字节输出流,抽象类,其子类共性成员方法有:
1.void close()关闭并释放资源
2.void flush()刷新此输出流并强制任何缓冲的输出字节被写出
3.void write(byte[] b)把字节数组写入此输出流
4.void write(byte[] b,int off,int len)把字节数组从偏移量off开始的len长度数组,写入此输出流
5.void write(int b)把指定的字节输出流
子类java.io.FileOutputStream
文件字节输出流,把内存中的数据写入到硬盘的文件中
构造方法:
1.FileOutputStream(String name,(可写可不写参数)boolean append)
2.FileOutputStream(File file,(可写可不写参数)boolean append)
在指定路径创建文件
boolean append为true时,创建文件不会覆盖原文件,而是在原文件基础上追加写入输出流。
写入数据的原理(内存–>硬盘):
java程序–>JVM–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中
换行符号:
windows:\r\n
linux:/n
mac:/r

使用方法eg:

public static void main(String[] args) {
        File file = new File("abc.txt");
        //1.创建对象new FileOutputStream
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file,true);
            //2.write写出数据
            String str = "aiuvibbkjbebashbuucjkndsafybube";
            byte[] bytes = str.getBytes();//中文一个字的GBK编码是两个字节,并且第一个字节是负数
            fileOutputStream.write(bytes);
            fileOutputStream.write("\r\n".getBytes());
            fileOutputStream.write(bytes,10,10);
            //3.释放资源
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

java.io.InputStream字节输入流

java.io.InputStream,字节输入流,抽象类,其子类共性成员方法有:
1.void close()关闭并释放资源
2.int read()从输入流中读取【下】一字节,并返回【这个字节】
3.int read(byte[] b)从输入流中读取一定数量的字节,并存储在缓冲区数组b中,返回值为读取有效个数的长度,即修改了缓冲区byte[]中的前几个元素(如果循环读取到结尾,后面的元素是没有被修改的),如果返回值为-1,则说明一个也没修改。

子类java.io.FileInputStream
文件字节输入流,把硬盘文件中的数据读取到内存中使用
构造方法:
1.FileInputStream(String name)
2.FileInputStream(File file)

另:字节流使用GBK编码,两个byte组合为一个汉字字符,而java控制台使用UTF-8编码,三个byte组合成一个汉字字符,所以在控制台打印输出汉字时会出现乱码。这时,使用字符流好一些。
按理说是1 char = 2 byte,1 byte = 8bit。但是汉字字符在不同编码格式下有不同的表现形式。

使用方法eg:

public static void main(String[] args) throws IOException {
        File file = new File("abc.txt");
        //1.创建对象new FileInputStream
        FileInputStream fileInputStream = new FileInputStream(file);
        //2.创建字节数组缓冲区
        byte[] b = new byte[20];//创建缓冲区数组b,常用长度1024或其整数
        //3.read读取数据
        int read = fileInputStream.read(b);
        System.out.println(read);
        System.out.println(new String(b));
          //再读取一次,read2为读取有效个数的长度,注意此时指针已经在第21个字节
        int read2 = fileInputStream.read(b);
        System.out.println(read2);
        System.out.println(new String(b));
        //4.释放资源
        fileInputStream.close();
    }

java.io.Reader字符输入流

java.io.Reader,字符输入流,是字符输入流的最顶层父类,抽象类,其子类共性成员方法有:
(与字节流类似)
1.void close()关闭并释放资源
2.int read()从输入流中读取【下】一字字符,并返回。
3.int read(char[] cbuf)从输入流中读取一定数量的字符,并存储在数组cbuf中。返回值为这次修改了数组中的多少元素,没有修改返回-1。

子类java.io.FileReader extends InputStreamReader extends Reader
文件字符输入流,把硬盘文件中的数据以字符的方式,读取到内存中使用
构造方法:
1.FileReader(String name)
2.FileReader(File file)

使用方法eg:

public static void main(String[] args) throws IOException {
        //1创建对象new FileReader
        FileReader fileReader = new FileReader("f:\\a.txt");
        //2.新建字符数组缓冲区
        char[] chars = new char[1024];
        //3.读取数据
        int len = fileReader.read(chars);
        int len2 = fileReader.read(chars);
        System.out.println(len2);
        System.out.println(new String(chars));
        //4释放资源
        fileReader.close();
    }

java.io.Writer字符输出流

java.io.Writer,字符输出流,所有字符输出流最顶层父类,抽象类,其子类共性成员方法有:
(与字节输出流类似)
1.void close()关闭并释放资源,但要先 刷新
2.void flush()刷新此输出流并强制任何 【缓冲的】 输出字符被写出
3.void write(char[] cbuf)写入字符数组到内存缓冲区
4.void write(char[] cbuf,int off,int len)把字符数组从偏移量off开始的len长度数组,写到内存缓冲区
5.void write(int c)写入单个字符到内存缓冲区
6.void write(String str)写入字符串到内存缓冲区
7.void write(String str,int off,int len)把字符串从偏移量off开始的len长度数组,写到内存缓冲区
子类java.io.FileWriter extends OutputStreamWriter extends Writer
文件字符输出流,把内存中的字符数据写入到硬盘的文件中
构造方法:
1.FileWriter(String name,(可写可不写)boolean append))
2.FileWriter(File file,(可写可不写boolean append))
在指定路径创建文件
boolean append为true时,不会创建文件覆盖原文件,而是在原文件基础上追加写入输出流。
写入数据的原理(内存–>硬盘):
java程序–>JVM–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中
换行符号:
windows:\r\n
linux:/n
mac:/r

使用方法eg:

public static void main(String[] args) throws IOException {
        //1.创建对象
        FileWriter fileWriter = new FileWriter("f:\\b.txt");
        //2.写出到内存缓冲区,内存把字符变为字节
        fileWriter.write(97);
        //3.刷新
        fileWriter.flush();
        //4.关闭资源
        fileWriter.close();
    }
public static void main(String[] args) throws IOException {
        //1.创建对象
        FileWriter fileWriter = new FileWriter("f:\\c.txt");
        //2.写出到内存缓冲区,内存把字符变为字节
        char[] chars = {'a', 'b','c', 'd', 'e'};
        fileWriter.write(chars);//abcde
        fileWriter.write(chars,2,3);//cde
        String str ="def";
        fileWriter.write(str);//def
        fileWriter.write(str,0,2);//de
        //3.刷新
        fileWriter.flush();
        //4.释放资源
        fileWriter.close();
    }

注意:输入流与输出流的创建与使用都是有异常的,实际应用中我们应该try…catch,而不是抛出:
在JDK1.7之前,使用try…catch时注意点有四:

public static void main(String[] args) {
        //1.把FileWriter对象的作用域上升在try之前
        //2.FileWriter对象必须赋值为null
        FileWriter fileWriter = null;
        try{
            fileWriter = new FileWriter("f:\\b.txt");
            fileWriter.write(97);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //3.在finally中释放资源,而且要try..catch
            //4.加if判断语句fileWriter不为空时才释放资源
            if (fileWriter !=null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

在JDK1.7之后,使用try…catch时,try(){}括号中定义流对象,执行完毕try,自动释放括号中的对象,不用写finally:

//文件拷贝案例
public static void main(String[] args) {
        try(
            FileInputStream source = new FileInputStream("E:\\Capture001.png");
            FileOutputStream target = new FileOutputStream("F:\\a.png");
            ){
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = source.read(bytes)) !=-1) {//注意判断方法
                target.write(bytes);
            }
            /*//释放资源(先关闭输出流较好,原则先开后关)
            target.close();
            source.close();*/
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

在JDK1.9之后,使用try…catch时,try(){},try前定义定义流对象,括号中传参数,执行完毕try,自动释放括号中的对象,不用写finally

//文件拷贝案例
public static void main(String[] args) throws FileNotFoundException {
        FileInputStream source = new FileInputStream("E:\\Capture001.png");
        FileOutputStream target = new FileOutputStream("F:\\a.png");
        try(source;target){
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = source.read(bytes)) !=-1) {
                target.write(bytes);
            }
            /*//释放资源(先关闭输出流较好)
            target.close();
            source.close();*/
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

双列集合Properties

java.util.Properties extends hashtable<k,v> implements Map<k,v>
Properties是唯一和IO流结合的双列集合
方法store()输出(写出)数据
方法load()输入(读取)数据
Properties集合的key和value都默认为字符串
eg1:Properties的基本使用

public static void main(String[] args) {
        //1.创建对象new Properties,默认都为String
        Properties properties = new Properties();
        //2.setProperty方法,添加键值对
        properties.setProperty("阿明","15");
        properties.setProperty("阿花","14");
        properties.setProperty("阿拉","17");
        properties.setProperty("阿奔","25");
        //3.stringPropertyNames方法,取出key组成Set集合
        Set<String> strings = properties.stringPropertyNames();
        //4.getProperty得到key对应的value值
        for (String string : strings) {
            String value = properties.getProperty(string);
            System.out.println(string +"="+value);
        }
    }

eg2:Properties输出键值对
方法:
void store(OutputStream out ,String comments)字节输出流不能有中文
void store(Writer writer ,String comments)字符写出流可以有中文
注意: comments注释不能为中文

public static void main(String[] args) throws IOException {
        //void store(OutputStream out ,String comments)字节输出流不能有中文
        //void store(Writer writer ,String comments)字符写出流可以有中文
        // comments注释不能为中文
        //1.创建对象
        Properties properties = new Properties();
        //2.添加键值对
        properties.setProperty("阿明","15");
        properties.setProperty("阿花","14");
        properties.setProperty("阿拉","17");
        properties.setProperty("阿奔","25");
        //3.创建FileWriter对象
        FileWriter fileWriter = new FileWriter("f:\\a.txt");
        //4.store方法,输出键值对
        properties.store(fileWriter,"name=age");
        //5.释放资源
        fileWriter.close();
    }

eg3:Properties读取键值对
方法:
void load(InputStream inStream )字节输入流不能有中文
void load(Reader reader)字符读取流可以有中文
注意:
1.文件中键值对默认连接符号可以用=,空格(其他符号)
2.文件中可以用#进行注释,被注释的键值对不会再被读取

public static void main(String[] args) throws IOException {
        //void load(InputStream inStream )字节输入流不能有中文
        //void load(Reader reader)字符读取流可以有中文
        //注意:1.文件中键值对默认连接符号可以用=,空格(其他符号)2.文件中可以用#进行注释,被注释的键值对不会再被读取
        //1.创建对象
        Properties prop = new Properties();
        //2.创建对象
        FileReader fileReader = new FileReader("f:\\a.txt");
        //3.load方法,读取键值对到Properties对象
        prop.load(fileReader);
        //4.释放资源
        fileReader.close();

        Set<String> strings = prop.stringPropertyNames();
        for (String string : strings) {
            String property = prop.getProperty(string);
            System.out.println(string+"="+property);
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值