前言
??近期学习了IO流,Java为I/O提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。为了帮助大家更好的学习,博主对IO流做了一下知识点回顾和总结,希望能够帮助到大家的学习,欢迎各位和博主进行交流 !
文件File类
概述 ??在学习IO流之前,我们需要了解一个File类文件,为什么要了解它呢?
??原因:IO流操作中大部分都是对文件进行操作,所以Java就提供了一个File类供我们来操作文件,File是文件和目录(文件夹)路径名的抽象表现形式
构造方法
??知道了,File的概述,接下来我们去了解它的构造方法: ??1.File(String pathName) ????根据字符串路径创建一个File对象 ??2.File(String parent,String child) ????根据字符串父级路径和子级路径创建File对象 ??3. File(File parent,String child) ????根据File类型父级路径和字符串子级路径创建File对象
成员方法
??再跟随博主走进它的成员方法,关于File的成员方法,我在这里总结了它的6大功能: 1.创建功能: ??1.boolean createNewFile() 创建一个新文件,如果存在就返回false ??2.boolean mkdir() 创建文件夹,如果存在一样的文件夹,就返回false ??3.boolean mkdirs() 创建多个文件夹,如果父类文件夹不存在,会帮你自动创建出来,如果存在一样的文件夹,则返回false ??4.注意 如果你创建文件或文件夹忘了写路径,那么默认在当前路径创建 2.删除功能: ??public boolean delete() ??注意: ??要删除一个文件夹,请注意该文件内不能包含文件或者文件夹 Java中删除不走回收站 3.重命名功能: ??public boolean renameTo(File dest) ??如果路径名相同,就是改名 ??如果路径名不同,就是改名并剪切 例子 ??//创建一个文件对象 ?? File file = new File(“F:\IDEA\syy.txt”); ?? File file1 = new File(“F:\IDEA\sys.txt”); ??System.out.println(file.renameTo(file1)); 4.判断功能: ??1).public boolean isDirectory() ????判读是否是文件夹 ??2).public boolean isFile() ????判断是否是文件 ??3).public boolean exists() ????判断文件或文件夹是否存在 ??4).public boolean canRead() ????判断是否可读 ??5).public boolean canWrite() ????判断是否可写 ??6).public boolean isHidden() ????判断文件或文件夹是否隐藏 5.获取功能: A.基本获取功能: ??a. public String getAbsolutePath() ???? 获取绝对路径 ?? b. public String getPath() ????获取构造方法中的路径 ??c. public String getName() ????获取文件或文件夹的名称 ??d. public long length() ????获取长度–字节数-可以获取文件的大小进行判断 ??e. publlic long lastModifiled() ????获取最后一次修改的时间,返回毫秒值,可以判断修改过几次 B.高级获取功能: ??1).public String[] list() ????获取目录下所有内容,返回字符串数组 ??2).public File[] listFiles() ????获取目录下所有内容,返回File对象数组 6.文件过滤功能: ??1).想获取的时候就满足条件,要实现文件过滤接口 ??2).public String[] listFiles (new FilenameFilter)
递归
??再这里我们来讲一种递归的方法,至于用来干什么呢,那么就是遍历目录下所有的文件: 递归概述: ??方法定义调用本身的现象
注意事项
1.递归一定要有出口
2.递归的次数不能太多,否则就内存溢出
3.构造方法不能递归使用
案例
不死神兔案例
删除指定目录下的指定后缀名文件
删除指定目录下所以文件和文件夹
IO流概述
1.IO流用来处理设备之间的数据传输,上传文件和下载文件
2.按照数据流向:
a.输入流
数据从外部流入写的程序
b.输出流
数据从程序流到外面
3.按照数据类型分类:
a.字节流
?字节输入流
读取数据
?字节输出流
写入数据
b.字符流
?2或3个字节=1个字符
?字符输入流
读取数据
?字符输出流
写入数据
4.到底使用哪种类型的流呢?
如果操作的数据是文本文件,就用记事本打开,能读懂的就用字符流,不能读懂的就用字节流,什么也不知道的就用字节流
IO流常用基类
字节流的抽象基类
1.InputStream
a.读取数据
字节输入流
b.子类
FileInputStream
●构造方法
? FileInputStream(String name)
创建字节输入流对象,带文件路径或名称
●方法
? public int read()
此输入流中读取一个字节,如果已到文件末尾,则返回-1
? public int read(byte [ ] b)
一次读取一个字节数组,返回读取字节数的个数,如果已到文件末尾,则返回-1
c.字节输入流操作步骤
1.创建字节输入流对象
2.调用read( )方法读取数据,并把数据显示在控制台
3.释放资源
d.字节缓冲输入流
1).作用
提高读取效率
2).格式
BufferedInputStrearm(FileInputStream)
3).举例
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\IDEA\\视频.avi"));
2.OutputStream
a.写入数据
字节输出流
b.字节流写数据同时处理异常的重要步骤
1.将创建字节流对象和写出数据的代码放在try中
2.在catch中捕获IOException异常
3.在finally中进行释放资源
1.子类
FileOutputStream
●构造方法:
? FileOutStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流
? FileOutStream(File file)
创建一个向指定File对象表示的文件中写入数据的文件输出流
●方法:
? public void close()
关闭次文件输出流并释放此流有关的所有系统资源
为什么一定要用close呢?
1).让流对象变成垃圾,这样就可以呗垃圾收器回收了
2).通知系统去释放跟该文件相关的资源
? public void write(byte[ ] b)
写入一个字节数组
? public void write(byte[ ] b,int off,int len)
写入一个字符数组的一部分,off索引开始,len索引结束
? public void write (int b)
写入一个字节
●如何实现数据的追加写入?
用构造方法带第二参数是true即可
FileOutStream fos =new FileOutStream("j.txt",true);
●如何实现数据的换行?
1).windows
添加一个\r\n
例如: fos.write(" \r\n".getBytes);
2).linux
\n
3).Mac
\r
2.字节输出流的操作步骤
△.创建字节输出流对象
△.写入数据
△.释放资源
字符流的抽象基类
字符流
为什么会出现字符流?
1.?(?????)?字符流的介绍:
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
2.?(?????)?中文的字节存储方式:
a.用字节流复制文本文件时,文本文件也会有中文,但是没有问题
b.原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
c.汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
刷新和关闭方法
字符串中的编码解码问题
相关方法:
??字符流中和编码解码问题相关的两个类:
1.InputStreamReader
2.OutputStreamWriter
●InputStreamReader:
a.是从字节流到字符流的桥梁
b.它读取字节,并使用指定的编码将其解码为字符
c.它使用的字符集可以有名称指定,也可以被明确指定,或者可以接受平台的默认字符集
●OutputStreamWriter:
a.是从字符流到字节流的桥梁
b.使用指定的编码将写入的字符编码为字节
c.它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
构造方法:
字符流读取数据的2种方式: ??1.int read() :一次读一个字符数据 ??2.int read(char [ ] cbuf) : 一次读一个字符数组数据
字符缓冲流
介绍:
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,
可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
特有功能 ??BufferedWriter: ????void newLine( ) : 写一行行分隔符,行分隔符字符串由系统属性定义 ??BufferedReader: ????String readLine( ) : 读一行文字,结果包含行的内容的字符串,不包括任何终止字符如果流的结尾已经到达,则为null。
其他特殊流
打印流
对象序列化流
-
对象序列化介绍: ??1.对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象 ??2.这种机制就是使用一个字节序列表示一个对象,该字节序列包含: ??对象的类型、对象的数据和对象中存储的属性等信息 ??字节序列写到文件之后,相当于文件中持久保存了一个对象的信息 ??反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化 -
对象序列化流: ObjectOutputStream ??将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象 构造方法: 序列化对象的方法: 注意事项: -
一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口 -
Serializable是一个标记接口,实现该接口,不需要重写任何方法
对象反序列化流
ObjectInputStream:反序列化先前使用
ObjectOutputStream:编写的原始数据和对象
构造方法
反序列化对象的方法 serialVersionUID&transient serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,会抛出InvalidClassException异常
- 如果出问题了,如何解决呢?
- 重新序列化
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;
transient
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
Properties
Properties介绍
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
作为Map集合的特有方法: Properties和IO流相结合的方法:
IO流常见面试题
1.字节流和字符流哪个好?怎么选择? ??大多数情况下使用字节流会更好,因为大多数时候 IO 操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的(图片等都是按字节存储的) ??如果对于操作需要通过 IO 在内存中频繁处理字符串的情况使用字符流会好些,因为字符流具备缓冲区,提高了性能。 2. 什么是缓冲区?有什么作用? ??缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性。 ??对于 Java 字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用 flush() 方法操作。 3.字符流和字节流有什么区别? ??字符流和字节流的使用非常相似,但是实际上字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件 4.什么是Java序列化,如何实现Java序列化? ??序列化就是一种用来处理对象流的机制,将对象的内容进行流化。可以对流化后的对象进行读写操作,可以将流化后的对象传输于网络之间。序列化是为了解决在对象流读写操作时所引发的问题 ??序列化的实现:将需要被序列化的类实现Serialize接口,没有需要实现的方法,此接口只是为了标注对象可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,再使用ObjectOutputStream对象的write(Object obj)方法就可以将参数obj的对象写出 5. PrintStream、BufferedWriter、PrintWriter的比较? ??PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream后进行输出。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream ??BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符,数组和字符串的高效写入。通过write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去。并且BufferedWriter只能对字符流进行操作。如果要对字节流操作,则使用BufferedInputStream ??PrintWriter的println方法自动添加换行,不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生,PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush) 6. BufferedReader属于哪种流,它主要是用来做什么的,它里面有那些经典的方法? ??属于处理流中的缓冲流,可以将读取的内容存在内存里面,有readLine()方法,它,用来读取一行 7.什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征? ??节点流: 直接与数据源相连,用于输入或者输出 ??处理流:在节点流的基础上对之进行加工,进行一些功能的扩展 ??处理流的构造器必须要 传入节点流的子类 8.流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是怎么关闭的? ??流一旦打开就必须关闭,使用close方法 ??放入finally语句块中(finally 语句一定会执行) ??调用的处理流就关闭处理流 ??多个流互相调用只关闭最外层的流
总结(附猜拳小游戏代码)
??通过上面的知识点回顾,我们能够了解到IO流的两种方式,一个是字节流,一种是字符流,字节流是可以复制任意文件的数据,而字符流只能复制文本数据,虽然它能够使用复制图片视频,但不能显示。 ??最后给大家附上一个小游戏的参考代码,有兴趣的可以下载试玩一下,还是蛮有趣的。 链接:https://pan.baidu.com/s/1v4iORhRjr-f3WDHJ9pamvw 提取码:yy52 链接代码
|