IO流
什么是流?
-
概念:内存与存储设备之间传输数据的通道
流的分类
-
按照方向
-
输入流:将 存储设备 中的内容读入 内存 中
-
输出流:将 内存 中的内容写入到 存储设备 中
-
-
按单位
-
字节流: 可以读写所有数据
-
字符流: 只能读写文本数据
-
-
按功能
-
节点流: 具有实际传输数据的读写功能。
-
过滤流:在节点流的基础之上增强功能。
-
字节流
字节流的父类(抽象类)
-
InputStream
public abstract class InputStream extends Object implements Closeable 这个抽象类是表示输入字节流的所有类的超类。
-
OutputStream
public abstract class OutputStream extends Object implements Closeable, Flushable
这个抽象类是表示字节输出流的所有类的超类。 输出流接收输出字节并将其发送到某个接收器。
主要用到的子类:
文件字节流:
FileInputStream
public int read(byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
package com.zhangan.io; import java.io.FileInputStream; import java.io.FileNotFoundException; /** * 文件字节输入流 * FileInputStream */ public class FileInputStreamDemo { public static void main(String[] args) throws Exception { //创建fileInputStream FileInputStream fileInputStream = new FileInputStream("F:\\idea\\files\\study\\testIO\\aaa.txt"); //单个字节 读取文件 // int data = 0; // while ((data=fileInputStream.read())!=-1){ // System.out.print((char)data); // } //一次读取多个字节 // byte[] buf = new byte[3]; // int i = fileInputStream.read(buf); // System.out.println(i); // System.out.println("---"); // System.out.println(buf); // System.out.println("---"); // System.out.println(new String(buf)); byte[] bytes = new byte[1024]; int count = 0; while ((count=fileInputStream.read(bytes))!=-1){ System.out.println(new String(bytes,0,count)); } //关闭 fileInputStream.close(); } }
FileOutputStream
public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流。
package com.zhangan.io; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * 文件字节输出流 * FileOutputStream */ public class FileOutputStreamDemo { public static void main(String[] args) throws IOException { //创建文件字节输出流对象 参数2:追加内容还是替换内容 FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt",true); //写入文件 fileOutputStream.write(100);//asc码 fileOutputStream.write('a'); fileOutputStream.write('c'); String str = "hello world"; fileOutputStream.write(str.getBytes()); //关闭 fileOutputStream.close(); System.out.println("完成"); } }
复制图片小案例
package com.zhangan.io; import java.io.FileInputStream; import java.io.FileOutputStream; /** * 实现图片的复制 */ public class CopyExample { public static void main(String[] args) throws Exception { //创建文件字节输入流 FileInputStream fileInputStream = new FileInputStream("F:\\idea\\files\\study\\testIO\\one.png"); //文件字节输入流 FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\files\\study\\testIO\\copy.png"); //一边读取 一边写入 byte[] buf = new byte[1024]; //1k 缓冲区 int count = 0;//实际读取字节个数 while ((count=fileInputStream.read(buf))!=-1){ /** * write(byte[] b, int off, int len) * 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。 */ fileOutputStream.write(buf,0,count);//防止最后一次不是1k的数据 } fileInputStream.close(); fileOutputStream.close(); System.out.println("完成copy"); } }
字节缓冲流 :
缓冲流:BufferedInputStream
BufferedOutputStream
提高IO效率,减少访问磁盘的次数; 数据存储在级冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
BufferedInputStream
package com.zhangan.io; import java.io.BufferedInputStream; import java.io.FileInputStream; /** * BufferedInputStreamDemo 字节缓冲流读取 */ public class BufferedInputStreamDemo { public static void main(String[] args) throws Exception{ //创建 FileInputStream FileInputStream fileInputStream = new FileInputStream("F:\\idea\\files\\study\\testIO\\aaa.txt"); //创建 BufferedInputStream BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); //读取数据 /** * 自带缓冲区 8k 也可以自己维护缓冲区 */ // int data = 0; // while ((data = bufferedInputStream.read())!=-1){ // System.out.println((char)data); // } byte[] buf = new byte[1024*8]; int count = 0; while ((count = bufferedInputStream.read(buf))!=-1){ System.out.println(new String(buf,0,count)); } bufferedInputStream.close(); System.out.println("完成"); } }
BufferedOutputStream
package com.zhangan.io; import java.io.BufferedOutputStream; import java.io.FileOutputStream; /** * BufferedOutputStream 字节缓冲流 写入文件 */ public class BufferedOutputStreamDemo { public static void main(String[] args) throws Exception { //创建 FileOutputStream FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt"); //创建 BufferedOutputStream BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); for (int i = 0; i < 10; i++) { bufferedOutputStream.write("hello world\r\n".getBytes()); //写入的是 8k的缓冲区 \r\n 表示换行 bufferedOutputStream.flush();//刷新到硬盘 } //关闭 close也会内部关闭flush 缓存区域满了也会调用flush 为了防止断电丢失数据 最好每次刷新 bufferedOutputStream.close(); System.out.println("完成"); } }
对象流
对象流:ObjectOutputStream
ObjectInputStream
。
-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能
-
read0bject()从流中读取一个对象
-
write0bject (0bject obj)向流中写入一个对象
-
使用流传输对象的过程称为序列化、反序列化。
ObjectOutputStream
package com.zhangan.io; import com.zhangan.entity.Student; import java.io.FileOutputStream; import java.io.ObjectOutputStream; /** * ObjectOutputStream 实现对象的序列化 */ public class ObjectOutputStreamDemo { public static void main(String[] args) throws Exception { //创建对象流 FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\files\\study\\testIO\\student.bin");//文件名后缀可以随便起 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); //实现序列化 === 写入操作 Student student = new Student("张安", 18); objectOutputStream.writeObject(student); objectOutputStream.flush();//可以不用调用 close会一起调用 //关闭 objectOutputStream.close(); System.out.println("完成"); } }
ObjectInputStream
package com.zhangan.io; import com.zhangan.entity.Student; import java.io.FileInputStream; import java.io.ObjectInputStream; /** * ObjectInputStream 实现反序列化 ==== 读取重构成对象 */ public class ObjectInputStreamDemo { public static void main(String[] args) throws Exception { //创建对象流 FileInputStream fileInputStream = new FileInputStream("F:\\idea\\files\\study\\testIO\\student.bin"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); //读取(反序列化) Student student = (Student) objectInputStream.readObject(); //关闭 objectInputStream.close(); System.out.println(student.toString()); } }
注意事项: (1)序列化类必须要实现Serializable接口
(2)序列化类中对象属性要求实现Serializable接口
(3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类
(4)使用transient(瞬间的)修饰属性,这个属性不能序列化
(5)静态属性也不能序列化
(6)序列化多个对象可以借助集合实现
字符流
字符编码
-
SO-8859-1 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
-
UTF-8 针对Unicode码表的可变长度字符编码。
-
GB2312 简体中文
-
GBK 简体中文、扩充
-
BIG5 台湾,繁体中文
字符流的父类(抽象类)
Reader
Writer
问题:
如果使用字节流,读取汉字(utf-8)的时候 一个汉字3个字节 读取会出现乱码
解决方案:使用字符流
主要用到的子类:
文件字符流
FileReader: public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。
package com.zhangan.io; import java.io.FileReader; /** * FileReader */ public class FileReaderDemo { public static void main(String[] args) throws Exception { //创建FileReader FileReader fileReader = new FileReader("F:\\idea\\files\\study\\testIO\\aaa.txt"); //读取 /** * 单个字符读取 */ // int data = 0; // while ((data = fileReader.read()) != -1) { // System.out.print((char) data); // } /** * 自定义缓冲区 */ char[] buf = new char[1024]; int count = 0; while ((count = fileReader.read(buf)) != -1) { System.out.println(new String(buf, 0, count)); } //关闭 fileReader.close(); } }
FileWriter: public void write(String str)//一次写多个字符,将b数组中所有字符,写入输出流。
package com.zhangan.io; import java.io.FileWriter; /** * FileWriter */ public class FileWriterDemo { public static void main(String[] args) throws Exception { //创建 FileWriter fileWriter = new FileWriter("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt"); //写入 for (int i = 0; i < 10; i++) { fileWriter.write("java是世界上最好的语言\r\n"); fileWriter.flush(); } fileWriter.close(); System.out.println("完成"); } }
复制文本小案例
package com.zhangan.io; import java.io.FileReader; import java.io.FileWriter; /** * 使用字符流 * 复制文件 * 只能复制文本文件 不能复制图片,声音,二进制文件 */ public class CopyExample2 { public static void main(String[] args) throws Exception { FileReader fileReader = new FileReader("F:\\idea\\files\\study\\testIO\\aaa.txt"); FileWriter fileWriter = new FileWriter("F:\\idea\\files\\study\\testIO\\copy2.txt"); char[] buf = new char[1024]; int count = 0; while ((count = fileReader.read(buf)) != -1) { fileWriter.write(buf, 0, count); fileWriter.flush(); } fileReader.close(); fileWriter.close(); System.out.println("完成"); } }
字符缓冲流
缓冲流:
BufferedReader
BufferedWriter
。
-
高效读写
-
支持输入换行符。公
-
可一次写一行、读一行。
BufferedReader
package com.zhangan.io; import java.io.BufferedReader; import java.io.FileReader; /** * BufferedReader * 字符缓冲流 读取文件 */ public class BufferedReaderDemo { public static void main(String[] args) throws Exception { //创建 FileReader fileReader = new FileReader("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt"); BufferedReader bufferedReader = new BufferedReader(fileReader); //读取 /** * 第一种方法 */ // char[] buf = new char[1024]; // int count = 0; // while ((count = bufferedReader.read(buf))!=-1){ // // System.out.print(new String(buf,0,count)); // // } /** * 第二种方式 一行一行读 */ String line = null; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } //关闭 bufferedReader.close(); } }
BufferedWriter
package com.zhangan.io; import java.io.BufferedWriter; import java.io.FileWriter; /** * BufferedWriter */ public class BufferedWriterDemo { public static void main(String[] args) throws Exception { //创建 FileWriter fileWriter = new FileWriter("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt", true); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); //写入 for (int i = 0; i < 10; i++) { bufferedWriter.write("好好努力!"); bufferedWriter.newLine(); bufferedWriter.flush(); } //关闭 bufferedWriter.close(); System.out.println("完成"); } }
打印流
PrintWriter:
-
封装了print() / println()方法,支持写入后换行。。
-
支持数据原样打印
package com.zhangan.io; import java.io.PrintWriter; /** * PrintWriter */ public class PrintWriterDemo { public static void main(String[] args) throws Exception { PrintWriter printWriter = new PrintWriter("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt"); printWriter.println(97); printWriter.println(true); printWriter.println(3.14); printWriter.println(3L); printWriter.println("汉字"); printWriter.close(); System.out.println("完毕"); } }
转换流
桥转换流:
InputStreamReader
OutputStreamWriter
。
-
可将字节流转换为字符流。
-
可设置字符的编码方式。
InputStreamReader
package com.zhangan.io; import java.io.FileInputStream; import java.io.InputStreamReader; /** * InputStreamReader 可以使用指定的编码 */ public class InputStreamReaderDemo { public static void main(String[] args) throws Exception { //创建 FileInputStream fileInputStream = new FileInputStream("F:\\idea\\files\\study\\testIO\\aaa.txt"); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8"); //读取 int data = 0; while ((data = inputStreamReader.read()) != -1) { System.out.print((char) data); } //关闭 inputStreamReader.close(); } }
OutputStreamWriter
package com.zhangan.io; import java.io.FileOutputStream; import java.io.OutputStreamWriter; /** * OutputStreamWriter */ public class OutputStreamWriterDemo { public static void main(String[] args) throws Exception { //创建 FileOutputStream fileOutputStream = new FileOutputStream("F:\\idea\\files\\study\\testIO\\fileoutputstream.txt"); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "utf-8"); //写入 String encoding = outputStreamWriter.getEncoding(); System.out.println(encoding); for (int i = 0; i < 10; i++) { outputStreamWriter.write("我爱学习\r\n"); outputStreamWriter.flush(); } //关闭 outputStreamWriter.close(); System.out.println("完成"); } }
File类
概念:代表物理盘符中的一个文件或者文件夹。。
方法:
-
createNewFile()//创建一个新文件。
-
mkdir()//创建一个新目录
-
delete()//删除文件或空目录
-
exists()//判断File对象所对象所代表的对象是否存在
-
getAbsolutePath(//获取文件的绝对路径
-
getName ()//取得名字
-
getParent()//获取文件/目录所在的目录
-
isDirectory ()//是否是目录
-
isFile()//是否是文件
-
length()//获得文件的长度
-
listFiles()//列出目录中的所有内容
-
renameTo()//修改文件名为
-
......
package com.zhangan.io; import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * FileDemo * (1)分隔符 * (2)文件操作 * (3)文件夹操作 */ public class FileDemo { public static void main(String[] args) throws Exception { // separtor(); // fileOperation(); directoryOperation(); } //(1)分隔符 public static void separtor() { System.out.println("路径分隔符" + File.pathSeparator); System.out.println("名称分隔符" + File.separator); } //(2)文件操作 public static void fileOperation() throws Exception { //创建文件 File file = new File("F:\\idea\\files\\study\\testIO\\file.txt"); //判断文件是否存在 if (!file.exists()) { boolean b = file.createNewFile(); System.out.println("创建结果:" + b); } //删除文件 // (1)直接删除 // boolean b = file.delete(); // System.out.println("删除结果:" + b); // (2)使用jvm退出时删除 // file.deleteOnExit(); // Thread.sleep(5000); //获取文件信息 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("文件创建时间" + SimpleDateFormat.getInstance().format(file.lastModified())); //判断 System.out.println("是否可写:" + file.canWrite()); System.out.println("是否是文件" + file.isFile()); System.out.println("是否隐藏" + file.isHidden()); } public static void directoryOperation() throws Exception { //创建文件夹 File file = new File("F:\\idea\\files\\study\\testIoDirectory"); if (!file.exists()) { //file.mkdir();//只能创建单级目录 boolean b = file.mkdirs();//创建多级目录 System.out.println("创建结果" + b); } //删除文件夹 //(1)直接删除 //只能删除空目录 //System.out.println("删除结果"+file.delete()); //使用jvm退出时删除 //file.deleteOnExit(); //获取文件夹信息 System.out.println("获取文件绝对路径" + file.getAbsolutePath()); System.out.println("获取路径" + file.getPath());//上面写什么就返回什么 System.out.println("文件名称" + file.getName()); System.out.println("获取父目录" + file.getParent()); System.out.println("文件创建时间" + SimpleDateFormat.getInstance().format(file.lastModified())); //判断 System.out.println("是否是文件夹" + file.isDirectory()); System.out.println("是否隐藏" + file.isHidden()); //遍历 File file1 = new File("F:\\idea\\files\\study\\testIO"); String[] list = file1.list(); for (String s : list) { System.out.println(s); //打印文件夹或者文件名 } } }
FileFilter文件过滤器
public interface FileFilter
-
boolean accept(File pathname)
-
当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。
System.out.println("========FileFilter接口的使用=========="); File[] listFiles = file1.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName().endsWith(".txt")) { return true; } return false; } }); for (File listFile : listFiles) { System.out.println(listFile); }
递归遍历文件夹与递归删除文件夹
package com.zhangan.io; import java.io.File; /** * 递归遍历文件夹 与 递归删除文件夹 */ public class ListDemo { public static void main(String[] args) { // listDir(new File("F:\\idea\\files\\study\\listfiles")); deleteDir(new File("F:\\idea\\files\\study\\listfiles")); } //递归遍历文件夹 public static void listDir(File dir) { File[] listFiles = dir.listFiles(); if (listFiles != null && listFiles.length > 0) { for (File file : listFiles) { if (file.isDirectory()) { listDir(file); } else { System.out.println("文件:" + file.getAbsolutePath()); } } } } //递归删除文件夹 public static void deleteDir(File dir) { File[] listFiles = dir.listFiles(); if (listFiles != null && listFiles.length > 0) { for (File file : listFiles) { if (file.isDirectory()) { deleteDir(file); } else { System.out.println("文件:" + file.getAbsolutePath() + "删除结果:" + file.delete()); } } } System.out.println("文件:" + dir.getAbsolutePath() + "删除结果:" + dir.delete()); } }