流的概念
内存与存储设备之间传输数据的通道。(数据借助流传出)
流的分类
按方向划分:
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
按单位划分:
- 字节流:以字节为单位,可以读写所有数据。
- 字符流:以字符为单位,只能读写文本数据。
按功能划分:
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
字节流
字节流的父类(抽象类):
- InputStream:字节输入流
- OutputStream:字节输出流
文件字节流
-
FileInputStream:
-
public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
-
FileInputStream的使用:
/** * 演示FileInputStream的使用 * 文件字节输入流 */ public class FileInputStreamDemo { public static void main(String[] args) throws Exception{ //1.创建FileInputStream,并指定文件路径 FileInputStream fis = new FileInputStream("d:\\aaa.txt"); //2.读取文件 //fis.read(); //2.1 单个字节读取 // int data = 0; // while ((data = fis.read())!=-1){ // System.out.println((char) data); // } //2.2 一次读取多个字节 byte[] buf = new byte[3]; int count = 0; while ((count=fis.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } //3.关闭 fis.close(); System.out.println("closed!!"); } }
-
-
FileOutputStream:
-
public void write(byte[] b) //一次写多个字节,将b数组中的所有字节,写入输出流。
-
FileOutputStream的使用:
/** * FileOutputStream的使用 * 文件字节输出流 */ public class FileOutputStreamDemo { public static void main(String[] args) throws Exception { //1.创建文件字节输出流对象 FileOutputStream fos = new FileOutputStream("d:\\bbb.txt",true); //2.写入文件 // fos.write(97); // fos.write('b'); // fos.write('c'); String s = "hello!"; fos.write(s.getBytes()); //3.关闭 fos.close(); System.out.println("closed!!"); } }
-
-
文件字节流实例(实现文件复制):
/**
* 使用文件字节流实现文件复制
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
//1.创建流
//1.1 文件字节输入流
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//1.2 文件字节输出流
FileOutputStream fos = new FileOutputStream("d:\\aaa2.txt",true);
//2. 一边读,一边写
byte[] buf = new byte[1024];
int count = 0;
while ((count= fis.read(buf))!=-1){
fos.write(buf,0,count);
}
fis.close();
fos.close();
System.out.println("copy closed!");
}
字节缓冲流
-
缓冲流:BufferedInputStream/BufferedOutputStream
- 提高IO效率,减少访问磁盘的次数;
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
-
BufferedInputStream
/** * BufferedInputStream使用 * 使用字节缓冲流读取 */ public class BufferedInputStreamDemo { public static void main(String[] args) throws Exception{ //1. 创建BufferedInputStream FileInputStream fis = new FileInputStream("d:\\aaa.txt"); BufferedInputStream bis = new BufferedInputStream(fis); //2. 读取 // int data=0; // while ((data=bis.read())!=-1){ // System.out.print((char) data); // } byte[] buf= new byte[1024]; int count=0; while ((count= bis.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } // 3. 关闭 bis.close(); } }
-
BufferedOutputStream
/** * 使用字节缓冲流写入文件 * BufferedOutputStream */ public class BufferedOutputStreamDemo { public static void main(String[] args) throws Exception{ //1.创建字节输出缓冲流 FileOutputStream fos = new FileOutputStream("d:\\buffer.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); //2.写入文件 for (int i = 0; i < 10; i++) { bos.write("Hello!\r\n".getBytes()); //写入8K缓冲区 bos.flush(); //刷新到硬盘 } //3.关闭(内部会调用flush方法) bos.close(); } }
对象流
-
对象流:ObjectOutputStream/ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能:
- readObject() 从流中读取一个对象
- writeObject(Object obj) 向流中写入一个对象
- 使用流传输对象的过程称为序列化、反序列化。(将对象写入至文件中的过程称为序列化、从文件中读取出来的过程称为反序 列化)
-
序列化实例:
/** * 使用ObjectOUtputStream实现对象的序列化 * 注意事项: * (1)序列化的类必须要实现Serializable接口 * (2)序列化类中的对象属性要求实现Serializable接口 * (3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类 * (4)使用transient(临时的)修饰属性,这个属性不能序列化 * (5)静态属性不能被序列化 * (6)序列化多个对象,可以借助集合实现 */ public class ObjectOutputStreamDemo { public static void main(String[] args) throws Exception{ //1.创建对象流 FileOutputStream fos = new FileOutputStream("d:\\stu."); ObjectOutputStream oos = new ObjectOutputStream(fos); //2.序列化(写入操作) Student s1 = new Student("zhangsan", 18); oos.writeObject(s1); //3.关闭 oos.close(); System.out.println("closed!!"); } }
-
反序列化实例:
/** * ObjectInputStream实现反序列化(读取重构成对象) */ public class ObjectInputStreamDemo { public static void main(String[] args) throws Exception{ //1.创建对象流 FileInputStream fis = new FileInputStream("d:\\stu"); ObjectInputStream ois = new ObjectInputStream(fis); //2.读取文件(反序列化) Student s = (Student) ois.readObject(); //3.关闭 ois.close(); System.out.println(s.toString()); } }
字符流
-
字符编码
- ISO-8859-1 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
- UTF-8 针对Unicode码表的可变长度字符编
- GB2312 简体中文
- GBK 简体中文、扩充
- BIG5 台湾,繁体中文
-
字符流的父类(抽象类):
-
Reader:字符输入流
-
Write:字符输出流
-
文件字符流
-
FileReader:
-
public int read(char[] c) //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。
-
FileWriter:
-
public void write(String str) //一次写多个字符,将b数组种所有字符,写入输出流。
-
FileReader的使用:
/** * 使用FileReader读取文件 */ public class FileReaderDemo { public static void main(String[] args) throws Exception{ //1.创建FileReader文件字符输入流 FileReader fr = new FileReader("d:\\bbb.txt"); //2.读取 //2.1单个字符读取 // int data=0; // while ((data=fr.read())!=-1){ //读取一个字符 // System.out.print((char) data); // } //2.2多个字符读取 char[] buf = new char[2]; int count = 0; while ((count=fr.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } //3.关闭 fr.close(); } }
-
FileWriter的使用:
/** * 使用FileWriter写入文件 */ public class FileWriterDemo { public static void main(String[] args) throws Exception{ //1.创建FileWriter对象 FileWriter fw = new FileWriter("d:\\writer.txt"); //2.写入 for (int i = 0; i < 10; i++) { fw.write("HI~~~\r\n"); fw.flush(); } //3.关闭 fw.close(); } }
-
实现文件复制:
/** * 使用FileReader和FileWriter实现文本复制,不能复制图片或者二进制文件 * 使用字节流可以复制任意文件。 */ public class CopyDemo02 { public static void main(String[] args) throws Exception{ //1.创建FileReader和FileWriter FileReader fr = new FileReader("d:\\writer.txt"); FileWriter fw = new FileWriter("d:\\writer2.txt"); //2.读写 int data=0; while ((data= fr.read())!=-1){ fw.write(data); fw.flush(); } //3.关闭 fr.close(); fw.close(); } }
字符缓冲流
-
缓冲流:BufferedReader/BufferedWriter
- 高效读写
- 支持输入换行符
- 可一次写一行、读一行
-
BufferedReader的使用:
/** * 使用字符缓冲流读取文件 * BufferedReader */ public class BufferedReaderDemo { public static void main(String[] args) throws Exception{ //1.创建一个缓冲流 FileReader fr = new FileReader("d:\\writer.txt"); BufferedReader br = new BufferedReader(fr); //2.读取 //2.1第一种方式(一次读取多个字符) // char[] buf = new char[1024]; // int count = 0; // while ((count= br.read(buf))!=-1){ // System.out.println(new String(buf,0,count)); // } //2.2第二种方式(一次读取一行) String line = null; while ((line= br.readLine())!=null){ System.out.println(line); } //3 关闭 br.close(); } }
-
BufferedWriter的使用:
/** * BufferedWriter的使用 */ public class BufferedWriterDemo { public static void main(String[] args) throws Exception{ //1.创建BufferedWriter对象 FileWriter fw = new FileWriter("d:\\buffer.txt"); BufferedWriter bw = new BufferedWriter(fw); //2.写入 for (int i = 0; i < 10; i++) { bw.write("好好学习!\r\n"); //windows:\r\n 换行 linux:\n bw.newLine(); //写入一个换行符 bw.flush(); } //3.关闭 bw.close(); } }
打印流
-
PrintWriter:
- 封装了print() / println() 方法,支持写入后换行。
- 支持数据原样打印。
-
PrintWriter的使用:
/**
* PrintWriter的使用
*/
public class PrintWriterDemo {
public static void main(String[] args) throws Exception{
//1.创建打印流
PrintWriter pw = new PrintWriter("d:\\print.txt");
//2.打印
pw.println(97);
pw.println(31.4);
pw.println(true);
pw.println('a');
//3.关闭
pw.close();
}
}
转换流
-
桥转换流:InputStreamReader / OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
-
InputStreamReader读取文件:
/** * 使用InputStreamReader读取文件,指定使用的编码 */ public class InputStreamReaderDemo { public static void main(String[] args) throws Exception{ //1.创建InputStreamReader对象 FileInputStream fis = new FileInputStream("e:\\writer.txt"); InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //格式需与文件编码格式相同,否则会乱码 //2.读取文件 int data = 0; while ((data= isr.read())!=-1){ System.out.println((char) data); } //3.关闭 isr.close(); } }
-
OutputStreamWriter写入文件:
/** * 使用OutputStreamWriter写入文件,使用指定的编码 */ public class OutputStreamWriterDemo { public static void main(String[] args) throws Exception{ //1.创建OutputStreamWriter对象 FileOutputStream fos = new FileOutputStream("e:\\info.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk"); //2.写入 for (int i = 0; i < 10; i++) { osw.write("桥转换流:InputStreamReader / OutputStreamWriter\n" + "\n" + "* 可将字节流转换为字符流。\n" + "* 可设置字符的编码方式"); osw.flush(); } //3.关闭 osw.close(); } }
File类
File概念
代表物理盘符中的一个文件或者文件夹。
方法:
/**
* File类的使用
* (1)分隔符
* (2)文件操作
* (3)文件夹操作
*/
public class FileDemo {
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. 创建文件
File file = new File("e:\\file.txt");
System.out.println(file.toString());
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("e:\\aa\\bb\\cc");
System.out.println(dir.toString());
if (!dir.exists()){
// System.out.println(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("e:\\壁纸");
String[] file = dir2.list();
for (String s : file) {
System.out.println(s);
}
}
}
FileFilter接口(文件过滤器)
-
public interface FileFilter
-
boolean accept(File pathname)
-
当调用File类中的listFiles()方法时,支持传入 FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可出现在listFiles()方法的返回值中。
-
FileFilter的使用:
//--------FileFilter接口的使用----------- File[] file1 = dir2.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName().endsWith(".png")){ return true; } return false; } }); for (File file2 : file1) { System.out.println(file2.getName()); }
-
实例:递归遍历/删除文件夹
/** * 案例(1)递归遍历文件夹 * 案例(2)递归删除文件夹 */ public class ListDemo { public static void main(String[] args) { // listDir(new File("e:\\javaCode")); deleDir(new File("e:\\javaCode")); } //(1)递归遍历文件夹 public static void listDir(File f){ File[] files = f.listFiles(); System.out.println(f.getAbsoluteFile()); if (files!=null&&files.length>0){ for (File file : files) { if (file.isDirectory()){ listDir(file); //递归 }else System.out.println(file.getAbsoluteFile()); } } } //(2)递归删除文件夹 public static void deleDir(File dir){ File[] files = dir.listFiles(); if (files!=null&&files.length>0){ for (File file : files) { if (file.isDirectory()){ deleDir(file); } System.out.println(file.getAbsoluteFile()+"删除"+file.delete()); } } System.out.println(dir.getAbsoluteFile()+"删除"+dir.delete()); } }
总结
-
流的概念:
- 内存与存储设备之间传输数据的通道
-
流的分类:
- 输入流、输出流;字节流、字符流;节点流、过滤流;
-
序列化、反序列化:
- 将对象通过流写入到文件,或将对象通过流读取到内存,必须实现Serializable接口。
-
File对象:
- 代表物理盘符中的一个文件或者文件夹。