文章目录
学习常用API的过程中,JAVA的文件API File 是文件、目录常用API,是我们学习API的必经之路,也是学习流的一个很好的开端。
1.File 文件
1.1 创建File 对象
1.1.1 绝对、相对路径
文件File中要传的参数少不了文件的路径。
绝对路径、相对路径相信我们已不陌生,都是表示具体文件、目录的路径。下面我们稍微复习一下:
绝对路径是指基于某个操作系统下,从根目录算起的路径,是最完整的表达方式之一:例如
C:\Users\accountNumber\Desktop\Tools\tools.exe
举个例子:
File f = new File("C:\\Users\\accountNumber\\Desktop\\Tools\\tools.exe");
//输出该文件是否存在的boolean结果
System.out.println(f.exists());
相对路径是指当前文件、程序下的相对路径,绝对路径里的冗长目录路径可以用"./"代替,沿用上述例子的路径,相对路径可以表达为:
File f = new File("./tools.exe");
System.out.println(f.exists());
其中"./"可以省略:
File f = new File("tools.exe");
System.out.println(f.exists());
注意,为了兼容LinuxOS等其他OS的路径表示规则,我们实际开发中常用斜杠"/"来表示路径的斜杠,而不是Windows系统复制路径时默认的反斜杠。
1.1.2 创建对象
操作文件通常要通过文件对象,参数为文件的目标路径。
为了程序在不同环境(OS、服务器等)的复用性,强烈建议使用相对路径。
File f = new File("[目标路径]");
1.2 File常用方法
1.2.1 判断文件是否存在
File f = new File("tools.exe");
//exists方法为判断文件是否存在的方法,返回的是boolean值
System.out.println(f.exists());
1.2.2 创建文件
创建文件方法createNewFile ,要注意:此时要抛异常。具体异常处理方式在下面的段落介绍。
public static void main(String[] args) throws IOException {
//当前目录下新建一个文件
File file = new File("./test.txt");
if(file.exists()){
//若该文件已存在
System.out.println("该文件已存在!");
}else{
//若文件不存在,创建文件
file.createNewFile();
}
}
1.2.3 创建目录
即创建文件夹。
//当前目录下创建一个目录
//实际开发中,相对路径的“./可以省略”
File dir = new File(".abc/sdd/demo.abc");
if(dir.exists()){
System.out.println("改目录已存在");
}else{
dir.mkdirs();
System.out.println("该目录已创建");
}
}
1.2.4 判断是否为文件夹或文件
isFile()判断是否为文件
File f = new File("demo.txt");
System.out.println(f.isFile());
isDirectory()判断是否为文件夹
File f = new File("demo.txt");
System.out.println(f.isDirectory());
1.2.5 删除文件、目录
delete()方法,该方法既可以删除文件,也可以删除目录。
删除文件:
File file = new File("test.txt");
if(file.exists()){
file.delete();
System.out.println("该文件已删除");
}else{
System.out.println("该文件不存在!");
}
}
删除目录:
//将当前目录下的demo目录删除
File dir = new File(".abc");
//删除
if(dir.exists()){
//必须是空目录
dir.delete();
System.out.println("该目录已删除");
}else{
System.out.println("该目录不存在");
}
1.2.6 获取当前文件夹列表
listFiles() 方法返回一个文件类型数组
File dir = new File(".");
if(dir.isDirectory()){
File [] subs = dir.listFiles();
for (File sub : subs) {
System.out.println(sub);
}
}
listFiles可以传参,进行文件过滤
//参数用filter
File [] files = dir.listFiles(filter);
其中Filefilter是个接口,要实现,我们可以使用匿名内部类来实例化它的实现类,举个例子:
//获取当前文件夹的所有目录
File dir = new File(".");
if(dir.isDirectory()){
FileFilter filter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
};
File [] files = dir.listFiles(filter);
for(File f : files){
System.out.println(f);
}
}
1.3 文件流
程序往往通过流来与外部设备进行数据交换。对于文件,JAVA使用FileInputStream和FileOutputStream来对文件进行读写。
对IO流的具体学习,可参见百度
1.3.1 FileInputStream
作用:读取文件
例子:
FileInputStream fis = new FileInputStream("./test.txt");
/**
* 读取规则,一位一位地读,输出低八位,余位补0,读到末尾返回-1的补码
* 用基本类型接收的时候,会输出该位的二进制
* */
int index = 24;
while(index > 0 ){
char d = (char) fis.read();
System.out.println(d);
index --;
}
fis.close();
1.3.2 FileOutputStream
作用:写入文件
例子:
//向文件test.txt写入一个字节
FileOutputStream fos = new FileOutputStream("./test.txt");
//以程序为原点,要将东西写入文件,使用输出流
/*
* void write (int d)
* 写出一个字节,写出的内容是给定的int值对应的二进制的低八位
* */
int index = 26;
while(index >0){
fos.write(index+97);
index --;
}
System.out.println("写出完毕");
fos.close();
File f = new File("./test.txt");
if(f.isFile()){
System.out.println(f.length());
}
1.3.3 文件复制
合理使用文件流可以实现文件复制。
举个例子:
//定义流
long now = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("./CpDemoPlus.mp4");
FileOutputStream fos = new FileOutputStream("./CpDemoPlus2.mp4");
//用比较简洁的方式复制
int index;
while ((index = fis.read())!=-1){
fos.write(index);
}
System.out.println("复制完毕!");
fis.close();
fos.close();
long after = System.currentTimeMillis();
System.out.println("复制经历了"+(after-now)+"ms");
2.Exception 异常
异常在我们学习过程中随处可见,例如我们操作数组时,不小心就会出现数组下表越界异常:IndexOutOfBoundsException.
在上面文件与文件流的学习中,我们也遇到了异常,在此我们详细介绍一下异常。
2.1 异常处理
2.1.1 异常分类
Exception 和 Error,他们都是Throwable类的派生类,都实现了Serializable接口。
其中,Exception 通常用于表示用户非法输入、文件损坏等非法情况导致的异常,是程序级别的一些错误。
Error则表示更严重的,系统级的一些错误,如程序运行时一些环境导致的错误。
文字上我们通常将异常表达为:错误、运行时异常与非运行时异常。错误与运行时异常通常我们不需要捕获,非运行时异常则需要我们进行显式的捕获或者抛出。
因此我们在编写程序的过程中,更多地会关注Exception异常。
2.1.2 try-catch-finally语句 捕获异常
语法如下:
try{
可能会发生异常的代码
}catch(ExceptionType e){
发生异常后执行的语句,通常是解决方案或者将异常输出
}finally{
无论以上代码是否执行,都会执行的语句,通常用于释放资源,如文件流的close
}
一般情况下,如果没有必须执行的语句,使用try-catch即可,其中catch可以连用,即catch后可以连着一个catch
以下是例子:
/**单个try-catch解决单个异常问题*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("./tools.exe");
//输出一下观察该文件是否存在
System.out.println("该文件是否存在"+f.exists());
//创建文件流,若该文件存在,创建文件输入流,否则输出该文件不存在
try {
//尝试执行的代码
FileInputStream fis = new FileInputStream(f);
}catch(FileNotFoundException e){
System.out.println("该文件不存在");
//输出异常信息
e.printStackTrace();
}
}
多个catch连用:
public static void main(String[] args) {
// TODO Auto-generated method stub
// 手动做两件会出现不同异常的事情:
int c [] = {1,2,3};
File f = new File("./tools.exe");
try {
FileInputStream fis = new FileInputStream(f);
System.out.println(c[4]);
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("数组下标越界!");
//以下使用catch连用捕获异常
}catch(FileNotFoundException e) {
System.out.println("文件不存在!请检查路径");
}
}
catch里的异常类型放在一块:
public static void main(String[] args) {
// TODO Auto-generated method stub
// 手动做两件会出现不同异常的事情:
int c[] = { 1, 2, 3 };
File f = new File("./tools.exe");
try {
FileInputStream fis = new FileInputStream(f);
System.out.println(c[4]);
} catch (ArrayIndexOutOfBoundsException | FileNotFoundException e) {
System.out.println("出現了異常!");
}
}
当异常类型特别多的时候,可以选用最大的Exception捕获
public static void main(String[] args) {
// TODO Auto-generated method stub
// 手动做两件会出现不同异常的事情:
int c[] = { 1, 2, 3 };
File f = new File("./tools.exe");
try {
FileInputStream fis = new FileInputStream(f);
System.out.println(c[4]);
} catch (Exception e) {
System.out.println("出現了異常!");
}
}
try-catch-finally连用,finally里的代码块必须执行
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("./tools.exe");
try {
FileInputStream fis = new FileInputStream(f);
} catch (Exception e) {
System.out.println("出現了異常!");
} finally {
System.out.println("无论上述代码是否异常,都会执行的代码");
}
}
2.1.3 抛出异常
关键字:throw 和 throws
throw 通常在方法内,throws通常在方法声明上。
throw
public static void main(String[] args) {
// TODO Auto-generated method stub
int i[] = {1,2,3};
Scanner sc = new Scanner(System.in);
System.out.println("请输入想要查询的数组下标");
int index = sc.nextInt();
//举个小例子,此处可能出现越界
if(index > 2) {
throw new ArrayIndexOutOfBoundsException();
}else {
System.out.println(i[index]);
}
}
实际开发中,一些程序可以运行的情况,但不符合业务逻辑,又不需要就地解决的问题,就可以通过throw抛出异常。
throws
当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理这个异常。
例如我们阅读源码时,会发现在一些类里面,已经给我们throws了一些异常
public void close() throws IOException {}
处理办法包括:try-catch-finally在当前代码块解决、继续throws抛出给上层程序解决。
注意,最好不要在main方法声明处throws异常,对JAVA虚拟机来说,main方法是程序的入口,也是最高曾的程序,
如果交给main throws ,又发生异常时,JVM会kill掉当前main方法,导致整个程序运行结束。
public class ThrowsDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
useMethodDemo();
}
public static void useMethodDemo() {
//使用该方法时,必须选择处理异常
try {
defineThrowsMethod();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void defineThrowsMethod() throws IOException{
File f= new File("./tools.exe");
FileInputStream fis = new FileInputStream(f);
//读一个低八位
int a = fis.read();
System.out.println(a);
}
}
2.1.4 自定义异常
我们还可以自定义异常,需要创建该异常的类,继承Exception并实现构造方法。举个例子:
public class ExceptionDefineByMyself extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public ExceptionDefineByMyself() {
super();
// TODO Auto-generated constructor stub
}
public ExceptionDefineByMyself(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public ExceptionDefineByMyself(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ExceptionDefineByMyself(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ExceptionDefineByMyself(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
testMethod();
} catch (ExceptionDefineByMyself e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testMethod() throws ExceptionDefineByMyself {
int i = new Scanner(System.in).nextInt();
if(i<0) {
throw new ExceptionDefineByMyself();
}
}
3.总结
本文涉及的知识点比较多,首先我们学习了JAVA中操作文件的API:File,初步了解了文件的常用方法,初步学习了文件流;在学习文件的过程中,我们发现IDE会强制我们进行异常处理,于是我们就学习了异常处理机制:捕获异常现场处理、抛异常交给上层处理、自定义异常。
我们下一篇见!