Java基础-复习10-IO流

一. 概述

1. 流(stream)的概念

  • 流:流就是有能力产出数据或接收数据的对象,本质是数据传输,作用是在数据源和程序间建立传送通道

2. IO流的分类

按数据流向分为

  • 输入流:外部(磁盘)数据读入到程序(内存)中
  • 输出流:程序数据输出到磁盘中

按数据单位分为

  • 字节流:按字节操作数据,一般处理非文本文件(jpg、mp4、mp3、doc、ppt)
  • 字符流:按字符操作数据,一般处理文本文件(txt、java、c、cpp)

按流的功能分为

  • 节点流:直接在数据源于程序间进行传输的流
  • 处理流:对已存在的流(节点流或处理流)包装(可多次),增强传输功能的流

流的整体分类

基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

其中,文件、数组、管道、字符串类为节点流,其余为处理流

分类InputStreamOutputStreamReaderWriter
文件FileInputStreamFileOutputStreamFileReaderFileWriter
数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
管道PipedInputStreamPipeOutputStreamPipedReaderPipedWriter
字符串StringReaderStringWriter
转换流InputStreamReaderOutputStreamWriter
对象流ObjectInputStreamObjectOutputStream
打印流PrintStreamPrintWriter
过滤流FilterInputStreamFilterOutputStreamFilterReaderFilterWriter
缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
推回流PushbackInputStreamPushbackReader
数据流DataInputStreamDataOutputStream

*表中加粗项为常用流

3. File类(java.io.File)

File类的对象代表文件或目录,用于对文件或目录的创建、查找和删除操作

File类的构造器:

  • File(String filePath) 根据给定路径字符串创建新的File实例
  • File(String parentPath, String childPath) 根据父路径和子路径创建新的File实例
  • File(File parentFile, String childPath)根据父文件对象和子路径创建新的File实例
// 文件路径名 
String path = "D:\\123.txt";
File file1 = new File(path); 

// 文件路径名
String path2 = "D:\\1\\2.txt";
File file2 = new File(path2);     -------------相当于D:\\1\\2.txt

// 通过父路径和子路径字符串
String parent = "F:\\aaa";
String child = "bbb.txt";
File file3 = new File(parent, child);  --------相当于F:\\aaa\\bbb.txt

// 通过父File对象和子路径字符串
File parentDir = new File("F:\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child); --------相当于F:\\aaa\\bbb.txt

File类的常用方法,参见菜鸟教程

二. 常用流的使用

使用流的标准化代码操作流程,以读取为例,写入同理

  1. 创建 File 类对象,指明读取的数据来源,文件必须存在
  2. 创建相应输入流,将File类对象作为参数传入流的构造器
  3. 创建相应的字节或字符数组
  4. .close() 关闭流
  5. 对异常进行 try-catch-finally 处理

1. 文件流

选择原则:对于处理纯文本数据,就优先考虑字符流,除此之外都使用字节流

假设使用文件流读取一个txt文本文件,代码如下:

@Test
public void testFileReader() throws IOException {
//1.File类的实例化
File file = new File("Hello.txt");
//2.FileReader流实例化
FileReader fr = new FileReader(file);
//3.读取字符 read(char[] c):返回每次读入c数组的字符个数,如果到文件末尾,返回-1
char[] c = new char[5];
int len;
while((len = fr.read(c)) != -1){
	String str = new String(c, 0, len);
	System.out.print(str);
	}
//4.关闭流
fr.close();
}

写入txt文件同理

@Test
public void testFileWriter() throws IOException {
//1.File类的实例化
File file = new File("Hello.txt");
//2.FileWriter流实例化
FileWriter fw = new FileWriter(file);
//3.写入字符
fw.write("Hello, world!\n");
//4.关闭流
fw.close();
}

2. 缓冲流

作用:创建一个内置默认大小(8kb)的缓冲数组,通过缓冲区读写,提高读写效率
读取:一次性从文件中读取8kb,存在缓冲区中直到装满,再读取下一个8kb数组
写入:先写到缓冲区中直到写满,再写入文件,使用flush()可强制缓冲区写入文件

实现图片的复制操作

@Test
public void testBufferedStream(){
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        //1.造文件
        File srcFile = new File("图片1.jpg");
        File destFile = new File("图片2.jpg");
        
        //2.造流
        //2.1造节点流
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        //2.2造缓冲流,可以合并书写
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);

        //3.文件读取、写出操作
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bis.read(buffer)) != -1){
            bos.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.关闭流
        if (bos != null){
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bis != null){
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 转换流

  • InputStreamReader:字节数组 -> 字符数组(解码)
  • OutputStreamWriter:字符数组 -> 字节数组(编码)

实现把文本文件由UTF-8编码转为GBK编码格式

@Test
public void test() {
    InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    try {
        //1.造文件、造流
        File file1 = new File("dbcp_utf8.txt");
        File file2 = new File("dbcp_gbk.txt");

        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);

        isr = new InputStreamReader(fis, "utf-8");
        osw = new OutputStreamWriter(fos, "gbk");

        //2.读写过程
        char[] cbuf = new char[20];
        int len;
        while ((len = isr.read(cbuf)) != -1){
            osw.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关流
        if (isr != null){
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (osw != null){
            try {
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4. 打印流

print()和println()都来自字节打印流PrintStream

实现复制文本文件

@Test
public printTest(){
	BufferedReader br = new BufferedReader(new FileReader("copy.txt"));
	PrintStream ps = new PrintStream("printcopy.txt");
	String line;
	while((line = br.readline()) != null){
		ps.println(line);
	}
	br.close();
	ps.close();
}

5. 对象流

序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点,当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

  • ObjectOutputStream:内存中的对象 -> 存储文件、网络发送(序列化过程)
  • ObjectInputStream:存储文件、网络接收 -> 内存中的对象(反序列化过程)

一个对象想要序列化,必须满足以下条件:

  • 实现 java.io.Serializable 接口
  • 提供一个全局常量 serialVersionUID(序列版本号,用于反序列化验证)
  • 该对象的内部属性必须是可序列化的(static和transient修饰的属性不可序列化)

Person类的对象序列化实现

@Test
public void personSerializeTest(){
	Person p = new Person();
	p.name = "张三";
	p.age = 28;
	try{
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Person.dat"));
		oos.writeObject(p);
		oos.close();
		fileOut.close();
	}catch(IOException i){
		i.printStackTrace();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值