IO流学习脚印

IO流

> 什么是 IO?
 --> I:Input
 --> O:Output

1、IO流的分类

> 按照流的方向分为:输入流 and 输出流 (以内存作为参照物)
  -->输入(Input)流:往内存中去,也可以称为“读(Read)”。
  -->输出(Output)流:从内存中出来,也可以称为“写(Write)”。

> 按照流的读取方式分类:
  --> 字节流:按照一个字节读入或写出 (类名以 “Stream” 结尾)
  --> 字符流:按照一个字符读入或写出 (类名以 “Reader/Writer” 结尾)
  
  字节流可读入或写出任意格式的文件,而字符流只能处理纯文本文件。

2、常用IO流(十六种)

> 文件流
  --> java.io.FileInputStream(掌握)
  --> java.io.FileOutputStream(掌握)
  --> java.io.FileReader
  --> java.io.FileWriter

> 转换流 (将字节流转换为字符流)
  --> java.io.InputStreamReader
  --> java.io.OutputStreamWriter

> 缓冲流
  --> java.io.BufferedInputStream
  --> java.io.BufferedOutputStream
  --> java.io.BufferedReader
  --> java.io.BufferedWtriter

> 数据流
  --> java.io.DataInputStream
  --> java.io.DataOutputStream

> 标准输出流
  --> java.io.PrintStream(掌握)
  --> java.io.PrintWriter

> 对象流
  --> java.io.ObjectInputStream(掌握)
  --> java.io.ObjectOutputStream(掌握)

3、IO流的使用

虽然 IO 流的种类不少,但对于常用 IO 流的基本使用,其代码相差无几

3.1 文件流

以下不妨借用 FileInputStream 和 FileOutprintStream 两种文件流进行简单的操作说明:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 *	四个步骤:
 *		1、创建源
 *		2、选择流
 *		3、操作流
 *		4、关闭流
*/
public class FileInputStreamTest{
	public static void main (String[] args){
	// 1、创建源
		FileInputStream fis = null;
		try{ /*
			该代码块中写流的操作,例如读取数据并打印...
			下面展示使用文件字节输入流读取文件中的数据并打印到控制台上。
		*/
		
		// 2、选择流
			fis = new FileInputStream("文件路径");
		
		// 3、操作流	
			// 下面创建一个缓冲区,用于一次性读取多个字节,减少内存和文件	
			// 系统的交互次数
			int readLen = -1; // read()读取到的字节大小
			byte[] flush = new byte[1024*1024]; // 1M的缓冲区
			// 若read()读取到文件末尾,则返回 -1
			while ( (readLen = fis.read(flush) ) != -1 ){
				// 下面语句输出文件中读取到的数据
				System.out.println(new String(flush, 0, readLen));
			}
			
		} catch(FileNotFoundException e) {
			e.printStackTrace();
		} catch(IOException e) {
			e.printStackTrace();
		} finally { /*
				因为流的使用比较占资源,所以用完之后一定要记得关闭!
				因为不管程序是否发生异常,finally 语句总会执行,
				所以,可将关闭流的操作放到 finally 语句的作用域中。
			*/
		// 4、关闭流
			if (fis != null){
				try{ 
					fis.close();	
				} catch(IOException e) {
					e.printStackTrace();
				}
			} 
		}
	}
}

以上就是 FIleInputStream 的简单使用。而 FileOutputStream 的使用只需把上面的代码做一点小改动就能实现:

// 1、将需要用到的类导入:
import java.io.FileOutputStream;

// 2、将创建源的代码改为如下代码:
	FileOutputStream fos = null;

// 3、将选择流的代码改为如下代码:
	// 该处的文件路径随意,文件不存在时,会自动创建文件。
	fos = new FileOutputStream("文件路径"); 
	// 该构造器还有一个参数可传:boolean append。
	// fos = new FileOutputStream("文件路径", true); 追加式写入模式
	
// 4、将操作流的代码改为如下代码:
	String str = "我是中国人!";
    byte[] src = str.getBytes();
    fos.write(src); // 将数据写入文件
    fos.flush(); // 刷新输出流

// 5、将关闭流的代码中的 fis 改为 fos 即可

综合以上所知,我们可以简单写一个文件复制的代码实现:

package IOSteam;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopyTest {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try{
            fis = new FileInputStream("文件路径");
            fos = new FileOutputStream("文件路径");

            int len = -1;
            byte[] flush = new byte[1024*1024];
            while ((len = fis.read(flush)) != -1){
                fos.write(flush);
                fos.flush(); //记得刷新,养成好习惯
            }
        } catch(FileNotFoundException e){
            e.printStackTrace();
        } catch(IOException e){
            e.printStackTrace();
        } finally{
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null){
                try{
                    fis.close();
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

对于上述代码,只有一个点需要注意:关闭流的次序。即为先启用的流后关闭

3.2 缓冲流(Buffered开头的流)

新增有两个概念:节点流 and 包装流/处理流。如下代码所示:

/*
   当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
   外部负责包装的这个流叫做:包装流/处理流。
*/
   FileReader reader = new FileReader("文件路径");
   BufferedReader br = new BufferedReader(reader);
   // 对于这个程序来说,FileReader就是一个节点流,BufferedReader就是一个包装流。

缓冲流的使用与文件流相差无几,只是不用创建一个byte数组来作数据缓冲区因为内部已经内嵌缓冲区。而且,关闭流的时候只需关闭包装流即可。

缓冲流因其内部有一个封装流的过程,所以效率应该要比文件流低一点。

3.3 数据流

DataOutputStream:这个流可以将数据及其数据类型一并写入文件中。(该文件记事本打不开)
DataInputStream:这个流可以将DataOutputStream 产生的文件数据及其数据类型读取到内存中,要求读的顺序需要和写的顺序一致

应用:数据加密存储

3.4 标准输出流

PrintStream:标准的字节输出流,默认输出到控制台。
标准输出流不需要手动close()关闭。

标准输出流的输出方向可以改变!

// 标准输出流的输出方向不再指向控制台,而是指向"log"文件。 
PrintStream printStream = new PrintStream(new FileOutputStream("log"));
// 修改输出方向,将输出方向修改到"log"文件。
System.setOut(printStream);

应用:日志工具

3.5 对象流

ObjectInputStream反序列化(DeSerialize)–>(将硬盘文件中的数据读入到内存当中,恢复成Java对象)
ObjectOutputStream序列化(Serialize)–>(将Java对象从内存中写出到硬盘文件中,将Java对象的状态保存下来)

参与序列化和反序列化的对象,必须实现Serializable接口

Serializale接口只是一个标志接口:这个接口中没有任何代码,仅仅起到标识的作用。这个标志接口是给JVM参考的,JVM看到这个接口之后,会自动为该类生成一个序列化版本号。
–>(序列化版本号的作用:当类名相同时,序列化版本号可以用来区分类,推荐自行设置序列化版本号!

public interface Serializable{
}

如何序列化多个对象:将对象放入集合中,序列化集合即可。

transient 关键字的使用:如果待序列化对象中的某些属性不需要序列化,可以使用该关键字进行修饰。

4、IO流与Properties的联合应用

应用:对于经常改变的数据,可以单独写到一个文件中,使用程序动态读取。以后修改数据的时候只需要修改这个文件的内容,不需要改动Java代码,也不需要重新编译,也不需要重启服务器,就可以拿到动态的信息。

类似于以上机制的文件被称为配置文件
并且,当配置文件中的内容格式为:

key=value

的时候,我们把这种配置文件称为属性配置文件

Java的属性配置文件推荐以 propertie 为后缀名。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值