第5次文章:关于IO流的基本操作
- 2019 年 10 月 8 日
- 筆記
春节假期就要结束啦,很多小伙伴儿明天就开始上班了,祝各位小伙伴儿新的一年工作顺心,万事顺利哟!
实例一:输出所选文件夹中的所有文件名,包含子孙级文件名
public class Demo05 { public static void main(String[] args) { String path = "C:\documents\java\公众号运营"; File src = new File(path);//创建File对象 printName(src); } //使用迭代进行输出 public static void printName(File src) { if (null==src||!src.exists()) {//如果为空或者不存在,则直接退出 return; } System.out.println(src.getAbsolutePath());//输出绝对路径 if(src.isDirectory()) {//判断是否为目录 File[] files = src.listFiles();//以file对象的方式,列举目录下的所有文件及文件夹 for(File temp:files) { printName(temp);//迭代每一个file对象 } } } }
下面对这段代码中的一些细节进行分析:
1、分隔符
在Java中,路径分隔符(;)使用常量:File.pathSeparator,名称分隔符(“/”或“”)使用常量:File.separator。尤其需要注意名称分隔符,在Windows中,名称分隔符使用斜杠“”,在Linux以及其他系统中,名称分隔符使用反斜杠“/”。由于在程序编写和使用时,经常会出现在不同的系统中,所以使用分隔符的时候,建议使用常量:File.separator,Java会根据具体环境,进行匹配。
在上面的代码中,第一行路径中出现了“\”,这是因为Java中的“”属于转义字符,比如“t”就代表制表符“tab”键,所以在使用单斜杠的时候,需要在其前面多加一个单斜杠。
2、File对象的创建
File对象的创建可以利用绝对路径和相对路径进行创建。上面的代码中使用的是绝对路径,当我们使用相对路径的时候,Java会默认当前工作空间user.dir为根路径。在创建File对象的时候,仅仅是将路径和File类型的新变量进行了一定的联系,并不会关注其到底有没有真实的存在路径中的文件。
3、关于File的一些基本方法
exist:检查此File对象是否真实的存在。
getAbsolutePath:获取File对象的绝对路径。
getParent:返回File对象的上一级目录。
getName:返回File对象的名称。
isFile:判断其File对象是否是文件。
isDirectory:判断File对象是否是目录。
list:将File对象的目录,以字符串数组的形式返回
listFiles:将File对象的目录,以File数组的形式进行返回
实例二:文件的读取
文件的读取有四个基本步骤:
1、建立联系 File对象
2、选择流:输入流InputStream + FileInputStream
3、读取数据,操作流对象:byte[] car = new byte[10]+read方法
4、释放资源:关闭
public class Demo01 { public static void main(String[] args) { //1、建立联系File对象 File src = new File("C:\documents\test\abc.txt\ABC.txt"); //2、选择流 InputStream is = null;//提升作用域 try { is = new FileInputStream(src); //3、操作 不断读取 缓冲数组 byte[] car = new byte[10]; int len=0;//接收 实际读取的大小 //循环读取 while(-1!=(len=is.read(car))) {//将实际读取到的数量返回给len,当读取结束时,返回len=-1 //输出 字节数组转换为字符串 String info = new String(car,0,len); System.out.println(info); } } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件不存在"); } catch (IOException e) { e.printStackTrace(); System.out.println("文件读取失败"); }finally { //4、释放资源 if(null!=is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("关闭文件输入流失败"); } } } } }
上面的这段代码中,有几个小技巧比较有用,所以来提一下:
1、在第2步选择流的时候,我们读取外部文件,选择输入流InputStream。输入流的使用需要和计算机的操作文件进行交互,所以需要捕获异常,而捕获异常的时候,会将输入流的申明放入代码段try{}中,成为了此代码段的一个局部变量,这样将不利于我们后续在代码段finally{}中释放资源。所以我们将输入流InputStream的申明放在try{}的外部,提升作用域,然后在代码段try{}中进行读取操作。
2、在使用输入流的时候,读取是使用字节数组“byte[]”进行读取,所以当我们需要进行临时的查看时,不能直接对读出来的字节进行查看,而是使用了“String info = new String(car,0,len);”将读取出来的字节数组转化成了字符串,然后再进行查看读取的内容。
3、在捕获异常的时候,为了后续的检查方便,一定要在每个catch中,添加报错的原因,否则,代码运行一旦报错,很难快速定位到报错的原因上,浪费大量时间。
实例三:文件的写出
主要步骤与文件的读入相差不多,也分为4步:
1、建立联系 File对象
2、选择流:输出流 OutputStream + FileOutputStream
3、读取数据,操作流对象:write()+flush
4、释放资源:关闭
public class Demo02 { public static void main(String[] args) { //1、建立联系 File对象 String path = "C:\documents\test\abc.txt\ABC.txt"; File dest = new File(path); //2、选择流: OutputStream os = null;//提升作用域 try { //以追加的形式写入文件,选择true,否则是以覆盖的形式写入文件,默认为false //FileOutputStream(File file, boolean append) os = new FileOutputStream(dest,true); //3、写出数据 String str = "peng is very good rn"; //写出时注意将字符串转换为字节流 byte[] car = str.getBytes(); //将字节流写出到目标文件 os.write(car, 0, car.length); os.flush();//强制刷新出去 } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件不存在"); } catch (IOException e) { e.printStackTrace(); System.out.println("写出时失败"); }finally { if(null!=os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("关闭输出流文件失败"); } } } } }
对文件的写出,与文件读入操作基本一致,这里提一个代码中的写出函数:FileOutputStream(File file, boolean append),当我们在使用输出流函数FileOutputStream时,如果没有将append参数设置为true,则文件写出的时候,将会以覆盖的方式输出到文件。比如,在这段代码中,我们向文件“ABC.txt”中写入字符串数据“peng is very good”,我们将append设置的是true(追加的形式写出),字符串数据不会覆盖“ABC.txt”文件中的原始数据,而是直接在目标文件的后面直接加入字符串“peng is very good”。如果我们将append参数设置为false,或者使用默认值,那么写出的方式将会是“覆盖”,直接将原文件中的所有数据清空,只写入这一个字符串数据“peng is very good”。