字节流和字符流的输入和输出

IO的概述:
  • IO:
       I:Input 输入(读取数据) 指的是从硬盘读取数据到内存中.
     O:Output 输出(把数据) 从内存中写出到其他设备上的流.
IO的分类:
  •  输入流:
        字节输入流:以字节为单位 读取数据.
        字符输入流:以字符为单位 读取数据.
  •  输出流:
        字节输出流:以字节为单位输出数据.
        字符输出流:以字符为单位输出数据.
按照类型分;
字节流;
  • 字节输入流:以字节为单位读取数据.
       顶层父类;IuputStream 这个抽象类是表示输入字节流的所有的超类.
  • 字节输出流:以字节为单位输出的数据.
       顶层父类:   OutputStream   这个抽象类表示字节输出流的所有的超类.     
字符流;
  •  字符输入流;以字符为单位读取数据.
        顶层父类:Reader用于读取字符流的抽象类.
  •  字符输出流:以字符为单位输出的数据.
        顶层父类:Writer用于字符流的抽象类.
总结:
 1.字节流和字符流的顶层父类都是抽象类  包:java.io
 2.集合类的顶层都是接口   包:java.util
Wirit只能接收字节(getByte)和数字.
字符参与计算的时候转换Int类型的数据.
不确定的次数用While.

字节流:
字节流的输出流(OputputStream)抽象类 主要输出来从内存中写出数据到硬盘中.
File:封装.
OputputStream常用方法;
输出换行:\t \r 换行.

字节输出流【OutputStream】常用的方法;

 
  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

  • public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

  • public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。

  • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。

  • public abstract void write(int b) :将指定的字节输出流。

代码演示;
 
package com.heima.zifu;
import java.io.File;
import java.io.FileOutputStream;
//FileOutputStream类
public class Demo02 {
public static void main(String[] args) throws Exception{
//使用File创建字节流对象
File file=new File("D:\\LULIANGHM\\JAVAEE\\Day10\\c.txt");
FileOutputStream fos=new FileOutputStream(file,true);//抛出异常
//字符串转换成字节数组
byte [] b="abcde".getBytes();
//写出位置从2开始,2个字节.索引为2
fos.write(b,2,2);
//数据追加在参数后面加一个true
fos.write(98);
//写出数据
fos.write(97);//写出一个字节a
//遍历数组
for(int i=0;i<b.length;i++){
//写出一个字节
fos.write(b[i]);
//写出一个换行,换行符号转成数组写出
fos.write("\r\n".getBytes());
}
//关闭资源
fos.close();
}
}
 
注意;close方法,当完成流的操作时候,必须调用此方法,释放资源.

 
字节输入流:
 

java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

  • public void close() :关闭此输入流并释放与此流相关联的任何系统资源。

  • public abstract int read(): 从输入流读取数据的下一个字节。

  • public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

FilelnputStream类:
构造方法:
- FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。 
- FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。  

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException 。

 

构造举例,代码如下:
 1 package com.heima.zifu;
 2 import java.io.FileInputStream;
 3 public class Demo05 {
 4     public static void main(String[] args) throws Exception {
 5         //使用文件名创建流对象
 6         FileInputStream fis=new FileInputStream("D:\\LULIANGHM\\JAVAEE\\Day10\\c.txt");
 7         //定义变量,保存数据
 8         int a;
 9 
10         while ((a=fis.read())!=-1){
11             //字节💗转换为字符型
12             System.out.println((char) a);
13         }
14         //关闭资源
15         fis.close();
16     }

 

使用字节数组读取:
代码演示:
 1 package com.heima.zifu;
 2 
 3 import java.io.FileInputStream;
 4 
 5 public class Demo06 {
 6     public static void main(String[] args) throws Exception{
 7         FileInputStream fis=new FileInputStream("D:\\LULIANGHM\\JAVAEE\\Day10\\c.txt");
 8         //定义变量
 9         int len;
10         byte[]  b=new byte[2];
11         //循环获取
12         while ((len=fis.read(b))!=-1){
13             //new String(b)转换为字符串形式显示
14             System.out.println(new String(b));
15         }
16         //关闭资源
17         fis.close();
18     }
19 }
输出结果:as
da
sd
as
da
sd
错误数据:d 由于最后一次读取时候,自读取一个字节e,数组中,上次读取的时候没有完全被替代,所以要获取有效字节
修改: System.out.println(new String(b));修改成
len每次读取的有效字节个数.
     System.out.println(new String(b,0,len));
 

 

字节流练习:图片复制:
复制图片的原理:
代码演示:
 
 
 1 package com.heima.tupian;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 
 6 /*
 7 使用字节流来拷贝一张图片
 8     需求:把G:\ccc\hb.jpg图片拷贝到day09\\hb.jpg
 9     IO流的核心代码:
10         1.创建输入流对象,封装数据源文件
11         2.创建输出流对象,封装目的地文件
12         3.定义变量,用来存储读取到的数据
13         4.只要满足条件就一直循环读取数据
14         5.写出数据
15         6.关闭流,释放资源
16  */
17 public class Demo01 {
18     public static void main(String[] args) throws Exception{
19         //1.创建字节输入流对象,封装数据源文件
20         FileInputStream fis=new FileInputStream("C:\\Users\\ASUS\\Desktop\\截图\\11111.jpg");
21         //1.2创建输出流对象,封装数据原文件
22         FileOutputStream fos=new FileOutputStream("D:\\LULIANGHM\\JAVAEE\\Day10\\sss.jpg");
23         //定义变量用于存储读取到的数据
24         byte[] bytes=new byte[1024];
25         //定义长度
26         int len;
27         //循环读取
28         while ((len=fis.read(bytes))!=-1){
29             //写出数据
30             //边写出边读取
31             fos.write(bytes,0,len);
32         }
33         //释放资源
34         //先释放输出流在释放输出流
35         fos.close();
36         fis.close();
37 
38     }
39 }

 


 
字符流:
字符输入流(Reader):

java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

  • public void close() :关闭此流并释放与此流相关联的任何系统资源。

  • public int read(): 从输入流读取一个字符。

  • public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。

FileReader类:
java.io.FileReader类是读取字符文件的便利类,构造时使用系统默认的字符编程和默认字节缓冲区.
小贴士:
1.字符编码:字节与字符的对应规则,Windows系统的中文编程默认是GBK编程表.
2.字节缓冲区:一个字节数组,用来临时存储字节数据.
构造方法:
  • FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。

  • FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。

字符输出流(Writer):
构造方法:
  • public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。

  • public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。

  • public void write(int c) :写出一个字符。

  • public void write(char[] cbuf):将 b.length字符从指定的字符数组写出此输出流。

  • public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流。

  • public void write(String str) :写出一个字符串。

FileWriter类:
构造方法:
  • FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。

  • FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。

代码演示:
package com.heima.zijie;

import java.io.FileWriter;

public class Demo01 {
    public static void main(String[] args) throws Exception{
        //基本写出数据
        //使用文件名称创建流对象
        FileWriter fw=new FileWriter("D:\\LULIANGHM\\JAVAEE\\Day10\\d.txt");
        // 字符串转换为字节数组
        char[]chars="黑马程序园".toCharArray();
        //写出字符串
        fw.write(chars);
        // 写出从索引2开始,2个字节。索引2是'程',两个字节,也就是'程序'。
        fw.write(chars,2,2); // 程序
        //写出数据
        fw.write(97);
        fw.write('b');
        fw.write(30000);
        for(int i=0;i<chars.length;i++){
            System.out.println(chars[i]);
        }
        //关闭系统释放资源
        fw.close();
    }
}

 

 

Io异常的处理:
JDK7前的处理:
package com.heima.biji;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;

public class Demo03 {
    public static void main(String[] args) {
        // 字节流一次读写一个字节数组来拷贝文件
        try (FileInputStream fis = new FileInputStream("day09\\a.txt")) {
            try (FileOutputStream fos = new FileOutputStream("day09\\aCopy.txt")) {
                // 1.创建输入流对象,封装数据源文件
                // 2.创建输出流对象,封装目的地文件
                // 3.定义变量,用来存储读取到的数据
                byte[] bys = new byte[3];// 用来存储读取到的字节数据
                int len;// 用来存储有效字节数

                // 4.只要满足条件就一直循环读取数据
                while ((len = fis.read(bys)) != -1) {
                    //            System.out.println(new String(bys,0,len));
                    // 5.写出数据  写有效字节数  write(byte[] b, int off, int len)
                    fos.write(bys);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * jdk1.7之前
     */
    private static void method10() {
        FileReader fr = null;
        FileWriter fw = null;

        // jdk之前的, 也是现在常用的
        try {
//        1.创建输入流对象,封装数据源文件
            fr = new FileReader("G:\\ccc\\a.txt");

//        2.创建输出流对象,封装目的地文件
            fw = new FileWriter("day09\\aa.txt");

//        3.定义变量,用来存储读取到的数据
            int len;

//        4.只要满足条件就一直循环读取数据
            while ((len = fr.read()) != -1) {
//        5.写出数据
                fw.write(len);
            }
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            // 一般永远都会执行,一般用来释放资源
            //6.关闭流,释放资源
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fr != null) {
                        fr.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        }
    }
}

 


属性集:
Properties类:
构造方法:
 
基本的存储方法:
与流相关的方法:

构造方法

  • public Properties() :创建一个空的属性列表。

基本的存储方法

  • public Object setProperty(String key, String value) : 保存一对属性。

  • public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。

  • public Set<String> stringPropertyNames() :所有键的名称的集合。


代码演示:

 

package com.heima.biji;

import java.io.FileInputStream;
import java.util.Properties;
import java.util.Set;

/*
java.util.Properties 继承于Hashtable 实现了Map接口,来表示一个持久的属性集
    特点:属性列表中的每个键及其对应的值都是一个字符串
    构造方法
    - public Properties() :创建一个空的属性列表。
    基本的存储方法
    - public Object setProperty(String key, String value) : 保存一对属性。  添加键值对 put()
    - public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。  get()
    - public Set<String> stringPropertyNames() :所有键的名称的集合。  keySet()
    和流相关的方法
    - public void load(InputStream inStream): 从字节输入流中读取键值对。
    参数中使用了字节输入流,通过流对象,可以关联到某文件上,这样就能够加载文本中的数据了。
 */
public class Demo04 {
    public static void main(String[] args)throws Exception {
        //day01();//Properties类的构造方法
        //创建属性对象
        Properties properties = new Properties();
        //加载文本中信息到属性集合
        properties.load(new FileInputStream("D:\\LULIANGHM\\JAVAEE\\Day10\\c.txt"));
        //遍历集合打印
        Set<String> strings = properties.stringPropertyNames();
        for (String key : strings) {
            System.out.println(key+"--"+properties.getProperty(key));
        }
    }
    private static void day01() {
        //创建属性集的对象
        Properties properties = new Properties();
        //添加健值对象
        properties.setProperty("djalskdjaa","a.txt");
        properties.setProperty("lu","adasdasdas");
        properties.setProperty("liang","dasdsadasd");
        System.out.println(properties);
        //通过健获取属性值
        System.out.println(properties.getProperty("lu"));
        System.out.println(properties.getProperty("liang"));
        //遍历集合
        Set<String> strings = properties.stringPropertyNames();
        for (String string : strings) {
            System.out.println(string+"---"+properties.getProperty(string));
        }
    }
}
/*
输出结果:
{djalskdjaa=a.txt, lu=adasdasdas, liang=dasdsadasd}
adasdasdas
dasdsadasd
djalskdjaa---a.txt
lu---adasdasdas
liang---dasdsadasd
 */

 

 

 



扩展:
gbk编码: 一个中文占2个字节
utf8编码: 一个中文占3个字节
idea开发工具: 默认编码为utf8
Windows默认编码: gbk
拷贝文件:
    如果该文件使用记事本打开看得懂,就用字符流
    如果该文件使用记事本打开看不懂,就用字节流
    字节流可以拷贝一切类型文件,但是字符流不一定

posted on 2019-03-31 20:03  风一般的男子·小亮  阅读(986)  评论(1编辑  收藏  举报

导航