IO流总结

IO流总结

1.使用IO流的四点明确

1. 明确要操作的数据是数据源还是数据目的(是读还是要写)

数据源(读):
IntupStream
Reader

目的数据(写):
Outputstream
Writer

2.明确要操作的设备上的数据是字节还是文本

数据源:
字节:InputStream
文本:Reader
目的数据:
字节:OutputStream
文本: Writer
3. 明确数据所在的具体设备
源设备:

硬盘:文件 File开头
内存:数组,字符串
键盘:System.in
网络:Socket

对应目的设备:

硬盘:文件 File开头
内存:数组,字符串
屏幕:System.out
网络:Socket

4. 明确是否需要额外功能

需要转换 – 转换流 InputStreamReader,OutputStreamWriter
需要高效 –缓冲流BufferedReader,BufferedWriter
多个源 – 序列流 SequenceInputStream
对象序列化 – ObjectInputStream,ObjectOutputStream
保证数据的传输形式 –打印流 PrintStream,PrintWriter
操作基本数据,保证字节原样性 – DataOutputStream,DataInputStream

IO流的分类 :
在这里插入图片描述

2.File类

至于IO流,也就是输入输出流,从文件出发到文件结束,最终还是离不开文件,所以IO流还得从文件File类讲起.

2.1File概述

java.io.File类是专门对文件进行操作的类,只能对文件本身进行操作,不能对文件内容进行操作
java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建,查询和删除等操作.

解析上面的两句话
第一句话意思就是说File跟流无关,File类不能对文件进行读和写,也就是不能对文件的内容进行输入或者输出.
第二句话就是说File主要表示类似D:\文件目录1****与D:\文件目录1\文件.txt,前者是文件夹(Directory)后者则是文件(file),而File类就是操作这两者的类.

2.2构造方法

在Java中,一切皆对象,File类也不例外,不论是哪个对象都应该从该对象的构造说起,这里分析File类的构造方法,先从API着手
在这里插入图片描述
主要学习比较常用的三个:

  1. public File(String pathname):通过将给定的路径名字符串转化为抽象路径名来创建新的File实例
  2. public File(String parent, String child):父路径名字符串和子路径名字符串创建新的File实例
  3. public File(File parent, String child) :父抽象路径名和子路径名字符串创建新的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 = "D:\\aaa";
String child = "bbb.txt";
File file3 = new File(parent,child); //相当于D:\\aaa\\bbb.txt

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

File类的注意点:

  1. 一个Flie对象代表硬盘中实际存在的一个文件或者目录
  2. File类构造方法不会检验这个文件是否真实存在,因为无论该路径下是否存在文件或者目录,都不影响File对象的创建

2.3常用方法

File的常用方法主要分为获取功能,获取绝对路径和相对路径,判断功能,创建删除功能的方法

2.3.1获取功能的方法
  1. **public String getAbsolutePath() 😗*返回此File 的绝对路径名字符串
  2. public String getPath(): 将此File转化为路径名字符串
  3. public String getName(): 返回由此File表示的文件或目录的名称.
  4. public long length(): 返回由此File表示的文件长度.

以上方法测试,代码如下:

public class FileGet{
public static void main(String[] args){
File f = new File("d:/aaa/bbb.java");
       System.out.println("文件绝对路径:"+f.getAbsolutePath());
       System.out.println("文件构造路径:"+f.getPath());
       System.out.println("文件名称:"+f.getName());
       System.out.println("文件长度:"+f.length()+"字节");
File f2 = new File("d:/aaa");     
       System.out.println("目录绝对路径:"+f2.getAbsolutePath());
       System.out.println("目录构造路径:"+f2.getPath());
       System.out.println("目录名称:"+f2.getName());
       System.out.println("目录长度:"+f2.length());

}
}

输出结果:

文件绝对路径:d:\aaa\bbb.java
文件构造路径:d:\aaa\bbb.java
文件名称:bbb.java
文件长度:2116字节

目录绝对路径:d:\aaa
目录构造路径:d:\aaa
目录名称:aaa
目录长度:3236

注意: **length()**表示文件的长度.但是 File 对象表示目录,则返回值未指定.

相对路径和绝对路径

相对路径:一个简化的路径,不已盘符开头,例如://aaa.txt//b.txt
绝对路径: 一个完整的路径,以盘符开头,例如:D://aaa.txt.

  1. 路径是不区分大小写的
  2. 路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠
//绝对路径
public class FilePath{
public static void main(String[] args){
       // D盘下的bbb.java文件
        File f = new File("D:\\bbb.java");
        System.out.println(f.getAbsolutePath());
      	
		// 项目下的bbb.java文件
        File f2 = new File("bbb.java");
        System.out.println(f2.getAbsolutePath());
}
 }

输出结果:

D:\bbb.java
D:\java\bbb.java
判断功能的方法
  1. **public boolean exists() :**此File表示的文件或目录是否实际存在。
  2. **public boolean isDirectory() :**此File表示的是否为目录。
  3. **public boolean isFile() :**此File表示的是否为文件。

方法演示:

public class FileIs {
    public static void main(String[] args) {
        File f = new File("d:\\aaa\\bbb.java");
        File f2 = new File("d:\\aaa");
      	// 判断是否存在
        System.out.println("d:\\aaa\\bbb.java 是否存在:"+f.exists());
        System.out.println("d:\\aaa 是否存在:"+f2.exists());
      	// 判断是文件还是目录
        System.out.println("d:\\aaa 文件?:"+f2.isFile());
        System.out.println("d:\\aaa 目录?:"+f2.isDirectory());
    }
}

输出结果:

d:\aaa\bbb.java 是否存在:true
d:\aaa 是否存在:true
d:\aaa 文件?:false
d:\aaa 目录?:true
创建删除功能的方法
  1. public boolean createNewFile(): 文件不存在,创建一个新的空文件并返回,true,文件存在,不创建文件并返回flase.
  2. public boolean delete() : 删除由此File表示的文件或目录.
  3. public boolean mkdir() : 创建由此File表示的目录.
  4. public boolean mkdirs() : 创建由此File表示的目录,包括任何必需但不存在的父目录

其中,mkdir()和mkdirs() 方法类似,但,mkdir() 只能创建一级目录,而mkdirs(),可以创建多级目录

方法测试:

public class FileCreateDelete {
    public static void main(String[] args) throws IOException {
        // 文件的创建
        File f = new File("aaa.txt");
        System.out.println("是否存在:"+f.exists()); // false
        System.out.println("是否创建:"+f.createNewFile()); // true
        System.out.println("是否创建:"+f.createNewFile()); // 以及创建过了所以再使用createNewFile返回false
        System.out.println("是否存在:"+f.exists()); // true
		
     	// 目录的创建
      	File f2= new File("newDir");	
        System.out.println("是否存在:"+f2.exists());// false
        System.out.println("是否创建:"+f2.mkdir());	// true
        System.out.println("是否存在:"+f2.exists());// true

		// 创建多级目录
      	File f3= new File("newDira\\newDirb");
        System.out.println(f3.mkdir());// false
        File f4= new File("newDira\\newDirb");
        System.out.println(f4.mkdirs());// true
      
      	// 文件的删除
       	System.out.println(f.delete());// true
      
      	// 目录的删除
        System.out.println(f2.delete());// true
        System.out.println(f4.delete());// false
    }
}

注意:delete方法,如果此file表示目录,则目录必须为空才能删除

目录的遍历

  1. public String[] list(): 返回一个String数组,表示该File目录中的所有子文件或目录
  2. public File[] listFailes() : 返回一个File数组,表示该File目录中的所有的子文件或目录.
public class FileFor {
    public static void main(String[] args) {
        File dir = new File("G:\光标");
      
      	//获取当前目录下的文件以及文件夹的名称。
		String[] names = dir.list();
		for(String name : names){
			System.out.println(name);
		}
        //获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

ListFile在获取指定目录下的文件或者文件夹时必须满足下面两个条件

  1. 指定的目录必须存在
  2. 指定的必须是目录.否则容易引发返回数组为null,出现NullPointerException异常.

2.5. 递归遍历文件夹下所有文件以及子文件

import java.io.File;

//递归遍历文件夹下所有的文件
public class RecursionDirectory {
    public static void main(String[] args) {
      File file=new File("D:\\java专属IO测试");
        Recursion(file);
    }
    public static void Recursion(File file){
        //1、判断传入的是否是目录
        if(!file.isDirectory()){
            //不是目录直接退出
            return;
        }
        //已经确保了传入的file是目录
        File[] files = file.listFiles();
        //遍历files
        for (File f: files) {
            //如果该目录下文件还是个文件夹就再进行递归遍历其子目录
            if(f.isDirectory()){
                //递归
                Recursion(f);
            }else {
                //如果该目录下文件是个文件,则打印对应的名字
                System.out.println(f.getName());
            }

        }
    }
}

3. 初识IO流

3.1什么是IO

我们把数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input和输出output,即流向内存是输入,流出内存就是输出.
Java 中I/O操作主要是指使用java.io,包下的内容,进行输入输出操作.输入也叫读取数据,输出也叫做写出数据.

3.2IO流的分类

根据数据的流分为: 输入流输出流
**输入流: **把数据从其他设备读取到内存中的流.
**输出流: **把数据从内存读取到其他设备上的流.

根据数据的类型分为:字节流字符流

**字节流: **以字节为单位,读取数据的流
**字符流: **以字符为单位,读取数据的流
分类之后所对应的父类:

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

3.3 关于IO的分流向说明

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

3.4 OutputStream和InputStream

输入流的层级关系:
在这里插入图片描述
输出流的层级关系
在这里插入图片描述

3.5流中常用的方法:

1. 字节输入流InputStream:

read( ) 读字节
flush() 刷新流
close() 关闭流
mark() 标记此输入流中的当前位置
skip(n) 跳过并丢弃来自此输入流的n个字节数据

2. 字节输出流 OutputStream

writer() 写字节
flush() 刷新流
close() 关闭流

3. 字符输入流 Writer

writer() 写字符
flush() 刷新
close() 关闭
append() 添加内容

4. 字符输出流 Reader

close() 关闭流
mark() 标记流中当前位置
markSupported() 告诉这个流是否支持mark()操作
read() 读字符
reset() 重置流
skip 跳过字符

3.6 文件里一切皆为字节

我们必须明确的一点是,一切文件数据(文本,图片,视频等)在存储时,都是以二进制数字的形式保存,都是一个一个的字节,那么传输时一样如此.所以,字节流可以传输任何文件数据,在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据.

3.7 四个抽象的父类

字节流

InputStream:

read() 读数据
void close() 关闭输入流
int available() 从输入流中返回数目
skip(long) 从输入流中返回数目
boolean markSupported() 是否支持标记
void mark(int) 在指定位置标记
void reset() 流重新定位到刚做标记的位置

OutputStream

write() byte写到外围设备
void close() 回收系统资源
void flush() 刷新缓冲区

字符流

Reader

BufferedReader

  1. BufferedRead 是带有缓冲区,先将数据读取到缓冲区内,接下来的操作都可以从缓冲区内读取数据,从而提高读取操作的效率
  2. readLine() 方法可以一次读取一行字符,以字符的形式返回,读到换行符’\n’才真正的读到,否则将处于阻塞状态

InputStreamReader

  1. FileReader是InputStreamReader的一个子类,用于从文件中读取字符数据.该类只能按照本地平台的字符编码来读取数据,用户不能指定其他字符编码类型.
  2. InputStreamReader 是字节流转字符流的桥梁,例: InputstreamReader(InputStream in)
  3. InputStreamReader(InputStream in, String charsetName)按照指定的字符编码读取输入流中的字符.

Writer

BufferedWriter

  1. newLine() 方法表示写入转化符
  2. write(String s, int off, int len) off表示开始读取字符的偏移量,len字符串的长度
    PrintWriter
    1. print()方法参数可以是基本数据类型、对象、字符(字符数组)和字符串,但是不能输出字节流。
    2. println()方法和print()方法类似,但会在末尾写上一个换行符
    3. PrintWriter类可以代替桥和BufferedWriter

3.8 编码对字节解析成中文

  1. GBK : 每次解析两个字节作为中文
  2. UTF-8 :每次解析三个字节作为中文
  3. UTF-18: 每次解析四个字节作为中文

4.随机读取流

RandomAccessFile

  1. 直接继承自java.lang.Object,该类的实例支持随机读取和写入文件.
  2. RandomAccessFile(String filename,String mode)mode:“r”/“rw”/“w”
  3. seek(long pointer)方法设置文件指针偏移,可以发生下一次的读取和写入
  4. 用于DatainputStream/DatapitputStream的方法,对基本数据类型的读取和写入
  5. readLine方法,从文件中读取一行的文本,功能类似于BufferReader

序列化

Java 提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该对象的数据,对象的泛型,对象中存储的属性 等信息.字节序列写完到文件之后,相当于文件中持久保存了一个对象的信息.
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化. 对象的数据,对象的类型,对象中存储的数据信息,都可以用来在内存中创建对象.
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值