15.1 File类
15.1.1 Flile
概念:表示操作系统磁盘上的文件或者是文件夹
路径:
- 相对路径 (相对于当前工程的跟路径)
- 绝对路径 (在磁盘上的完整路径)
常见方法
方法名 | 描述 |
createNewFile() | 创建一个新文件。 |
mkdir() | 创建一个新目录。如果父目录不存在,则无法创建 |
mkdirs() | 创建一个新目录。如果父目录不存在,则一起创建 |
delete() | 删除文件或空目录。 |
exists() | 判断File对象所对象所代表的对象是否存在。 |
length() | 获取文件(夹)的大小(字节) |
getAbsolutePath() | 获取文件的绝对路径。 |
getAbsoluteFile() | 获取文件(夹)的绝对路径:(返回File) |
getName() | 获取当前file对象的文件名或者是文件夹名 |
getParent() | 获取当前file对象的父目录(返回String) |
isDirectory() | 是否是目录。 |
isFile() | 是否是文件。 |
getPath() | 获取文件(夹)的相对路径:(返回String) |
listFiles() | 列出目录中的所有内容。 |
案例演示:
public class TestFile { public static void main(String[] args) throws Exception { //separator(); //fileOpe(); directoryOpe(); } //(1)分隔符 public static void separator() { System.out.println("路径分隔符"+File.pathSeparator); System.out.println("名称分隔符"+File.separator); } //(2)文件操作 public static void fileOpe() throws Exception { //1创建文件 createNewFile() File file=new File("d:\\file.txt"); //System.out.println(file.toString()); if(!file.exists()) { boolean b=file.createNewFile(); System.out.println("创建结果:"+b); } //2删除文件 //2.1直接删除 //System.out.println("删除结果:"+file.delete()); //2.2使用jvm退出时删除 // file.deleteOnExit(); // Thread.sleep(5000); //3获取文件信息 System.out.println("获取文件的绝对路径:"+file.getAbsolutePath()); System.out.println("获取路径:"+file.getPath()); System.out.println("获取文件名称:"+file.getName()); System.out.println("获取父目录:"+file.getParent()); System.out.println("获取文件长度:"+file.length()); System.out.println("文件创建时间:"+new Date(file.lastModified()).toLocaleString()); //4判断 System.out.println("是否可写:"+file.canWrite()); System.out.println("是否时文件:"+file.isFile()); System.out.println("是否隐藏:"+file.isHidden()); } //(3)文件夹操作 public static void directoryOpe() throws Exception{ //1 创建文件夹 File dir=new File("d:\\aaa\\bbb\\ccc"); System.out.println(dir.toString()); if(!dir.exists()) { //dir.mkdir();//只能创建单级目录 System.out.println("创建结果:"+dir.mkdirs());//创建多级目录 } //2 删除文件夹 //2.1直接删除(注意删除空目录) //System.out.println("删除结果:"+dir.delete()); //2.2使用jvm删除 // dir.deleteOnExit(); // Thread.sleep(5000); //3获取文件夹信息 System.out.println("获取绝对路径:"+dir.getAbsolutePath()); System.out.println("获取路径:"+dir.getPath()); System.out.println("获取文件夹名称:"+dir.getName()); System.out.println("获取父目录:"+dir.getParent()); System.out.println("获取创建时间:"+new Date(dir.lastModified()).toLocaleString()); //4判断 System.out.println("是否时文件夹:"+dir.isDirectory()); System.out.println("是否时隐藏:"+dir.isHidden()); //5遍历文件夹 File dir2=new File("d:\\图片"); String[] files=dir2.list(); System.out.println("--------------------------------"); for (String string : files) { System.out.println(string); } } }
//创建File对象 File file = new File("d:\\a.txt"); if(!file.exists()) { //创建文件 file.createNewFile(); } System.out.println("判断文件或者是文件夹是否存在"+file.exists()); System.out.println("判断是否是文件:"+file.isFile()); System.out.println("判断是否是文件夹:"+file.isDirectory()); System.out.println("获取文件或者文件夹的名字:"+file.getName()); System.out.println("获取文件大小(字节):"+file.length()); System.out.println("获取文件的相对路径:"+file.getPath()); System.out.println("获取文件的绝对路径(String):"+file.getAbsolutePath()); System.out.println("获取文件的绝对路径(File):"+file.getAbsoluteFile()); System.out.println("获取文件的父目录(String):"+file.getParent()); System.out.println("获取文件的父目录(File):"+file.getParentFile()); System.out.println("获取文件所在位置磁盘的总空间:"+file.getTotalSpace()); System.out.println("获取文件所在位置磁盘的可用空间:"+file.getFreeSpace()); System.out.println("获取文件的最后修改时间(毫秒)"+file.lastModified()); System.out.println("判断文件是否可读"+file.canRead()); System.out.println("判断文件是否可写"+file.canWrite()); System.out.println("判断文件是否可执行"+file.canExecute()); System.out.println("判断文件是否是隐藏文件"+file.isHidden());
15.1.2 FileFilter接口
FileFilter:文件过滤器接口
- boolean accept(File pathname)。
- 当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。
案例演示:过滤所有的.jpg图片。
public class TestFileFilter{ public static void main(String[] args){ File dir=new File("d:\\图片"); File[] files2=dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if(pathname.getName().endsWith(".jpg")) { return true; } return false; } }); for (File file : files2) { System.out.println(file.getName()); } } }
15.2 IO流
15.2.1 概念
- 内存与存储设备之间传输数据的通道。
- 水借助管道传输;数据借助流传输。
15.2.2 流的分类
15.2.2.1 按方向
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
15.2.2.2 按单位
- 字节流:以字节为单位,可以读写所有数据 。
- 字符流:以字符为单位,只能读写文本数据 。
15.2.2.3 按功能
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
15.3 字节流【重点】
15.3.1 字节抽象类
InputStream
:字节输入流
- public int read(){}。
- public int read(byte[] b){}。
- public int read(byte[] b,int off,int len){}。
OutputStream
:字节输出流
- public void write(int n){}。
- public void write(byte[] b){}。
- public void write(byte[] b,int off,int len){}。
15.3.2 文件字节流【重点】
FileOutputStream
:
out.write(int b)
;
- 一次写入一个字节,整数表示这个字节对应ASCII码值
out.write(byte b)
;
- 一次写入一个字节数组的内容
out.write(b, off, len)
;
- 参数2:从数组的指定位置开始
- 参数3:执行写出的字节个数
- 一次写入一个字节数组的内容
FileInputStream
:
fis.read()
;
- 一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1
fis.read(byte[] b)
;
- 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
fis.read(byte[] b,int offset,int len)
;
- 参数2:读取到数组中指定起始位置
- 参数3: 指定读取的字节个数
- 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
文件字节输入流
FileInputStream
public class FileInputStreamDemo { public static void main(String[] args) { FileInputStream fis = null; try { //一、创建流对象 fis = new FileInputStream("a.txt"); //二、通过流对象进行读或者写 /* * 方法1:read() * 一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1 */ // System.out.println(fis.read()); // System.out.println(fis.read()); // System.out.println(fis.read()); // System.out.println(fis.read()); /** * 方法2:fis.read(b) * 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1 * */ //自定义缓冲区 // byte[] buf = new byte[1024]; // int len = fis.read(buf); // //将byte数组转换成String字符串 // String str = new String(buf,0,len); // System.out.println(str); //自定义缓冲区 // byte[] buf = new byte[1024]; // int len; // while( (len = fis.read(buf)) != -1) { // String str = new String(buf,0,len); // System.out.println(str); // } /** * 方法3:fis.read(buf,offset,len); * 参数2:读取到数组中指定起始位置 * 参数3: 指定读取的字节个数 * * 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1 */ //自定义缓冲区 byte[] buf = new byte[1024]; fis.read(buf, 2, 3); System.out.println(Arrays.toString(buf)); } catch (Exception e) { e.printStackTrace(); }finally { //三、关闭流对象 try { if(fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }
文件字节输入流FileOutputStream
public class FileOutputStreamDemo { public static void main(String[] args) { //一、创建流对象 FileOutputStream fos = null; try { fos = new FileOutputStream(new File("b.txt")); //二、通过流对象进行读或者写 /** * fos.write(int b) * 一次写入一个字节,整数表示这个字节对应ASCII码值 */ //fos.write(97); /** * fos.write(byte[] b); * 一次写入一个字节数组的内容 */ //byte[] b = "你好".getBytes(); //fos.write(b); /** * fos.write(byte[] b,int offset,int len); * 参数2:从数组的指定位置开始 * 参数3:执行写出的字节个数 * * 一次写入一个字节数组的内容 */ byte[] b = "你好吗?".getBytes(); //System.out.println(Arrays.toString(b)); //fos.write(b, 2, 6); fos.write(b,0,b.length); } catch (Exception e) { e.printStackTrace(); }finally { //三、关闭流对象 try { if(fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
15.3.3 IO流细节
- 1、在使用文件输出流的时候如果文件不存在会自动创建,但是要保证其父目录存在
- 2、在使用文件输出流的时候,如果想要向文件中追加内容,那么需要将构造参数append设置为true
- 3、在使用IO读写的时候,读写的操作应当写在try代码块中,关闭资源的代码写在finally代码块中
- 4、将IO流的创建写在try()中,这样IO流在使用完成之后无需关闭
15.3.4 字节缓冲流【重点】
缓冲流:
BufferedOutputStream
/BufferedInputStream
- 提高IO效率,减少访问磁盘的次数。
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
public class BufferedSteamDemo { public static void main(String[] args) throws Exception { // //一、创建缓冲流流对象 // FileInputStream fis = new FileInputStream("c.txt"); // BufferedInputStream bis = new BufferedInputStream(fis); // // //二、通过流对象进行读写 // byte[] buf = new byte[1024]; // int len; // while((len = bis.read(buf) ) != -1) { // String str = new String(buf, 0, len); // System.out.println(str); // } // // //三、关闭流资源(后用先关闭) // bis.close(); // fis.close(); //一、创建缓冲流流对象 FileOutputStream fos = new FileOutputStream("d.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); //二、通过流对象进行读写 bos.write("hello,缓冲流".getBytes()); //刷新(将缓冲区的内容刷新到目的地(硬盘)) bos.flush(); //三、关闭流资源(后用先关闭) //关闭流资源的时候,会自动刷新缓冲区内容。(只会刷新一次) bos.close(); fos.close(); } }
15.3.5 综合案例(文件拷贝)
public class FileCopyDemo { public static void main(String[] args) { copy2(); } public static void copy1() { long start = System.currentTimeMillis(); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip"); fos = new FileOutputStream("d:\\1.zip"); //定义缓冲区(一次读取1024个字节) byte[] buf = new byte[1024]; int len; while((len = fis.read(buf)) != -1) { fos.write(buf,0,len); } } catch (Exception e) { e.printStackTrace(); }finally { try { if(fis!=null) fis.close(); if(fos!=null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } long end = System.currentTimeMillis(); //字节流耗时:147035 System.out.println("字节流耗时:"+(end - start)); } public static void copy2() { long start = System.currentTimeMillis(); FileInputStream fis = null; BufferedInputStream bis = null; FileOutputStream fos = null; BufferedOutputStream bos = null; try { fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip"); fos = new FileOutputStream("d:\\1.zip"); bis = new BufferedInputStream(fis,80*1024); bos = new BufferedOutputStream(fos,80*1024); byte[] buf = new byte[1024]; int len; while((len = bis.read(buf)) !=-1) { bos.write(buf, 0, len); //刷新一次就相当于磁盘之间的一次IO操作,会降低效率 //bos.flush(); } } catch (Exception e) { e.printStackTrace(); }finally { try { if(fis!=null) fis.close(); if(bis != null) bis.close(); if(bos!=null) bos.close(); if(fos!=null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } long end = System.currentTimeMillis(); //缓冲流耗时:106388 System.out.println("缓冲流耗时:"+(end - start)); } }
copy1()方法耗时147s
copy2()方法耗时17s
15.3.6 对象流【重点】
对象流:
ObjectOutputStream
/ObjectInputStream
- 增加了缓冲区功能。
- 增加了读写8种基本数据类型和字符串功能。
- 增加了读写对象的功能:
readObject()
从流中读取一个对象。writeObject(Object obj)
向流中写入一个对象
15.3.6.1 对象流读写基本类型
//============对象流读写基本类型+String类型============ //一、创建流对象 FileOutputStream fos = new FileOutputStream("e.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); //二、通过对象流进行读写 oos.writeInt(97); //Integer oos.writeDouble(100.25); //Double oos.writeUTF("对象流"); //String //三、关闭流资源 oos.close(); fos.close(); //一、创建流对象 FileInputStream fis = new FileInputStream("e.txt"); ObjectInputStream ois = new ObjectInputStream(fis); //二、通过对象流进行读写 (读取的顺序和写入的顺序要一致) System.out.println(ois.readInt()); System.out.println(ois.readDouble()); System.out.println(ois.readUTF()); //三、关闭流资源 ois.close(); fis.close();
15.3.6.2 对象流读写对象
对象流写操作(序列化)
//============对象流读写对象============ //写入对象 FileOutputStream fos = new FileOutputStream("f.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); User user = new User("cxk", 30); oos.writeObject(user); oos.close(); fos.close();
对象流写操作(反序列化)
//读取对象 FileInputStream fis = new FileInputStream("f.txt"); ObjectInputStream ois = new ObjectInputStream(fis); User user1 = (User) ois.readObject(); System.out.println(user1); ois.close(); fis.close();
实体类(必须要实现序列化接口)
class User implements Serializable{ String name; int age; //..... }
15.3.6.3 对象流读写集合
//============对象流读写List集合============ //写入对象 FileOutputStream fos = new FileOutputStream("f.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); User user1 = new User("cxk1", 31); User user2 = new User("cxk2", 32); User user3 = new User("cxk3", 33); List<User> userList = new ArrayList<User>(); userList.add(user1); userList.add(user2); userList.add(user3); oos.writeObject(userList); oos.close(); fos.close(); //读取对象 FileInputStream fis = new FileInputStream("f.txt"); ObjectInputStream ois = new ObjectInputStream(fis); List<User> users = (List<User>) ois.readObject(); System.out.println(users); List<User> users1 = (List<User>) ois.readObject(); ois.close(); fis.close();
15.3.6.4 对象流使用细节
序列化的细节:
- 1、对象流读到流的末尾,会抛出异常
EOFException
- 2、如果属性不想被序列化,那么可以使用transient关键字修饰
3、类实现了Serializable接口,会自动生成一序列化id(序列化和反序列的id要保证一致)
15.4 字符流【重点】
15.4.1 字符抽象类
Reader:字符输入流
public int read(){}。
public int read(char[] c){}。
- public int read(char[] b,int off,int len){}。
Writer
:字符输出流
- public void write(int n){}。
- public void write(String str){}。
- public void write(String str,int offset,int len){}。
- public void write(char[] c){}。
- public void write(char[] c,int offset,int len){}。
15.4.2 文件字符流【重点】
文件字符输入流
FileReader
public class FileReaderAndWriterDemo2 { public static void main(String[] args) throws Exception { //一、创建字符流对象 FileReader fr = new FileReader("h.txt"); //二、通过流对象读写数据 /** * fr.read() * 一次读取一个字符,并返回这个字符在Unicode码表中的值,如果读到流的末尾返回-1 */ //System.out.println(fr.read()); //System.out.println(fr.read()); /** * fr.read(char[] ch) * 一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1 */ // char[] cbuf = new char[1024]; // int len; // while((len = fr.read(cbuf)) != -1) { // String str = new String(cbuf, 0, len); // System.out.println(str); // } /** * fr.read(char[] ch,int offset,int len) * 参数2:指定存放在数组中的起始位置 参数3:指定存放字符的长度 * 一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1 */ char[] cbuf = new char[1024]; fr.read(cbuf, 3, 10); System.out.println(Arrays.toString(cbuf)); //三、关闭流资源 fr.close(); } }
文件字符输出流 FileWriter
public class FileReaderAndWriterDemo { public static void main(String[] args) throws Exception { //一、创建字符流对象 FileWriter fw = new FileWriter("h.txt"); //二、通过流对象读写数据 /** * write(int b) * 写入一个字符,整数表示这个字符在Unicode码表中的值 */ //fw.write(97); //fw.write(20320); /** * write(char[] ch) * 写入一个字符数组 */ //String str = "你真棒"; //fw.write(str.toCharArray()); /** * write(String str) * 写入一个字符串 */ //fw.write("你好真棒!!!"); /** * write(char[] ch,int offset,int len) * 参数2:可以指定数组的起始位置 参数3:可以指定写入的字符长度 * 写入一个字符数组 */ //String str = "你真棒"; //fw.write(str.toCharArray(), 1, 2); /** * write(String str) * 参数2:可以指定字符串的起始位置 参数3:可以指定写入的字符长度 * 写入一个字符串 */ fw.write("你好真棒!!!", 1, 2); //三、关闭流资源 fw.close(); } }
15.4.3 字符缓冲流【重点】
缓冲流:
BufferedWriter
/BufferedReader
- 支持输入换行符
- 可一次写一行、读一行。
public class BufferedDemo { public static void main(String[] args) throws Exception { //1、创建字符串缓冲输入流 BufferedReader br = new BufferedReader(new FileReader("d:\\a.txt")); //2、通过字符缓冲流读取内容 //一次一行内容,读到文件末尾返回null //System.out.println(br.readLine()); String line; while((line = br.readLine()) != null) { System.out.println(line); } //3、关闭资源 br.close(); //1、创建字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\ddd.txt")); bw.write("BufferedWriter。。。。。"); //写入一个换行 bw.newLine(); bw.write("第二行。。。。。"); //3、关闭资源 bw.close(); } }
15.4.4 转换流
转换流:
InputStreamReader
/OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
将字节输入流转换成字符输入流,并设置编码
public class InputStreamReaderDemo { public static void main(String[] args) throws Exception { //1、创建字节流对象 FileInputStream fis = new FileInputStream("d:\\a.txt"); //2、将字节流装换成字符流 InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); //3、将字符流包装成字符缓冲流 BufferedReader br = new BufferedReader(isr); String line; while( (line = br.readLine()) != null) { System.out.println(line); } br.close(); //OutputStreamWriter 将字节输出流转换成字符输出流 } }
15.4.5 打印流
- 字节打印流
- 字符打印流
打印流中提供了一组可以直接写出基本类型和String的方法
注意:打印流中的print(Object obj)方法并不是写出对象,而是写出对象的toString方法的返回值
public class PrintDemo { public static void main(String[] args) throws Exception { //1、创建字节打印流 PrintStream ps = new PrintStream("D:\\aaaa.txt"); //printXXX方法 ps.print(10); //换行 ps.println("dsadsa"); ps.print("哈哈print流"); //注意:写入的是对象字符串变现形式(toString方法的结果) ps.print(new Student()); ps.close(); //2、创建字符打印流 PrintWriter pw = new PrintWriter("D:\\aaaa.txt"); pw.print("哈哈"); pw.println(); pw.print(1000); pw.close(); } }
15.5 字符编码【理解】
- 字符
- 各个国家的文化符号
- 字符集
- 将文化符号进行统一收集生成字符集合(字典)
- 字符编码
- 每一种字符集 对字符的编排
- 常见字符集 :
ASCII
、GBK
、Unicode
(万国码)
- 常见的字符编码:
ASCII编码 GBK编码 UTF-8 UTF-16 UTF-32 ISO8859-1 Big5 GB2312 GB18030
ASCII编码
- 美国信息交换标准代码 最多只能表示256个字符
- 一个字符 = 一个字节
GBK编码
- 国标码 前身是
GB2312
- 如果是0~128 ASCII码中的字符 。 一个字符 = 一个字节
- 其他情况 一个字符 = 两个字节
UTF-8 编码
- 可变字符
- 如果是0~128 ASCII码中的字符 一个字符 = 一个字节
- 如果是128~2048 Unicode码表中的字符 一个字符 = 两个字节
- 如果是2048 ~65535 Unicode码表的字符 一个字符 = 三个字节
- 编码:
- 将程序的内容写入到目的地,就是编码过程
- 解码:
- 将目的地的内容读取到程序中,就是解码过程
- 为什么会出现乱码?
- 编码和解码的编码方式不一致
常见字符编码:
编码 | 说明 |
ISO-8859-1 | 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。 |
UTF-8 | 针对Unicode的可变长度字符编码。 |
GB2312 | 简体中文。 |
GBK | 简体中文、扩充。 |
BIG5 | 台湾,繁体中文。 |
15.6 Properties实现流操作
Properties:属性集合。
特点:
- 存储属性名和属性值。
- 属性名和属性值都是字符串类型。
- 没有泛型。
- 和流有关。
案例演示:Properties实现流操作。
public class TestProperties { public static void main(String[] args) throws Exception { //1创建集合 Properties properties=new Properties(); //2添加数据 properties.setProperty("username", "zhangsan"); properties.setProperty("age", "20"); System.out.println(properties.toString()); //3遍历 //3.1-----keySet----略 //3.2-----entrySet----略 //3.3-----stringPropertyNames()--- Set<String> pronames=properties.stringPropertyNames(); for (String pro : pronames) { System.out.println(pro+"====="+properties.getProperty(pro)); } //4和流有关的方法 //----------list方法--------- PrintWriter pw=new PrintWriter("d:\\print.txt"); properties.list(pw); pw.close(); //----------2store方法 保存----------- FileOutputStream fos=new FileOutputStream("d:\\store.properties"); properties.store(fos, "注释"); fos.close(); //----------3load方法 加载------------- Properties properties2=new Properties(); FileInputStream fis=new FileInputStream("d:\\store.properties"); properties2.load(fis); fis.close(); System.out.println(properties2.toString()); } }