目录
2.4、打印流PrintStream & PrintWriter
一、File类
在学习IO流之前,我们先简单了解一下IO包中的File类,以及一些常用操作。
1.1、File对象
利用File类,创建一个File对象,该对象可以指向我们系统下的一个路径。
- 该路径已经存在,我们可以利用该对象,进行一些数据获取。
- 该路径不存在,我们可以利用mkdir、mkdirs、createNewFile方法创建。
现在针对于路径不存在时,怎么使用上述三种方法创建该路径来,总结:
mkdir && createNewFile :
两者都有返回值(类型是boolean),true表示创建成功,反之。
File my = new File("D://123.txt"); //创建File对象my,my对象指向一个路径 my.createNewFile() // 创建对应类型文件,即创建 名为"123" 的 txt文本文件 my.mkdir() //创建 “123.txt”为名 的 文件夹 /** * 上面两个创建方法的缺陷 : * "D://123.txt" 之间,不能存在中间文件。 * 如"D://hello//123.txt",这样是错的。 * 要想这样创建,可以看一下个方法。 */
mkdirs :
有返回值(类型是boolean),true表示创建成功,反之。
File my = new File("D://hello//123.txt") //创建File对象 my.dirks() //根据上述路径,依次创建文件夹。 D盘下创建hello文件夹,hello文件夹下创建“123.txt”文件夹
可以看到,前面利用File创建对象时,里面只传入了一个参数,下面学习一下传入两个参数的情况:
File my = new File("上级目录","123.txt") //传入了 父路径 、 之路径 my.mkdirs() //依次创建文件夹。 “上级目录”文件夹 下面包含 “123.txt”文件夹 my.crcreateNewFile() //在“上级目录”文件夹 下,创建 名为123的 文本文件。(前提,上级目录,必须已存在,才能创建123.txt)
1.2、File类 の 常见方法
通过上面File类对象的创建,如果路径存在,我们可以利用该对象,进行数据的改动。下面简单介绍一些File类常见的方法。还很多常用的方法,大家可以去API文档观看。
delete() && exists() :
File f = new File("d:123.txt") //或者("haha","123456.txt") f.delete(); //删除该文件 , boolean类型返回值,true:删除成功,反之 f.exists(); //判断文件是否存在, boolean类型返回值,true:存在,反之
listFiles(): 无筛选
File m = new File("d://") File[] files = m.listFiles(); // 无筛选的,返回一个File类型数组,数组内容:d盘下所有文件 && 文件夹
listFiles(FileFilter filter): 有筛选
/** * 有筛选的:listFiles(FileFilter filter) * filte,表示自己的筛选规则,下面给出一个列子,简单介绍 * * AviFile(): * 是我们自己,实现了FileFilter接口,编写出来的一个类, * 该方法里面的代码块,相当于过滤的“规则”定义吧。 */ File m = new File("d://") FileFilter filter = new AviFile(); //创建自己的规则AviFile对象 File[] files = m.listFiles( filter ); //根据规则,筛选d盘下的文件 && 文件夹,返回给File类型数组 static class AviFile implements FileFilter{ //接口实现,编写过滤的规则 @Override public boolean accept(File pathname) { // m下面的文件、文件夹,逐一进入accept方法 if (pathname.getName().endsWith(".avi")){ // 规则定义,getName()获取文件名, endsWith(".avi")表示后缀名是否为 “.avi”,是返回true,反之。 return true; //满足条件,则写入数组 } return false; } }
绝对路径:从盘符开始 ,是一个完整的路径 例如 "d://haha//123.txt"
相对路径:在Java代码中 ,是相对于项目的目录文件,这是一个不完整的便捷路径,在Java开发中很常用 例如”123.txt“
二、IO流
在简单了解File类之后,我们可以发现,前面我们对File类对象,只是简单的创建、删除等操作,并没有单单对一个文件里面的内容,进行操作过。(如:读取一个文本文件里面的内容,我们前面就没有操作过,下面来开始学习)。
首先,我们要分清楚,输入流和输出流。
- 文件内容读到 java程序中,对于java就是输入流 ,对于文件就是输出流。
简而言之:有输出流,就一定有输入流;选择好参照物,就可以轻松判断是什么流。
IO流的分类:
按照流的方向来分 : 输入流-------输出流.
按照流动的数据类型来分 : 字节流-------字符流
2.1、字节流
上面IO流分类中,介绍了 以字节为单位的数据流动,称之为字节流。
字节流 :
--- 输入字节流 的超类: InputStream
--- 输出字节流 的超类: OutputStream
2.1.1、FileInputStream字节输入流
InputStream流,是输入字节流的所有类的超类。
下面,我们就介绍一下该超类下面的 FileInputStream流。
使用格式:
//两者都行,创建fis对象 InputStream fis = new FileInputStream("d://123.txt"); FileInputStream fis = new FileInputStream("d://123.txt");
常见方法:
read() //无参数 ,读取一个字节数据
fis.read() //读取一个字节的数据,返回数据的 asill码值, // int b = fis.read() --- (char)b ,就可以打印出原数据 // 读取的数据,应是 字母 & 数字。否则经转化,打印出来的是乱码。而且若是汉字之类的数据,我们用的更多的是字符流,后续会介绍
read(byte[] b) //有参数,数据写入bytes,数据最多读取 b.length长度的字节
byte[] bytes = new byte[10]; //创建一个byte类型 数组 fis.read(bytes) //一次读取10个字节长度的数据,剩余不足10个字节的,有多少读多少, 但是bytes的长度还是10 。数据存入byte类型的数组 bytes int len = fis.read(bytes) //有返回值,只不过返回的是,本次读取了多长字节的数据。 String str = new String(bytes,0,len); //转化成字符,0-len,就是转化有效数据。不然为空的地方,转换时,会出错。 这样转化,可以读出汉字 System.out.println(str);
2.1.2、FileOutputStream字节输出流
OutputStream流,是输出字节流的所有类的超类。
下面,我们就介绍一下该超类下面的 FileOutputStream流。
使用格式:
FileOutputStream fos = new FileOutputStream("d://123.txt"); FileOutputStream fos = new FileOutputStream("d://123.txt",true); //文件不存在,则创建。 // true表示,追加写,不覆盖源文件内容。
常见方法:
write():
fos.write(53) //写入 一个 asill码值为 53 的字符 byte[] b = {53,54,55,56,57,59}; fos.write(b); //将上述数组,全部元素,写入文件,也是asill值对应字符 byte[] b = {53,54,55,56,57,59}; fos.write(b,2,3); //下标为2开始,写入3个元素 到文件
2.2、字符流
上面IO流分类中,介绍了 以字符为单位的数据流动,称之为字符流。
字符流 : 只能操作 文字
--- 输入字符流 的超类: Reader
--- 输出字符流 的超类: Writer
2.2.1、FileReader字符输入流
Reader ,是字符输入流的所有类的超类。
下面介绍其子类,FileReader
使用格式:
Reader f = new FileReader("d://123.txt"); FileReader f = new FileReader("d://123.txt");
常用方法:
read() //无参数,也是只读取一个字符,需要(char)转化,才能得到原数据
int i = f.read(); System.out.println((char)i); //如果没有数据,read()返回 -1 。 即 i = -1
read() //有参数,数据写入bytes,数据最多读取 b.length长度的字节
char[] chars = new char[10]; int len = f.read(chars); String text = new String(chars,0,len); System.out.println(text);
可以看到,FileReader 与 FileInputStream 的read()用法是基本相似的。
2.2.2、FileWrite字符输出流
Write,是所有字符输出流的超类,
下面介绍其子类,FileWrite类
使用格式:
FileWrite f= new FileWrite("d://123.txt"); FileWrite f = new FileWrite("d://123.txt",true); //文件不存在,则创建。 // true表示,追加写,不覆盖源文件内容。
常用方法:
f.write("你好") //写入“你好” char[] i = {53,54}; //写入对应 asill码值 的 字符 f.write(i);
2.3、字节转换字符流
在IO流中,除了字节流、字符流,还有一种转化流。就是将字节流 “转换” 为字符流。转换加双引号,表示不是真的 转 ,是 ”装饰“ :使用了装饰者设计模式。(看上去就像转换一样。)
2.3.1、InputStreamReader
FileInputStream fis = new FileInputStream("字符流.txt"); //字节流 fis对象 /** * 在获取文件路径之后,我们前面所学的知识,就可利用read方法,开始读取一个字节的数据了。 * * 现在,学习转化流,我们下一步需要将字节流,转化为 字符流,就需要用到InputStreamReader流 */ InputStreamReader isr = new InputStreamReader(fis); //转化 字符流 //然后就可以使用 read方法,其跟前面方法基本一致,不做过多介绍了
2.3.2、OutputStreamWriter
FileOutputStream fos = new FileOutputStream("字符流.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos); osw.write("你们好"); osw.flush(); //刷新 osw.close(); //关闭 两者都可以在运行代码后,直观看到文本文件内容发生变化
2.4、打印流PrintStream & PrintWriter
下面来介绍一下 一个特殊的流——打印流,ta有两者实现方法:
PrintStream && PrintWriter
那什么是打印流呢?其实常见语句 " System.out.println() " ,就是一种打印流,点击源码,可以发现 :
- 对象out的类型就是PrintStream
- 可以发现PrintStream 继承了FilterOutputStream
- FilterOutputStream 继承了 OutputStream
① PrintStream打印流
PrintStream ps = new PrintStream("打印流.txt"); //这里就相当于,要把内容,打印到相应的文件。文件不存在,则自动创建。 ps.println("你好"); //需要打印的内容 FileOutputStream f = new FileOutputStream("777.txt"); //字节流 转化为字符流 PrintStream f1 = new PrintStream(f); f1.println("ddd");
②PrintWriter打印流
除了,上面PrintStream打印流以外,还有一种常见的打印流——PrintWriter。
其,用法与上面PrintStream打印流,基本相似。
PrintWriter pw = new PrintWriter("打印流.txt"); pw.println("你好"); pw.flush();//刷新 FileOutputStream f = new FileOutputStream("7177.txt"); //字节 转化字符流 PrintWriter f1 = new PrintWriter(f); f1.println("ddd"); f1.flush();
不同点:
可以看到,PrintWriter打印流,需要在写一句 flush()刷新方法;不然文本文件,没有内容显示。使用close()方法也可以。
相同点:
两者,都可以实现 将字节流转化为字符流 ,其使用过程,同前面讲解的 字节转化字符流的InputStreamReader一样。 推荐使用这种方式!!
可以看出来,打印流针对与 java而言,是输出流!
2.5、缓存读取流——BufferedReader
缓存读取流:将字符输入流 转换为带有缓存 可以一次读取一行的缓存字符读取流。
就相当于,一次读取文件里面一行的数据!!
- 前面所学到的 字节流 & 字符流,除了利用read()读取一个 字节 &字符;
- 还能利用read(char[] chars),一次最多读取chars.length长度的字节数组 & 字符数组,
- 显然,都没有一次读取文件里面,一行的功能。
使用格式如下:
BufferedReader 传入的类型 必须是Reader及其子类
FileReader f = new FileReader("打印流.txt"); BufferedReader a = new BufferedReader(f); String text; do { text = a.readLine(); System.out.println(text); }while (text != null);
可以看出来,缓存读取流针对与 java而言,是输入流!
三、特殊的流——Properties
Properties :即是集合map 也是IO 。
以前的快递E栈 ,数据只能存在 内存里面,结束该程序,我们的数据就没了 。现在使用IO口,把数据存入文件里面,就可以永久使用。而Properties流,正好适配快递E栈的信息存储。
使用格式:
put() //通过 键值对方式,存储信息
store() // 第一个参数 是要写入的文件路径 ; 第二个参数是 注释(写入文件时,不会显示文字,显示的是其unicode码。)。
public class Properties_Test { public static void main(String[] args) throws IOException { Properties ppt = new Properties(); ppt.put("name","艾欧尼亚"); // 键 = 值 ppt.put("user","刀妹"); //上面 相当于 创建了 一个map集合 。 下一步,把他存入文件夹 FileWriter fw = new FileWriter("123.Proerties"); ppt.store(fw,"英雄联盟"); fw.close(); } }
上面是写入数据,下面我们来介绍如何读取数据:
Properties ppt = new Properties(); Reader f = new FileReader("123.Proerties"); ppt.load(f); //f 可以是字节流 \ 字符流 。这里利用Reader,所以f是字符流 System.out.println(ppt.getProperty("name")); // getProperty(键) ,通过 键 获取 值 System.out.println(ppt.getProperty("user"));
感谢观看!!!