Java学习笔记之文件

时间:2023-02-26 16:29:35

一.文件类
1.File类
文件和目录路径的抽象表达形式
1.1构造方法
·File(String pathname):把一个路径名称封装成File对象
·File(String parent, String child):把一个父路径和一个子路径封装成一个File对象
·File(File parent, String child):把一个父路径File对象和一个子路径封装成一个File对象
1.2创建功能
A:创建文件
public boolean createNewFile():如果文件不存在,就创建。否则,不创建。
需求:D盘下造一个文件a.txt
import java.io.File;
import java.io.IOException;

        public class CreatFileDemo {
public static void main(String[] args) throws IOException {
File file = new File("D://a.txt");
System.out.println(file.createNewFile());
}
}
B:创建目录
public boolean mkdir():如果目录不存在,就创建。否则,不创建。
需求:D盘下造一个文件夹test
import java.io.File;

public class CreatDemo2 {
public static void main(String[] args) {
File file = new File("D://test");
System.out.println(file.mkdir());
}
}
public boolean mkdirs():如果目录不存在,就创建。否则,不创建。
即时父目录不存在,也可以连父目录一起创建。
1.3删除功能:
public boolean delete():既可以删除文件,又可以删除目录。且当有此语句是先执行此语句
注意:A:Java程序的删除不走回收站。
B:如果目录内还有内容就不能删除。
1.4路径问题:
A:绝对路径 就是以盘符开始的路径(d:\\test\\aaa\\b.txt)
B:相对路径 就是不以盘符开始的路径(a.txt)
一般都是相对应当前的项目而言的。
1.5
判断功能
public boolean isDirectory():是否是目录
public boolean isFile():是否是文件
public boolean exists():是否存在
public boolean canRead():是否可读
public boolean canWrite():是否可写
public boolean isHidden():是否隐藏


1.6获取功能
public String getAbsolutePath():获取绝对路径
public String getPath():获取相对路径
public String getName():获取名称

二.字节流和字节高效流
2.1 I/O流分类
按流向分可分为输入流和输出流;按数据类型分可分为字节流和字符流,字节流又可分为字节输入流(InputStream抽象类)和字节输出流(OutputStream抽象类);字符流可分为字符输入流(Reader)和字符输出流(Wirter)
2.2
针对以上举个例子是说明
需求:请用字节流往一个文本文件中写一句话:”helloworld”。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

    public class FileOutput {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("D://a.txt");//建立文件
fos.write("HelloWorld".getBytes());//写入文件内容
fos.close();//关流
}
}
2.3
在上面的代码中FileOutputStream是OutputStream的子类,由于OutputSteam是抽象类,所以我们必须使用多态的方式来是想它的具体功能,相应的InputStream的子类是FileInputStream
它们具有对称的方法:
FileOutputStream写数据的方法
write(byte[] b)
write(int b) :一次写一个字节
write(byte[] b, int off, int len) :一次写一个字节数组的一部分
2.4
对于字节输入流和字符输出流有一定的操作流程,以字符输入流为例:
* 字节输入流操作步骤:
* A:创建字节输入流对象
FileInputStream fis = new FileInputStream("a.txt");

* B:调用方法读取数据(一次读取一个字节数组,提升效率)
一次读取一个字节数组: public int read(byte[] b):返回实际读取长度,数据被读取到数组中。
-- 测试方法返回长度?根据String类的构造方法构造字符串
* C:释放资源
fis.close
举个例子:
1.一次复制一个字节
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

//A:把a.txt的内容复制到b.txt中

public class CopyFileDemo {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("D://a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");

int byt;
while((byt = fis.read()) != -1){
fos.write(byt);
System.out.print((char)byt);
}

fos.close();
fis.close();
}
}

2.一次复制一个字节数组
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class CopyFileDemo2 {
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("D://b.mp4");
FileOutputStream fos = new FileOutputStream("c.mp4");

byte[] chs = new byte[1024];
int len;
while((len = fis.read(chs)) != -1){
fos.write(chs, 0, len);
}

fos.close();
fis.close();

}
}
2.5
字节缓冲区流(也叫高效流):
BufferedInputStream(read() 一次读取一个字节, public int read(byte[] b):返回实际读取长度,数据被读取到数组中。)
BufferedOutputStream(write(byte[] b))

流:
低级流: 基本的流,可以直接操作文件。
高级流:是操作基本流的流。

A:高效字节流一次读写一个字节
并计算时间

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedDemo {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://b.mp4"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d.mp4"));

int byt;
while((byt = bis.read()) != -1){
bos.write(byt);
}

bos.close();//关流
bis.close();

long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime + "ms");
}
}
B:高效字节流一次读写一个字节数组,并计算时间
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedDemo2 {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://b.mp4"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e.mp4"));

byte[] byt = new byte[1024];
int len;
while((len = bis.read(byt)) != -1){
bos.write(byt, 0, len);
}

bos.close();//关流
bis.close();

long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime + "ms");
}
}
2.6
编码问题:在java中默认的编码方式是GBK,还有另一种是UTF-8。两者之间需要我们手动切换,切记一点,用什么编码就要用什么解码
所谓编码就是把我们能够看得懂的字符转换蔚看不懂的;解码就是把我们看不懂的转换为我们可以看懂的

三.字符流和字符高效流
Reader(抽象类):用于读取字符流的抽象类。子类必须实现的方法只有read(char[], int, int)和close(),但多数子类将重写更多的方法以提供更高的效率
Wirter(抽象类):写入字符流的抽象类,必须重写的方法有write(char[], int, in ),flush(),close()方法,但是多数子类将重写更多的方法,以得到更高的效率和功能
1.1字节流和符流
OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
InputStreamReader:是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

    写入数据,把字节输出流转换为字符输出流(不指定码表)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));

把字节输出流转换为字符输出流(指定码表)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt", "GBK"));

读取数据, 把字节输入流转换为字符输入流(不指定码表)
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
把字节输入流转换为字符输入流(指定码表)
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt", "GBK"));

总结:我们一般创建字符输入或者输出流一般情况下使用系统默认的码表就可以,如果来来回回需要指定码表的话,就显得非常的麻烦了
1.2构造方法
FileWriter(File file)
FileWriter(String fileName)
FileReader(File file)
FileReader(String fileName)
这里需要注意一下FileWriter中的方法flush()和close()的区别?
* A:flush 刷新缓冲区,流对象可以继续
* B:close 先刷新缓冲区,再关闭流对象。流对象不可以继续使用了。
练习上述问题:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter(new File("e.txt"));
fw.write("假如生活欺骗了你,不要悲伤,不要难过,忧郁的日子将会过去,快乐的日子将会来临");
fw.flush();
fw.close();
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fi = new FileReader(new File("e.txt"));
int ch;
while ((ch=fi.read())!=-1) {
System.out.print((char)ch);
}
/* char[] cha = new char[1024];
int len;
while((len = fi.read(cha)) != -1){
System.out.print(new String(cha, 0, len));
} */

fi.close();
}
}
1.3高效流(更多方法可查阅API)
* BufferedReader:字符缓冲输入流
构造:BufferedReader(Reader in)
特殊方法:public String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

* BufferedWriter:字符缓冲输出流
构造:BufferedWriter(Writer out)
特殊方法:public void newLine():会根据系统来确定写入不同的换行符
利用字符高效流的一次读写一行的特性复制文件
写数据注意三部曲:
bw.write(line);
bw.newLine();
bw.flush();
针对上述的知识点,可以通过一个练习键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低存入文本文件

四.设计模式(了解)
A:设计模式概述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰.

B:设计模式分类
创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
行为型模式(对象的功能): 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
结构型模式(对象的组成): 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、
解释器模式、状态模式、策略模式、职责链模式、访问者模式。


单例设计模式(掌握)
A:单例设计思想
保证类在内存中只有一个对象
B:如何实现类在内存中只有一个对象呢?
构造私有
本身提供一个对象
通过公共的方法让外界访问
C:案例演示: 单例模式之饿汉式

问题:面试中写哪种设计模式呢?

工厂设计模式(掌握)
(简单工厂模式概述和使用)(理解)
A:简单工厂模式概述: 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
B:优点: 使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,
而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品。
明确了类的职责
C:缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,
就需要不断的修改工厂类,不利于后期的维护
D:案例演示


(抽象工厂模式的概述和使用)(理解)
A:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
B:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,
只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
C:缺点: 需要额外的编写代码,增加了工作量

五.异常
1.1
异常:就是程序出现的不正常的情况。

举例:

异常:
错误:这是非常严重的问题,一般我们处理不了,一般在这里指的是硬件问题。
异常:
编译时期异常 开始就必须要处理的,如果不处理,后面就走不了。
运行时期异常 开始可以不用处理。这种问题一旦发生,就是我们的程序问题,需要我们修改程序。

体系结构:
Throwable:
Error:
Exception:
非RuntimeException:编译时期异常
RuntimeException:运行时期异常

异常演示:
除数不能为0

java.lang.ArithmeticException: / by zero

针对异常,JVM默认的处理方案:
一旦遇到程序出现了问题,就会把问题的类名,错误原因,错误的位置等信息打印在控制台,以便我们观察。
并且,会自动从当前出问题的地方停止掉。

这种处理方案虽然可以,但是不够好。
哪里不好呢?
其实程序出问题,不应该直接停止,因为我们的程序可能是由多部分组成的,
其中一个部分出问题了,不应该影响其他部分的执行。
所以,我们应该想办法让其他的部分能够执行下去。
1.2

我们是如何处理异常,保证各个部分不影响的呢?
两种方案:
A:try…catch…finally
B:throws

try…catch…finally:
try{
可能出现异常的代码
}catch(异常类名 变量名) {
针对异常的代码处理
}finally {
释放资源的地方
}

我们简化一下第一个:
try{
可能出现异常的代码
}catch(异常类名 变量名) {
针对异常的代码处理
}
1.3
多个异常的处理(演示数组索引越界异常,除数为0异常)
A:针对每一个出现问题的地方写一个try…catch语句
B:针对多个异常,采用一个try,多个catch的情况。
try…catch…catch…

    遇到try里面的问题,就自动和catch里面进行匹配。
一旦匹配就执行catch里面的内容,执行完毕后,接着执行后面的代码。

注意:
如果异常间有子父关系,父必须在最后。

1.4
编译时期异常和运行时期异常的区别:
编译时期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译
FileNotFoundException(文件未找到异常)
运行时期异常:无需显示处理,也可以和编译时异常一样处理
ArithmeticException
1.5
Throwable中的方法:(演示除数为0异常)
rintStackTrace():打印异常信息,程序从出问题的地方开始就会打印创建一个该异常对应的对象,
该对象直接调用打印方法

1.6(演示编译器异常,运行期异常)
try…catch 是直接进行了处理。
而throws则是把异常处理的事情交给了调用者。

throws用在方法上,声明方法有异常,交给调用者处理。
但是呢,如果是编译时期异常,调用就必须处理。
如果是运行时期异常,调用者可以处理,也可以不处理。
1.7
throws:(演示文件未找到异常,除数为0异常)
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用,号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能,并不一定会发生这些异常
1.8
异常处理:
try…catch…finally

finally:一般用于释放资源。在数据库操作或者IO流比较常见。

特点:
被finally控制的语句体一定会执行

    特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))

1.9
finally相关的面试题:
final,finally的区别?
final:最终的意思。可以修饰类,方法,变量。
修饰类,类不能被继承
修饰方法,方法不能被重写
修饰变量,变量是常量
finally:
异常处理的一部分。被finally控制的代码一定会执行。
特殊情况:在执行到finally之前,jvm退出了。
1.9.1
注意:
A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
B:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

    上述仅仅针对编译时期异常
与运行时期异常无关。

1.9.2
throw和throws的区别?
throws:
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常

throw:
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常?
案例演示:演示编译时期异常(文件未找到异常)和运行时期异常(除数为0异常)使用上的区别
throw:
如果throw的是编译时期异常,在方法声明上必须用throws进行标记

这里写代码片