JavaSE——IO(上)(File、字节流、字符流、转换流、打印流、缓存流)

第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("已经写出");}
}结果为:
BC

3.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("a:"+fr.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();}
}结果如下:
a:97
锄: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
锄禾日当午3

6.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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习新技能时,大脑在如何发生改变?

来源:中国生物技术网众所周知,无论是一项运动、一种乐器还是一门手艺,掌握一项新技能都是需要花费时间并进行训练的。虽然我们都知道健康的大脑能够应付的来,但是为了开发出新行为大脑如何发生改变科学家们对此仍知之甚少。近日&a…

1-4-14:计算邮资

描述 根据邮件的重量和用户是否选择加急计算邮费。计算规则:重量在1000克以内(包括1000克), 基本费8元。超过1000克的部分,每500克加收超重费4元,不足500克部分按500克计算;如果用户选择加急,多收5元。 输入输入一行&a…

JavaSE——IO(下)(Properties类、序列化与反序列化)

第3节 IO(下) 一、.properties文件与Properties类 1.1 .properties文件介绍 .properties文件一种属性文件,以键值对 的格式存储内容,在Java中可以使用Properties类来读取这个文件,一般来说它作为一些参数的存储&…

MATLAB获得子图位置

a1subplot(9,11,1) get(a1,position) %[0.1300 0.8577 0.0547 0.0673] %前面两个数值分别代表子图离左边框和下边框的距离,后面两个数值是子图的长和宽

VS调试dll详细过程记录

VS调试dll详细过程记录 qianghaohao(孤狼) 前言:在我们写的程序中有时候调用dll,并且需要跟踪dll中的函数,此时直接调试调用dll的工程是无法跳进dll的函数的,此时我们可以启动dll工程 来跟踪程序的走向。注意:要有…

谁在真正领跑 5G:技术创新和标准

来源:云头条5G是包括美国总统特朗普在内的所有人都在谈论的新技术。所以,每家公司自然都想谈论5G以及如何领跑这个领域。然而现实情况是,移动5G是一项涵盖甚广的无线标准,它改变了我们对蜂窝通信的认识,并前所未有地拓…

JavaSE——XML与JSON(语法格式、解析内容)

第6节 XML与JSON 一、XML 1.1 XML简介 XML全称为可扩展标记语言(extensible Markup Language) 。 特性: xml具有平台无关性,是一门独立的标记语言; xml具有自我描述性。 用途: 网络数据传输 数据存…

matlab画图设置

设置坐标轴显示范围: xlim([0,150]) 设置坐标轴显示的刻度: set(gca, XTicklabel,[0,50,100,150] ); 不显示坐标轴刻度: set(gca, YTicklabel,[] ); 设置坐标轴标题及旋转角度: ylabel(yl,Rotation,0) 设置字体大小 se…

root 链接ftp

could not change active booleans:Inalid boolean 2014-11-02 16:05:34分类: Linux could not change active booleans:Inalid boolean [rootumboyserver vsftpd]# setsebool allow_ftpd_full_access 1[rootumboyserver vsftpd]# setsebool allow_ftpd_use_cifs 1…

三大阶段,四大领域,详解你不知道的AIoT!

AIoT即AIIoT,指的是人工智能技术与物联网在实际应用中的落地融合。目前,越来越多的行业及应用将AI与IoT结合到了一起,AIoT已经成为各大传统行业智能化升级的最佳通道,也是未来物联网发展的重要方向。来源:物联网智库AI…

Spring的@Resource注解报java.lang.NoSuchMethodError

见:https://www.cnblogs.com/xiaoguoniu/p/13504601.html 少了javax的包

word修改公式中的部分字体

有时候只想修改word公式中的部分字体大小,方法是先将公式变成普通文本格式再进行修改。

青春谁不糊涂3

1、生命的意义是不稳健,当人们多么辉煌,但是,当它逐渐凋落,有明显她的人,她静静地在一旁独自,讲话。不语。屏息中交换生命的本真。任凭四周的嘈杂与纠纷。2、靠幽默与搞笑出道的人,不到功成名就…

人类为什么会同情机器人,是否需要禁止虐待机器人

6月14日,一段形似波士顿动力机器人Atlas反击人类的视频在网络热传,制作这款视频的团队Corridor Digital,是一家位于洛杉矶的美国制作工作室。自2010年以来,一直以制作与流行文化相关的病毒在线短片视频而闻名。Corridor Digital由…

dubbo学习总结——思维导图

Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的、轻量级的开源Java RPC框架,可以和Spring框架无缝集成,2018年阿里巴巴把这个框架捐献给了apache基金会 什么是RPC? RPC全称为remote procedure call,即远程…

python为字体添加上下标

添加上标:^ 添加下标:_ 举例: import numpy as np import matplotlib.pyplot as pltt np.linspace(0, 10, 1000) y np.sin(t) plt.plot(t, y) plt.xlabel(a/${m_2}$,fontdict{weight: normal, size: 15}) plt.show() 效果: …

Eclipse在更换工作空间之后很多设置要重新配置

Eclipse在更换工作空间之后很多设置要重新配置,比如服务器,比如反编译工具等转载于:https://www.cnblogs.com/2027437606qq/p/5029306.html

微信演进的六点思考:微信生态如何演变?如何在其中掘金?

*头图来源:东方IC来源:虎嗅APP虎嗅注:在微信上下游诞生了无数的生态企业,他们关注着微信的一举一动,以便在其中掘金。6月15日,微盟集团CEO孙涛勇在华映资本WE来大会上,分享了对微信生态商业进化…

最小步长移动word表格标尺

有时想移动word的表格的标尺,发现只能一下移动一格,这时只需要移动标尺的时候同时按住Alt键,就能以最小分辨率移动表格的标尺