Java高级API-Day04-IO流

IO流

1、IO流的四点明确

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

源:
InputStream  Reader

目的:
OutputStream  Writer

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

源:
字节: InputStream
文本: Reader

目的:
字节: OutputStream
文本: Writer

(3)明确数据所在的具体设备

源设备:
硬盘:文件 File开头
内存:数组,字符串
键盘:System.in
网络:Socket
对应目的设备:
硬盘:文件 File开头
内存:数组,字符串
屏幕:System.out
网络:Socket

(4)明确是否需要额外功能

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

2、File类

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

1.1 File概述

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

怎么理解上面两句话?其实很简单!

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

1.2 构造方法

在java中,一切皆是对象,File类也不例外,不论是哪个对象都应该从该对象的构造说起,所以博主来分析分析File类的构造方法。
我们主要来学习一下比较常用的三个:

1、 public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
2、 public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
3、 public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

File类的注意点:
一个File对象代表硬盘中实际存在的一个文件或者目录。
File类构造方法不会给你检验这个文件或文件夹是否真实存在,因此无论该路径下是否存在文件或者目录,都不影响File对象的创建。

1.3 常用方法

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

1.3.1 获取功能的方法
1、public String getAbsolutePath():返回此File的绝对路径名字符串。

2、public String getPath():将此File转换为路径名字符串。

3、public String getName():返回由此File表示的文件或目录的名称。

4、public long length():返回由此File表示的文件的长度。

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

1.3.2 绝对路径和相对路径

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

1、路径是不区分大小写
2、路径中的文件名称分隔符windows使用反斜杠,反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

1.3.3判断功能的方法

1、 public boolean exists() :此File表示的文件或目录是否实际存在。
2、public boolean isDirectory():此File表示的是否为目录。
3、public boolean isFile():此File表示的是否为文件。

1.3.4 创建删除功能的方法

public boolean createNewFile():文件不存在,创建一个新的空文件并返回true,文件存在,不创建文件并返回false。
public boolean delete():删除由此File表示的文件或目录。
public boolean mkdir():创建由此File表示的目录。
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。
其中,mkdirs()和mkdir()方法类似,但mkdir(),只能创建一级目录,mkdirs()可以创建多级目录比如//a//b//c,所以开发中一般用mkdirs();

这些方法中值得注意的是createNewFile方法以及mkdir与mkdirs的区别
注意:delete方法,如果此File表示目录,则目录必须为空才能删除。

1.4 目录的遍历

public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

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

1,指定的目录必须存在

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

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

package File;

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流

1.1 什么是IO

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input 和输出output ,即流向内存是输入流,流出内存的输出流。

Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。

1.2 IO的分类

根据数据的流向分为:输入流 和 输出流。

输入流 :把数据从其他设备上读取到内存中的流。
输出流 :把数据从内存 中写出到其他设备上的流。
根据数据的类型分为:字节流 和 字符流。

字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。
分类之后对应的超类(V8提示:超类也就是父类的意思)

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

注:
由这四个类的子类名称基本都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。

字节流写数据的两个小问题
字节流写数据如何实现换行

写完数据后,加换行符
windows:\r\n
linux:\n
mac:\r
字节流写数据如何实现追加写入

public FileOutputStream(String name,boolean append)
创建文件输出流以指定的名称写入文件,如果第二个参数为true,则字节将写入文件的末尾而非开头
字节流写数据加异常处理
finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源
特点:被finally控制的语句一定会执行,除非JVM退出
try{可能出现异常的代码;}
catch(异常类名 变量名){异常的处理代码;}
finally{执行所有清除操作}

为什么会出现字符流
由于字节流操作中文不是特别的方便,所以Java就提供字符流

字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?

汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

1.3 字符串中的编码解码问题

编码:

byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中。
解码:

String(byte[] bytes):通过使用平台的默认字符集编码指定的字节数组来构造新的String
String(byte[] byte,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String

1.4 字符流写数据

方法名 说明
void write(int c) 写一个字符
void writ(char[] cbuf) 写入一个字符数组
void write(char[] cbuf,int off,int len) 写入字符数组的一部分
void write(String str) 写入一个字符串
void write(String str,int off,int len)

1.5 字符流读数据

方法名 说明
int read() 一次读一个字符数据
int read(char[] cbuf) 一次读一个字符数组数据

1.6 字符缓冲流

字符缓冲流:

BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途
构造方法:

BufferedWriter(Writer out)
BufferedReader(Reader in)

1.7 IO流总结

小结:字节流可以复制任意文件数据,有4种方式一般采用字节缓冲流一次读写一个字节数组的方式;字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能

String readLine():一次读取一个字符串
void newLine():写一个换行符
void write(String line):一次写一个字符串

猜你喜欢

转载自blog.csdn.net/weixin_43901457/article/details/113845457