一、流的概念
流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。
一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。
流的方向是重要的,根据流的方向,流可分为两类:输入流和输出流。用户可以从输入流中读取信息,但不能写它。相反,对输出流,只能往输入流写,而不能读它。
便于理解,这么定义流: 流就是一个管道里面有流水,这个管道连接了文件和程序。流的本质是数据传输
流的分类:
Java中的流,可以从不同的角度进行分类。
按照数据流的方向不同可以分为:输入流和输出流。
按照处理数据单位不同可以分为:字节流和字符流。
字节流:一次读入或读出是8位二进制。
字符流:一次读入或读出是16位二进制。
字节流和字符流的原理是相同的,只不过处理的单位不同而已。后缀是Stream是字节流,而后缀是Reader,Writer是字符流。
使用场景:
纯文本:优先字符流
图片、视频、音频等二进制文件:优先字节流
不确定文件类型:优先字节流
(字节流是万能的流)
二、文件File类
File有三种构造方法:
File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File(String parent, String child):从父路径名字符串和子路径名字符串创建新的 File实例
File(File parent, String child):从父抽象路径名和子路径名字符串创建新的 File实例
File的创建功能:
1、public boolean mkdir()
创建由此抽象路径名命名的目录
2、public boolean mkdirs()
创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
3、public boolean createNewFile()
当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
注:1、要看创建的是文件还是目录看方法而不是路径名
2、同一目录下不能由名字相同的多个文件或目录
File的判断功能
1、public boolean isDirectory()
测试此抽象路径名表示的File是否为目录
2、public boolean isFile()
测试此抽象路径名表示的File是否为文件
3、public boolean exists()
测试此抽象路径名表示的File是否存在
File的获取功能
1、public String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串
2、public String getPath()
将此抽象路径名转换为路径名字符串
3、public String getName()
返回由此抽象路径名表示的文件或目录的名称
4、public String[] list()
返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
5、public File[] listFiles()
返回此抽象路径名表示的目录中的文件和目录的File对象数组
File的删除:public boolean delete()
删除由此抽象路径名表示的文件或目录
如果要删除的目录下有内容,那么要先把内容删除才能再删除目录
二、递归
递归的特点:
1、编程的角度来看,递归指的是方法定义中调用方法本身的现象
2、把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
3、递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
使用递归解决问题需要注意两个方面:
1、递归出口:否则会内存溢出
2、递归规则:与原问题相似的规模较小的问题
三、字节流
1、字节流的抽象基类:
InputStream:这个抽象类是表示字节输入流的所有类的超类
OutputStream:这个抽象类是表示字节输出流的所有类的超类
2、使用字节流的步骤:
1)创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
2)调用字节输出流对象的写数据方法
3)释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
3、字节输出流
FileOutputStream(String name):创建文件输出流以指定的名称写入文件
写数据:
void write(int b)
一次写一个字节数据
void write(byte[] b)
一次写一个字节数组数据
void write(byte[] b, int off, int len)
一次写一个字节数组的部分数据
(从数组下标off开始长度为len的数据)
换行符:
windows:\r\n
linux:\n
mac:\r
追加写入:
public FileOutputStream(String name,boolean append)
创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
异常处理:
可以选择使用throws将IOException抛出,
也可以使用:try-catch-finally处理
4、字节输入流
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream ,该文件由文件系统中的路径名name命名
使用步骤(一次读取一个字节数组):
5、字节缓冲流
BufferedOutputStream(OutputStream out)
BufferedInputStream(InputStream in)
一次读入一个字节数据:
一次读入一个字节数组数据
四、字符流
字符流=字节流+编码表
抽象基类:Reader,Writer
1、常见字符集
ASCI字符集
GBXXX字符集:GBK
Unicode字符集:UTF-8编码
2、编码解码相关方法:
byte[] getBytes()
使用平台的默认字符集将该 String编码为一系列字节
byte[] getBytes(String charsetName)
使用指定的字符集将该 String编码为一系列字节
String(byte[] bytes)
使用平台的默认字符集解码指定的字节数组来创建字符串
String(byte[] bytes, String charsetName)
通过指定的字符集解码指定的字节数组来创建字符串
3、字符输入流
InputStreamReader
是从字节流到字符流的桥梁
InputStreamReader(InputStream in)
InputStreamReader(InputStream in,String chatset)
字符流读数据的2种方式:
int read():一次读一个字符数据
int read(char[] cbuf):一次读一个字符数组数据
4、字符输出流
OutputStreamWriter
是从字符流到字节流的桥梁
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out,String charset)
字符流写数据的五种方式:
1)void write(int c)
写一个字符
2)void write(char[] cbuf)
写入一个字符数组
3)void write(char[] cbuf, int off, int len)
写入字符数组的一部分
4)void write(String str)
写一个字符串
5)void write(String str, int off, int len)
写一个字符串的一部分
刷新和关闭方法
flush():刷新流,之后还可以继续写数据
close():关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
5、字符缓冲流
BufferedWriter(Writer out)
void newLine()
写一行行分隔符,行分隔符字符串由系统属性定义
BufferedReader(Reader in)
String readLine()
读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
6、复制文件的异常处理:
五、特殊流&Properties集合
1、标准输入流:public static final InputStream in
2、标准输出流:public static final PrintStream out
3、字节打印流:PrintStream
public static void setOut(PrintStream out):
重新分配“标准”输出流
4、字符打印流:PrintWriter
构造方法:
PrintWriter(String fileName)
使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
PrintWriter(Writer out, boolean autoFlush)
创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区
5、对象序列化流
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
构造方法:
ObjectOutputStream(OutputStream out)
方法:
void writeObject(Object obj)
将指定的对象写入ObjectOutputStream
假如我们修改了对象所属的类文件,可以重新序列化,
也可以给对象所属的类加一个serialVersionUID:
private static final long serialVersionUID = 42L;
transient
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
例如:
6、对象反序列化流
对象反序列化:把对象信息从文件中读取回来,重构对象
构造方法:ObjectInputStream(InputStream in)
方法:
Object readObject()
从ObjectInputStream读取一个对象
7、Properties
创建对象:
Properties作为Map集合的特有方法:
Object setProperty(String key, String value)
设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
String getProperty(String key)
使用此属性列表中指定的键搜索属性
Set<String> stringPropertyNames()
从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
和IO流结合的方法:
void load(InputStream inStream)
从输入字节流读取属性列表(键和元素对)
void load(Reader reader)
从输入字符流读取属性列表(键和元素对)
void store(OutputStream out, String comments)
将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流
void store(Writer writer, String comments)
将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流