做网站设计,湖南网站制作公司推荐,苏州万户网络科技有限公司,用wordpress建站之后如何优化第3节 IO#xff08;上#xff09;
一、File类与文件基本操作
在程序中经常需要用到文件的操作#xff0c;Java有专门的类来进行文件的操作——File类。
1.1 File类概述
它是对文件和目录路径名的抽象表示。 即它本身不是一个文件#xff0c;只是一个抽象表示#xff…第3节 IO上
一、File类与文件基本操作
在程序中经常需要用到文件的操作Java有专门的类来进行文件的操作——File类。
1.1 File类概述
它是对文件和目录路径名的抽象表示。 即它本身不是一个文件只是一个抽象表示一个用于操作文件的对象实现后。
用户界面和操作系统使用依赖于系统的路径名字符串来命名文件和目录。此类提供了一个抽象的与系统无关的分层路径名视图。
1.2 绝对路径于相对路径 绝对路径 从盘符开始是一个完整的路径例如c://a.txt 相对路径 在Java代码中是相对于项目目录路径 这是一个不完整的便捷路径在Java开发中很常用。
看一个例子就明白了
package com.kaikeba.coreclasslibrary.io;import java.io.File;public class path {public static void main(String[] args) {File file1 new File(c://a.txt);File file2 new File(a.txt);System.out.println(file1的路径file1.getAbsolutePath());System.out.println(file2的路径file2.getAbsolutePath());}
}结果如下
file1的路径c:\a.txt
file2的路径E:\JAVAEE开发工程师\code\classcode\a.txt
其中项目的路径就是E:\JAVAEE开发工程师\code\classcode。
1.3 File类字段 这边的路径分隔符和默认名称分隔符是为了适应不同的os因为在不同的os上它们是不一样的为了避免经常修改这些可以利用File类给出的这些字段在不同的os上会给出相应的分隔符下面看一下Windows上的分隔符是什么
System.out.println(File.pathSeparator);
System.out.println(File.separator);结果如下
;
\
1.4 构造方法 parent和child构造的方法parent是目录child是具体文件名。
1.5 方法
1、三个测试 2、比较两个抽象路径名 3、在该路径下创建文件存在则不新建 4、删除文件 5、判断是否存在该文件 6、得到绝对路径可以是File类或String字符串 7、得到文件或目录名称 8、测试是否是绝对路径、目录、文件、隐藏文件 9、返回文件的长度大小 10、列出该目录下的所有文件或字符串路径 11、新建目录或递归新建目录 上述就是一些常用方法。
1.6 文件遍历与文件过滤器
1.6.1 文件遍历充分利用File类的方法
如何在一个路径下找出所有的PDF文件这就需要遍历路径下的所有文件和目录遇到目录还要在进目录继续遍历
代码如下
package com.kaikeba.coreclasslibrary.io;import java.io.File;public class listfiles {public static void main(String[] args) {File e new File(e:\\);File[] files e.listFiles();listFiles(files);}private static void listFiles(File[] files) {if(files ! null files.length 0) {for(File file:files) {if(file.isFile()) {//文件if(file.getName().endsWith(.pdf)) {//找到了一个大于10M的PDF文件if(file.length()10*1024*1024) {System.out.println(file.getAbsolutePath());}}}else {//文件夹继续递归遍历File[] files2 file.listFiles();listFiles(files2);}}}}
}结果就是遍历的所有在E盘下的PDF的路径...1.6.2 文件过滤器
上述遍历的框架已经有了但是在判断是否是我们要找的文件时if判断是我们自己写的还有一种方法虽然不常用但是也可以了解。
listFiles方法的参数里有一个FileFilter类型的filefilter变量 FileFilter是一个接口只有一个抽象方法 可以把判断条件写在accept里面如果返回true就保存该文件返回false就不保留该文件例子如下
package com.kaikeba.coreclasslibrary.io;import java.io.File;
import java.io.FileFilter;public class filefilter2 {public static void main(String[] args) {File e new File(e:\\);listFiles(e);}private static void listFiles(File file) {//1. 创建一个过滤器规则 并 描述规则//2. 通过文件获取子文件夹File[] files file.listFiles(new FileFilter() {Overridepublic boolean accept(File pathname) {if(pathname.getName().endsWith(.pdf) || pathname.isDirectory()) {return true;}return false;}});if(files ! null || files.length 0) {for (File f : files) {if (f.isDirectory()) {listFiles(f);} else {System.out.println(f.getAbsolutePath());}}}}
}返回结果如上述代码一致。二、流输入输出概述
计算机中的任何数据文本图片视频音乐等等都是以二进制形式存储的。在数据传输时也都是以二进制形式存储的。后续学习的任何流在传输时底层都是二进制。
可以将数据传输的操作看做一种数据的流动。按照流动的方向分为输入Input和输出Output。
Java中的IO操作主要指的是java.io包下的一些常用类的使用通过这些类对数据进行读取输入Input和写出Output。
IO流的分类 按照流的方向来分可以分为输入流和输出流 按照流动的数据类型来分可以分为字节流和字符流 。
字节流 输入流InputStream 输出流OutputStream
字符流 输入流Reader 输出流Writer
三、字节流
3.1 字节输出流OutputStream类
3.1.1 OutputStream类概述
此抽象类是表示输出字节流的所有类的超类输出流接收输出字节并将它们发送到某个接收器。它的实现子类最常用的就是FileOutputStream类。
方法
1、关闭输出流 2、刷新缓存强制写出 3、写出操作将字节数组或字节写出 3.1.2 FileOutputStream类
是OutputStream类最常用的一个实现类。
构造方法 指定要输出写入的文件对象或String路径文件不存在会自动创建append表示是否追加写入true为追加模式false为清空内容从头写入。
方法 基本就是使用OutPutStream类的方法。
看个例子
package com.kaikeba.coreclasslibrary.io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class outputstream {public static void main(String[] args) throws IOException {//FileOutputStreamFileOutputStream fos new FileOutputStream(a.txt);
// byte[] bytes {65,66,67,68,69};
// fos.write(65);byte[] bytes ABCDEF.getBytes();
// fos.write(bytes);fos.write(bytes, 1, 2);fos.close();System.out.println(已经写出);}
}结果为
BC3.2 字节输入流InputStream类
3.2.1 InputStream类概述
此抽象类是表示输入字节流的所有类的超类。最常见的子类是FileInputStream类。
方法
1、关闭输入流 2、读取下一个字节 3、读取一些字节 4、读取一些字节并指定开始位置和读取个数 注意 读取的方法返回的都是读取到的有效字节的个数 如果已经到文件末尾将会返回-1 。
5、其他一些读取方法 6、跳过并丢弃输入流的n字节数据 3.2.2 FileInputStream类
是InputStream类最常用的一个子类。
构造方法 给定要读取的文件。
方法 看一个例子
首先在a.txt文件中写有Hello InputStream的内容。下面来将其文件中的内容读取到程序中
package com.kaikeba.coreclasslibrary.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class inputstream {public static void main(String[] args) throws IOException {//FileInputStreamInputStream fis new FileInputStream(a.txt);while(true) {byte b (byte)fis.read();//b如果为-1表示已经读取到文件末尾读取完毕if(b -1) {break;}System.out.print((char)b);}}
}结果为
Hello InputStream但是这种方式每次只读取一个字节需要很多次读取read操作与文件的连接次数太多会拖慢程序的速度所以可以使用read的另一个方法
package com.kaikeba.coreclasslibrary.io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class inputstream {public static void main(String[] args) throws IOException {//FileInputStreamInputStream fis new FileInputStream(a.txt);//推荐下面这种方式读取因为读取的次数较少byte[] bytes new byte[10];int len fis.read(bytes);System.out.println(new String(bytes,0,len));len fis.read(bytes);System.out.println(new String(bytes,0,len));len fis.read(bytes);System.out.println(len);fis.close();}
}结果如下
Hello Inpu
tStream
-1用一个字节数组来接收读取到的固定长度的数据但是要注意读到最后如果不满10个字节了那么返回的将不是希望的结果因为是将新读取到的覆盖数组未满10个最后几个后面将不会被覆盖即多出几个没用的字节。
解决按照上述的写法将成功读取到的字节个数接收并用String的bytes数组指定长度的构造方法来输出。
优点这样大大减少了连接文件的次数加速了程序的运行。
3.2.3 字节流读取文字
如果将上述a.txt中的内容换成中文比如 锄禾日当午汗滴禾下土 再来看上述代码的输出
锄禾日
午
滴禾下这并不是乱码因为中文编码一般不是一个字节来表示一个字所以它10个字节可能读到的是3个半字那半个字是无法恢复的它比乱码更加可怕 这就是字节流的缺点所在后续学习字符流就是专门解决读取文字的问题。
四、字符流
字符流与字节流的区别就是字节流是一个字节一个字节的传输但是字符流不太一样虽然内部还是传输的字节但是因为一个字符比如一些非英文文字需要几个字节来表示一个字符所以它会一次读或写一个字符这样就可以避免3.2.3出现的问题。
4.1 字符输出流Writer类
4.1.1 Writer类概述
用于写入字符流的抽象类。最常用的子类为OutputStreamWriter下的FileWriter。其中OutputStreamWriter后续介绍。
方法 比较常用的有
1、append将字符或序列追加到此Writer注意它的返回类型为Writer即追加完后的文件自己。 其实它内部调用的还是write方法但是write方法没有返回这就使得append方法可以连续操作当然用write也可以达到一样的效果。
2、close关闭流关闭之前先刷新缓存 3、flush刷新缓存如果不刷新内容是写在缓存区的还没有真正写入文件 close方法中已经调用了flush这里我们不使用close只看使用flush和不使用flush的区别 目前b.txt是空的下面调用
public class flush {public static void main(String[] args) throws IOException {FileWriter fw new FileWriter(b.txt, true);fw.append(锄禾日当午).append().append(汗滴禾下土);}
}结果还是空的因为没有刷新缓冲区 如果加上flush
FileWriter fw new FileWriter(b.txt, true);
fw.append(锄禾日当午).append().append(汗滴禾下土);
fw.flush();结果为 4、write写一个字符数组字符数组的一部分一个字符一个字符串字符串的一部分 4.1.2 FileWriter类 使用默认缓冲区大小将文本写入字符文件。构造方法 参数
1、File file / String fileName要将内容写入的文件
2、Charset charset指定编码集常见的有gbk、“uft8”
3、boolean append是否是追加模式写入
方法没有新的都是用的或重写的父类方法。
看个例子
package com.kaikeba.coreclasslibrary.io;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class writer {public static void main(String[] args) throws IOException {//Writer//FileWriterFileWriter fw new FileWriter(b.txt);fw.write(a);fw.write(锄禾日当午);//注意append的用法因为它返回文件本身fw.append().append(汗滴禾下土);fw.close();}
}b.txt中的内容为
a锄禾日当午汗滴禾下土4.2 字符输入流Reader类
4.2.1 Reader类概述
用于读取字符流的抽象类。常用的子类为InputStreamReader下的FileReader类。
方法 常用的有
1、close关闭流 2、read读入一个字符返回的就是它的int型编码 3、将字符读入数组一部分或指定缓冲区 4.2.2 FileReader类
使用默认缓冲区大小从字符文件中读取文本使用指定的编码集或默认编码集。
构造方法 参数
1、File file / String fileName从哪个文件读取
2、Charset charset指定编码集。
方法也没有新的。
看个例子
package com.kaikeba.coreclasslibrary.io;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class reader {public static void main(String[] args) throws IOException {//ReaderFileReader fr new FileReader(b.txt);/*while(true) {int c fr.read();if(c -1) {break;}System.out.print((char)c);}*/System.out.println(afr.read());System.out.println(锄fr.read());char[] chars new char[100];int len fr.read(chars);System.out.println(new String(chars, 0, len));fr.close();}
}结果如下
a97
锄38148
禾日当午汗滴禾下土五、字节流转换字符流
5.1 InputStreamReader类
InputStreamReader类是从字节流到字符流的桥接器这也是比较常用的比如从外界接收到的流一般都是字节流如果要正确读取文字的话需要转为字符流。每次调用read方法都可能导致从底层字节输入流中读取一个或者多个字节。
它是Reader类的一个子类是FileReader的父类。
构造方法 主要的参数是要传入一个字节输入流InputStream。
方法 主要是read方法可以读取一个字符或者将字符输入数组的一部分。
看一个例子
public class zhuanhuanliu {public static void main(String[] args) throws IOException {//字节流 ‘装饰’为 字符流 使用了装饰者设计模式//自己新建一个字节输入流用于模仿外界接收到的FileInputStream fis new FileInputStream(b.txt);//将字节输入流转换为字符输入流//参数1要转换的字节流//参数2指定编码名称InputStreamReader isr new InputStreamReader(fis,utf8);while(true) {int c isr.read();if(c -1) {break;}System.out.print((char)c);}}
}结果就是将b.txt中的内容全部输出5.2 OutputStreamWriter类
OutputStreamWriter是从字符流到字节流的桥接器使用指定的charset将写入其中的字符编码为字节。调用write方法都会导致在给定字符上调用编码转换器生成的字节在写入底层输出流之前在缓冲区中累积。
它是Writer类的子类是FileWriter类的父类。
构造方法 主要参数是要转换的输出字节流。
方法 写一个字符或字符串或字符数组的一部分。
看一个例子
public class zhuanhuanliu2 {public static void main(String[] args) throws IOException {//转换流//字符流 ‘装饰’为 字节流 使用了装饰者设计模式FileOutputStream fos new FileOutputStream(b.txt);OutputStreamWriter osw new OutputStreamWriter(fos);osw.write(床前明月光);osw.close();}
}即将“床前明月光”写入b.txt。六、打印流与缓存流
6.1 PrintStream类
PrintStream类向另一个输出流添加功能即能够方便地打印各种数据值的表示。
构造方法 传入的参数主要是要写入的文件可以是File型String型或者字节输出流。
方法
1、追加 2、关闭、刷新 3、打印 4、打印并换行 5、写入 看个例子
public class print_bufferedreader {public static void main(String[] args) throws IOException {//(字符输出)打印流注意它会自动刷新PrintStream ps new PrintStream(b.txt);ps.println(锄禾日当午1);ps.println(锄禾日当午2);ps.println(锄禾日当午3);}
}b.txt中的内容就是
锄禾日当午1
锄禾日当午2
锄禾日当午36.2 PrintWriter类
它和PrintStream类基本上差不多主要的区别是写入的时候不会自动刷新。
public class print_bufferedreader {public static void main(String[] args) throws IOException {PrintWriter pw new PrintWriter(b.txt);pw.println(锄禾日当午1);pw.println(锄禾日当午2);pw.println(锄禾日当午3);pw.flush();}
}b.txt中的内容就是
锄禾日当午1
锄禾日当午2
锄禾日当午3也可以用输出流作为参数
public class print_bufferedreader {public static void main(String[] args) throws IOException {FileOutputStream fos new FileOutputStream(b.txt);PrintWriter pw new PrintWriter(fos);pw.println(勇敢牛牛);pw.close();}
}b.txt中的内容就是
勇敢牛牛6.3 BufferedReader类
从字符输入流中读取文本缓冲字符以便有效地读取字符数组和行。可以指定缓冲区大小或者可以使用默认大小。
构造方法 方法 它比较独特的一个方法是readLine方法读取一行文字看一个例子
public class print_bufferedreader {public static void main(String[] args) throws IOException {//缓存读取流将字符输入流 转换为带有缓存 可以一次读取一行的缓存字符读取流FileReader fw new FileReader(b.txt);BufferedReader br new BufferedReader(fw);String text br.readLine();System.out.println(text);}
}结果解释读取b.txt中的一行文字。七、收集异常日志
在程序运行过程中不可能一直看着屏幕上的输出所以当出现异常的时候利用IO我们可以将这些异常写到指定的文件中后续有时间打开这个记录异常的文件查看即可。
看一个例子
public class printstacktrace {public static void main(String[] args) throws FileNotFoundException {try{//将可能出现异常的内容用try捕捉String s null;s.toString();}catch (Exception e) {//新建打印流指定输出的文件PrintWriter pw new PrintWriter(b.txt);//把时间也记录下来SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm);pw.println(sdf.format(new Date()));//将异常输出到打印流中e.printStackTrace(pw);//关闭打印流pw.close();}}
}b.txt中的内容就是异常
2021-09-13 19:57
java.lang.NullPointerExceptionat com.kaikeba.coreclasslibrary.io.printstacktrace.main(printstacktrace.java:12)