IO流 java

IO流的概述

  • IO:输入/输出(Input/Output)

  • :是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质就是数据传输

  • IO流就是用来处理设备间数据传输问题的
    常用的应用:文件复制、文件上传、文件下载

以游戏程序为中心读取文件就是输入,写入文件是输出
在这里插入图片描述
分类:

  • IO流在java中从输入输出角度分类:
    1.输入流
    2.输出流
  • IO流在java中从数据的角度来分类:
    1.字符流
    文本,我们能读的懂的都可以认为是字符流。比如:文章,java文件等等
    2.字节流
    二进制的数据,这种数据一般用文本打开我们读不懂。比如,图片文件,mp3文件,等等。

一、字节流

字节流基类

  • InputStream:这个抽象类是表示字符输入流的所有类的超类
    在这里插入图片描述

  • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    在这里插入图片描述

  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

(一)字节流写数据 OutputStream

常用子类 FileOutputStream

1.构造方法
在这里插入图片描述

2.三种写入方法

1.void write(byte[] b) 
将 b.length字节从指定的字节数组写入此输出流 (一次写一个字节数组)

2.void write(byte[] b, int off, int len) 
从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流 
(一次写一个字节数组的部分数据)

3.void write(int b) 
将指定的字节写入此输出流 (一次写一个字节数据)

3.两个小问题

字节写入流如何实现换行?

  • 写完数据后,加换行符
    windows:\r\n
    linux:\n
    mac:\r
  
public class IOTest5 {

    public static void main(String[] args) {

        //创建一个文件
        File file = new File("test.txt");
       OutputStream writer = null;

        try {
            //IO流是需要关闭的,如果不这样设计就会不能关闭资源
            writer = new FileOutputStream(file);
            for (int i = 0; i < 100; i++) {
                writer.write("HelloWorld\r\n");
                //每次写入10个helloworld的时候做一次flush
                if(i % 10 == 0){
                    writer.flush();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //判断writer不是空防止空指针异常
            if(writer != null) {
                try {
                    //在关闭前会做flush的事情
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字节写入流如何实现追加?

  • FileOutputStream(String name, boolean append)
  • 创建文件输出流以指定的名称写入文件,如果第二个参数为ture,则将字节写入文件的末尾而不是开头

 1.创建文件
  2.创建输出流对象
   3.把流指向指定的文件
	4.释放资源
public class IOTest4 {

    public static void main(String[] args) {


        OutputStream writer = null;

        try {
            //IO流是需要关闭的,如果不这样设计就会不能关闭资源
            //writer = new FileOutputStream("test1.txt", true);
            writer = new FileOutputStream(new File("test1.txt"), true);
            writer.write("liangliang");

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //判断writer不是空防止空指针异常
            if(writer != null) {
                try {
                    //在关闭前会做flush的事情
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

(二)字节流读数据 InputStream

常用子类 FileInputStream

1.构造器
在这里插入图片描述
2.方法

1.int read() 
从该输入流读取一个字节的数据
  
2.int read(byte[] b) 
从该输入流读取最多 b.length个字节的数据为字节数组。
 
3.int read(byte[] b, int off, int len) 
从该输入流读取最多 len字节的数据为字节数组。 

案例

将“d:/jiaoben5735.rar”进行读取,并且复制到 “f:/jiaoben5735.rar” 中

public class CopyDemo {    
	public static void main(String[] args) { 
	       
		InputStream in = null;        
		OutputStream out = null;        
		try {            
		//创建字节输入流            
			in = new FileInputStream("d:/jiaoben5735.rar");
			 //创建字节输出流            
		    out = new FileOutputStream("f:/jiaoben5735.rar");
		    //定义一个字节数组,输入流读取写入数组,输出流读取数组中的内容写入字节输出流对象            
		    byte[] bs = new byte[1024];            
		    int len = -1;            
		    while((len = in.read(bs)) != -1){                
		    //把读取的数据写入字节输出流                
		    out.write(bs, 0, len);            
		    }        
		  } catch (Exception e) {            
		   e.printStackTrace();        
		   } finally {            
		   try {                
		   if(out != null){                    
		   out.close();                
		   }                
		   if(in != null){                    
		   in.close();                
			}            
		} catch (IOException e) {               
		    e.printStackTrace();            
		    }        
		}    
	}
}

(三)字节流 高效缓冲区

1.写数据缓冲流

构造器

 1.BufferedOutputStream(OutputStream out) 
 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
   
 2.BufferedOutputStream(OutputStream out, int size) 
 创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流 

方法

1.void write(byte[] b, int off, int len) 
从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。
 
2.void write(int b) 
将指定的字节写入缓冲的输出流 

2.读数据缓冲口

构造器

1.BufferedInputStream(InputStream in) 
创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用

2.BufferedInputStream(InputStream in, int size) 
创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用 

方法

1.int read() 
从该输入流读取一个字节的数据

2.int read(byte[] b, int off, int len) 
从给定的偏移开始,将字节输入流中的字节读入指定的字节数组 

案例
利用高校缓冲区将图片 D:/feiji.jpg 进行读取并且复制到 plane.jpg 中

public class BufferCopy {    
	public static void main(String[] args) {        
	//定义一个高效缓存字节流        
	BufferedInputStream in = null;        
	BufferedOutputStream out = null;        
	try {            
	//创建一个高效缓存字节流对象            
	in = new BufferedInputStream(new FileInputStream("D:/feiji.jpg"));
	out = new BufferedOutputStream(new FileOutputStream("plane.jpg"));
	//定义一个字节数组            
	byte[] bs = new byte[1024];            
	//定义一个标志            
	int len = -1;            
	while((len = in.read(bs)) != -1){                
		out.write(bs, 0, len);            
		}        
	} catch (Exception e) {            
	e.printStackTrace();        
	} finally {            
	try {                
	if(out != null){                   
	 out.close();                
	 }                
	 if(in != null){                    
	 in.close();                
	 }           
	  } catch (IOException e) {               
	   e.printStackTrace();            
	   }       
    }   
 }
}

二、字符流

字符流的抽象基类:

  • Reader:字符输入流的抽象类
    在这里插入图片描述

  • Writer:字符输出流的抽象类
    在这里插入图片描述

(一)字符流写数据

常用子类
FileWriter

1.构造方法

1.FileWriter(File file) 
  给一个File对象构造一个FileWriter对象 
   
2.FileWriter(File file, boolean append) 
  给一个File对象构造一个FileWriter对象
   
3.FileWriter(FileDescriptor fd) 
构造与文件描述符关联的FileWriter对象
  
4.FileWriter(String fileName) 
构造一个给定文件名的FileWriter对象
  
5.FileWriter(String fileName, boolean append) 
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据 

2.方法
在这里插入图片描述

(二)字符流读数据

常用子类
FileReader

1.构造器

1.FileReader(File file) 
创建一个新的 FileReader ,给出 File读取
  
2.FileReader(FileDescriptor fd) 
创建一个新的 FileReader ,给定 FileDescriptor读取
 
3.FileReader(String fileName) 
创建一个新的 FileReader ,给定要读取的文件的名称 

2.方法
在这里插入图片描述

(三)字符流高效缓冲区

1.写数据缓冲流

构造器

1.BufferedWriter(Writer out) 
  创建使用默认大小的输出缓冲区的缓冲字符输出流  
  
2.BufferedWriter(Writer out, int sz) 
  创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区 

方法

1. void newLine()   //特有方法
  写一行行分隔符
  
2.void write(char[] cbuf, int off, int len) 
  写入字符数组的一部分
  
3.void write(int c) 
  写一个字符  

4.void write(String s, int off, int len) 
  写一个字符串的一部分 

2.读数据缓冲流

构造器

1.BufferedReader(Reader in) 
  创建使用默认大小的输入缓冲区的缓冲字符输入流
  
2.BufferedReader(Reader in, int sz) 
  创建使用指定大小的输入缓冲区的缓冲字符输入流 

方法

1.int read() 
  读一个字符  
  
2.int read(char[] cbuf, int off, int len) 
  将字符读入数组的一部分
  
3.String readLine()  //常用到的特有方法
  读一行文字

三、字符流和字节流之间的转换

1.字节流转换成字符流

构造方法

1.InputStreamReader(InputStream in) 
  创建一个使用默认字符集的InputStreamReader

2.InputStreamReader(InputStream in, Charset cs) 
  创建一个使用给定字符集的InputStreamReader
  
3.InputStreamReader(InputStream in, CharsetDecoder dec) 
  创建一个使用给定字符集解码器的InputStreamReader
  
4.InputStreamReader(InputStream in, String charsetName) 
  创建一个使用命名字符集的InputStreamReader 

方法

1.String getEncoding() 
  返回此流使用的字符编码的名称
    
2.int read() 
  读一个字符  
  
3.int read(char[] cbuf, int offset, int length) 
  将字符读入数组的一部分
  
4.boolean ready() 
  告诉这个流是否准备好被读取 

2.字符流转换成字节流

构造器

1.OutputStreamWriter(OutputStream out) 
  创建一个使用默认字符编码的OutputStreamWriter 
  
2.OutputStreamWriter(OutputStream out, Charset cs) 
创建一个使用给定字符集的OutputStreamWriter
  
3.OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
  创建一个使用给定字符集编码器的OutputStreamWriter
  
4.OutputStreamWriter(OutputStream out, String charsetName) 
  创建一个使用命名字符集的OutputStreamWriter 

方法

1.String getEncoding() 
  返回此流使用的字符编码的名称  
  
2.void write(char[] cbuf, int off, int len) 
  写入字符数组的一部分
  
3.void write(int c) 
  写一个字符  
  
4.void write(String str, int off, int len) 
  写一个字符串的一部分 

四、打印流

分类:

  • 字节打印流:PrintStream
  • 字符打印流:PrintWriter

特点:

  • 只负责输出数据,不负责读取数据
  • 有自己的特有方法

1.字节打印流

构造方法

  • PrintStream(String fileName)
    使用指定的文件名创建新的打印流,无需自动换行

方法

//继承的父类的方法

1.void write(byte[] buf, int off, int len) 
  从指定的字节数组写入 len个字节,从偏移 off开始到此流
  
2.void write(int b) 
  将指定的字节写入此流
  
3.void write(byte[])
  将指定的字节数组写入流

//自己的独特方法
1.void print(String s) 
打印字符串 

2.void println() 
通过写入行分隔符字符串来终止当前行
.......................

特点:

  • 使用继承父类的方法写数据,查看的时候会转码
  • 使用自己特有的方法写数据,查看的数据原样输出

2.字符打印流

构造方法

1.PrintWriter(String fileName) 
  使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新

2.PrintWriter(Writer out, boolean autoFlush) 
  创建一个新的PrintWriter
  
  out - 字符输出流 
  autoFlush - 一个布尔值 如果为真,则println,printf,或format方法将刷新输出缓冲区

方法

//继承父类的方法

1.void write(char[] buf) 
  写入一个字符数组
    
2.void write(char[] buf, int off, int len) 
  写一个字符数组的一部分
    
3.void write(int c) 
  写一个字符  
  
4.void write(String s) 
  写一个字符串  
  
5.void write(String s, int off, int len) 
  写一个字符串的一部分 

//自己特有的方法

1.void print(String s) 
  打印字符串
  
2.void println() 
  通过写入行分隔符字符串来终止当前行
   
3.void println(String x) 
  打印一个字符串,然后终止行 

特点

PrintWriter(String fileName) 构造器特点:

  • 使用继承父类德方法写数据,因为是字符打印流,需要进行 flush() 操作,才可以将内容写入:如果连续输入两个内容,想要换行,需要用\r\n换行符
  • 如果使用自己独有的方法,也需要进行 fiush() 操作,才能将内容写入:如果想要换行,则可以直接调用自己独有方法 println、printf 或 format 方法,自动换行

PrintWriter(Writer out, boolean autoFlush) 构造器特点:

  • 在构造器第二个布尔参数为 true 的前提下,使用 println、printf 或 format方法时,会自动换行,并且自动 fiush() ,直接一步到位

五、对象序例化和反序例化

1.对象序例化

对象实例化流: ObjectOutputStream

概述:

  • 将Java对象的原始数据类型和图形写入 OutputStream
  • 可以使用ObjectInputStream 读取(重构)对象
  • 可以通过使用流的文件来实现对象的持久储存
  • 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构队象

构造方法

ObjectOutputStream(OutputStream out)

创建一个写入指定的OutputStream的ObjectOutputStream

序例化方法

void writeObject(Object obj)

将指定的对象写入ObjectOutputStream

注意:

  • 一个对象想要被序例化,该对象所属的类必须实现 Seriailizable 接口
  • 在序列化的过程中要手动指定要序列化的类的的serialVersionUID,这样可以在类改变后依然可以反序列化,否则会报错。
  • Seriailizable 是一个标记接口,实现该接口,不需要重写任何方法
  • 如果要是对多个对象来做序列化,一定要放在集合中
    在这里插入图片描述
    实现接口
    在这里插入图片描述

2.反序例化

对象反序例化: ObjectInputStream

概述: ObjectInputStream 反序例化先前使用 ObjectOutputStream 编写的原始数据和对象

构造方法:

ObjectInputStream(InputStream in)

创建从指定的InputStream读取的ObjectInputStream

反序例化方法:

Object readObject()

从ObjectInputStream读取一个对象

3.SerialVersionUID & transient

在这里插入图片描述

六、Properties 类

1.概述:

  • Properties 类表示了一个持久的属性集
  • Properties 可保存在流中或从流中加载
  • 属性列表中每个键及其对应值都是一个字符串
  • 是一个 Map 体系的集合类

2.特点:

  • 继承于HashTable,是线程安全的键值对存储结构
  • Properties 可保存在流中或从流中加载
  • 只能保存字符串的键值对。

3.构造方法:
在这里插入图片描述
4.方法

作为 Map 集合的特有方法:
在这里插入图片描述
实例代码:

在这里插入图片描述
和 IO 流相结合的方法:
在这里插入图片描述
实例代码:

public class PropTest6 {


    public static void main(String[] args) {

        //创建一个Properties对象
        Properties prop = new Properties();


        InputStream in = null;
        try {
            //in = new FileReader("src/names.properties");
             in = PropTest6.class.getClassLoader().getResourceAsStream("names.properties");
             //从字节流中来加载数据到属性对象中
            prop.load(in);
            System.out.println(prop);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

5.案例:

游戏次数大于三次提示充值

在这里插入图片描述

七、字符编码

基础知识:

  • 计算机中储存的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
  • 按照某种规则,将字符存储勁計算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调一下:按照 A编码存储,必须按照 A 编码解析,这样才能显示正确的文本符号。否则就会导致乱码现象
  • 字符编码:就是一套自然语言的字符与二进制数之间的对应规(A65)

字符集:

  • 是一个系统支持的所有字符的集合,包括各国家文婷、标点符号、图符号、数字等
  • 计算机要准确的存储和只別各种字符集符号,就需要进行字符编码,一套字符集必然至有一套字符编码。常见字符集有 ASCI 字符集、GBX0字符集
    Unicode 字符集等

ASCil 字符集:

  • ASCil ( American Standard Code for Information Interchange
    .美国信息胶交换标准代码):是基于拉丁字母的一套电脑编码系统,用显示现代英语,主要包括空制字符(回车键、退格、换行键等)和呵显示字符贞文大小写字符、阿拉伯数字和西文符号)

  • 基本的 ASCI字符集,使用7位表示个字符,共128字符。ASC1的扩展字符集使用8位表示一个字符。共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等

GBXXX 字符集:

  • G82312:简体中文码表。一个小127的子行的意义与原来是同,但两个大于127的子付连在一 E
    时。木表小个议字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字用、日文的假名等都编进去了,连在 ASCI
    里本来就有的数字、标点、字母誕统統重新了两个字节长的编码,这就是常说的全角字符,而原来在127号以下的那些就叫半角字符了

  • GBK : 最常用的中文码表。是在GB2312标准基础上的展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等

  • GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支繁体汉字以吸日汉字等

unicode 字符集:

  • 为表达任意语言的任字符而&计,是业界的种5准。也称为统一目、标住万 H
    .它最多使用4个字书的数字来表达每个字母、符号,老文实有三种编码方家, UTF -8、 UTF -16fQUTF32,最为常用的 UTF-8编码

  • UTF -8编码:可以用来表示 Unicode
    标准中任意符,它是电子部件、网页及其他存锦或的送文字的应用中,优先采用的编5,互联网工程工作小姐( IETF )要求所有互取网议部必须支持UTF -6编码,它使用一至四个字节为每个字符编码

  • 编码规则:
    128个 US - ASCl 字符只需一个字节编码
    拉丁文等字符,需要二个学节编码
    大部分常用字(含中文,使用三个字符编码
    其他扱少使用的 Unicode 辅助字符,使用四字节编码
    小结:采用何种规则编码,就要采用对应规则解码,否则就会出现乱码

八、标准输入输出流

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值