JAVA学习打卡第十天
什么是流
- 概念内存与存储设备之间传输数据的通道
- 水借助管道传输;数据借助流传输
- 流的分类:
- 按方向【重点】:
- 输入流:<存储设备>中的内容读入到<内存>中
- 输出流:将<内存>中的内容写入到<存储设备>中
- 按单位:
- 字节流:以字节为单位,可以读写所有数据
- 字符流:以字符为单位,只能读写文本数据
- 按功能:
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础上增强功能
- 按方向【重点】:
字节流
-
字节流的父类(抽象类):
- InputStream:字节输入流
- OutputStream:字节输出流
-
文件字节流
-
FileInputStream:
-
public int read(byte[] b):从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1
-
示例
import java.io.FileInputStream; public class FileStreamTest_1 { public static void main(String[] args) throws Exception{ //创建一个FileInputStream,并指定文件路径 FileInputStream fis = new FileInputStream("D:\\javatest.txt"); //读取文件(单个字节读取) System.out.println("==========单个字节读取=========="); int data = 0; while ((data = fis.read()) != -1) { System.out.print((char) data);//--->读出内容为对应的ascill编码,要强制类型转换 } System.out.print("\n执行完毕"); //关闭 fis.close(); } }
import java.io.FileInputStream; public class FileStreamTest_2 { public static void main(String[] args) throws Exception { //创建一个FileInputStream,并指定文件路径 FileInputStream fis = new FileInputStream("D:\\javatest.txt"); //多个字节读取 System.out.println("==========多个字节读取(1)=========="); byte[] buf = new byte[3]; int count = fis.read(buf); System.out.println(new String(buf)); System.out.println(count); count = fis.read(buf); System.out.println(new String(buf)); System.out.println(count); count = fis.read(buf); System.out.println(new String(buf, 0, count)); System.out.println(count); //关闭 fis.close(); } }
import java.io.FileInputStream; public class FileStreamTest_3 { public static void main(String[] args) throws Exception{ FileInputStream fis = new FileInputStream("D:\\javatest.txt"); System.out.println("==========多个字节读取(2)=========="); byte[] buf = new byte[3]; int count = 0; while ((count = fis.read(buf)) != -1) { System.out.println(new String(buf, 0, count)); } } }
-
-
FileOutputStream:
-
public void write(byte[] b):一次写多个字节,将b数组中所有字节,写入输出流
-
示例
import java.io.FileOutputStream; public class FileStreamTest_4 { public static void main(String[] args) throws Exception{ //创建文件字节输出流对象 //FileOutStream会覆盖文件中原来的数据,如不想覆盖,应在文件名后的append赋值为true FileOutputStream fos = new FileOutputStream("D:\\javatest_2.txt", true); //写入文件 System.out.println("==========单个传入=========="); fos.write(97); fos.write('b'); fos.write('c'); System.out.println("==========多个传入=========="); String string = "Hello world"; fos.write(string.getBytes()); //关闭 fos.close(); System.out.println("执行完毕"); } }
-
-
-
字节流复制文件
-
先读入到内存,再写入到硬盘
-
示例
import java.io.FileInputStream; import java.io.FileOutputStream; public class FileStreamTest_5 { public static void main(String[] args) throws Exception{ //创建文件字节输入流 FileInputStream fis = new FileInputStream("D:\\javatestjpg.jpg"); //创建文件字节输出流 FileOutputStream fos = new FileOutputStream("D:\\javatestjpg_2.jpg"); //一边读一边写 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("复制完毕"); } }
-
-
字节缓冲流
-
缓冲流:BufferedInputStream/BufferOutputStream
-
提高IO效率,减少访问磁盘的次数
-
数据存储在缓冲区中,flush是将缓存区的内容写入文件,也可以直接close
-
示例(输入):
import java.io.BufferedInputStream; import java.io.FileInputStream; public class BufferStreamTest_1 { public static void main(String[] args) throws Exception{ //创建字节缓冲输入流 FileInputStream fis = new FileInputStream("D:javatest_in.txt"); BufferedInputStream bis = new BufferedInputStream(fis); //读取 int data = 0; while((data = bis.read()) != -1) { System.out.print((char) data); } //关闭--->只需要关闭缓冲流,其内部会自动关闭字节流 bis.close(); } }
-
示例(输出):
import java.io.BufferedOutputStream; import java.io.FileOutputStream; public class BufferStreamTest_2 { public static void main(String[] args) throws Exception{ //创建字节缓冲输出流 FileOutputStream fos = new FileOutputStream("D:\\javatest_out_bufferstream.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); //写入文件--->内容不超过8k时,都写入缓冲区,虽然文件已经创建,但是没有内容 for (int i = 0; i < 10; i++) { bos.write("helloworld\r\n".getBytes()); bos.flush();//----->将缓冲区内容刷入文件 } //关闭 bos.close();//----->内部会调用flush方法 } }
-
-
对象流
-
对象流:ObjectOutputStream/ObjectInputStream
-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能
- readObject():从流中读取一个对象
- writeObject():向流中写入一个对象
-
使用流传输对象的过程称为序列化、反序列化
-
序列化的类必须实现Serializable接口,该接口没有任何内容,只是一个标记
-
示例(序列化):
import java.io.Serializable; public class Student implements Serializable { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student[name:" +this.name + ";age:" + this.age + "]"; } }
import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class ObjectStreamTest_1 { public static void main(String[] args) throws Exception{ //创建对象流 FileOutputStream fos = new FileOutputStream("D:\\Student_out.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); //实现序列化(写入操作) Student student = new Student("xianyun", 20); oos.writeObject(student); //关闭 oos.close(); System.out.println("序列化完毕"); } }
-
示例(反序列化):
import java.io.FileInputStream; import java.io.ObjectInputStream; public class ObjectStreamTest_2 { public static void main(String[] args) throws Exception{ //创建对象流 FileInputStream fis = new FileInputStream("D:\\Student_out.bin"); ObjectInputStream ois = new ObjectInputStream(fis); //读取文件(反序列化) Student student = (Student) ois.readObject(); //关闭 ois.close(); System.out.println(student.toString()); } }
-
- 序列化类必须实现Serializeable接口
- 序列化类中对象属性要求实现Serializable接口
- 序列化类需要初始化一个序列化版本号ID,此ID保证序列化的类和反序列化的类是同一个类
- 使用transient修饰属性,则该属性不能被序列化
- 静态属性(静态成员)不能序列化
- 序列化多个对象,可以借助集合实现
-
编码方式
- 字符编码
- ISO-8859-1收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
- UTF-8:针对Unicode码表的可变长度字符编码
- GB2312:简体中文
- GBK:简体中文、扩充
- BIG5:台湾、繁体中文
- 当编码方式与解码方式不一致时,会出现乱码
字符流
-
字符流的父类(抽象类):
- Reader:字符输入流
- public int read(){}
- public int read(char[] c){}
- public int read(char[] b, int off, int len){}
- Writer:字符输出流
- public void write(){}
- public void write(String str){}
- public void write(char[] c){}
- Reader:字符输入流
-
文件字符流
-
FileReader:
-
public int read(char[] c):从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1
-
示例
import java.io.FileReader; public class charStreamTest_1 { public static void main(String[] args) throws Exception{ //创建文件字符流 FileReader fr = new FileReader("D:\\hello.txt"); //读取 /* System.out.println("一次读取单个字符"); int data = 0; while ((data = fr.read()) != -1) { System.out.println((char) data); } */ System.out.println("通过字符缓冲区"); char[] c = new char[1024]; int count = 0; while ((count = fr.read(c)) != -1) { System.out.println(new String(c, 0, count)); } //关闭 fr.close(); } }
-
-
FileWriter:
-
public void write(String str):一次写多个字符,将b数组中所有字符,写入输出流
import java.io.FileWriter; public class charStreamTest_2 { public static void main(String[] args) throws Exception{ FileWriter fw = new FileWriter("D:\\writer.txt"); //写入 for (int i = 0; i < 10; i++) { fw.write("java是世界上最好的语言\n"); fw.flush(); } //关闭 fw.close(); } }
-
-
字符流复制文件
import java.io.FileReader; import java.io.FileWriter; public class charStreamTest_3 { public static void main(String[] args) throws Exception{ FileReader fr = new FileReader("D:\\writer.txt"); FileWriter fw = new FileWriter("D:\\writer_copy.txt"); char[] buf = new char[1024]; int count = 0; while ((count = fr.read(buf)) != -1) { fw.write(buf, 0, count); fw.flush(); } fr.close(); fw.close(); } }
- 使用FileReader和FileWriter可以复制文本文件,但不能复制图片或者二进制文件
-
-
字符缓冲流
-
缓冲流:BufferedReader/BufferedWriter
-
高效读写
-
支持输入换行符
-
可一次写一行、读一行
-
示例(输入)
import java.io.BufferedReader; import java.io.FileReader; public class BufferStreamTest_1 { public static void main(String[] args) throws Exception{ FileReader fr = new FileReader("D:\\writer.txt"); BufferedReader br = new BufferedReader(fr); /* char[] buf = new char[1024]; int data = 0; while ((data = br.read()) != -1) { System.out.println(new String(buf, 0, data)); } */ System.out.println("==========一行一行读=========="); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); } }
-
示例(输出)
import java.io.BufferedWriter; import java.io.FileWriter; public class BufferStreamTest_2 { public static void main(String[] args) throws Exception{ FileWriter fr = new FileWriter("D:\\writer_copy_2.txt"); BufferedWriter bw = new BufferedWriter(fr); for (int i = 0; i < 10; i++) { bw.write("好好学习,天天向上"); bw.newLine(); bw.flush(); } bw.close(); } }
-
-
-
打印流(PrintWriter)
- 封装了print()/println()方法,支持写入后换行
- 支持数据原样打印
-
转换流
-
桥转换流:InputStreamReader/OutputStreamWriter
-
可将字节流转换为字符流
-
可设置字符的编码方式
-
示例
import java.io.FileInputStream; import java.io.InputStreamReader; public class InputStream_Reader_test { public static void main(String[] args) throws Exception{ //创建InputStreamReader对象 FileInputStream fis = new FileInputStream("D:\\writer.txt"); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); //读取文件 int data = 0; while ((data = isr.read()) != -1) { System.out.print((char)data); } //关闭 isr.close(); } }
import java.io.FileOutputStream; import java.io.OutputStreamWriter; public class OutputStream_Writer_test { public static void main(String[] args) throws Exception{ FileOutputStream fos = new FileOutputStream("D:\\writer_3.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); for (int i = 0; i < 10; i++) { osw.write("haohaoxuexi,天天向上\n"); osw.flush(); } osw.close(); } }
-
File类
-
概念:代表物理盘符中的一个文件或者文件夹
-
方法:
- creatNewFile():创建一个新文件
- mkdir:创建一个新目录
- delete():删除文件或空目录
- exists():判断File对象所代表的对象是否存在
- getAbsolutePath():获取文件的绝对路径
- getName():获得名字
- getParent():获取文件/目录所在的目录
- isDirectory():是否是目录
- isFile():是否是文件
- length():获得文件的长度
- listFiles():列出目录中的所有内容
- renameTo():修改文件名为
-
示例(文件操作)
import java.io.File; import java.util.Date; public class FileTest { public static void main(String[] args) throws Exception { //分隔符 separator(); //文件操作 fileOpe(); } public static void separator() { System.out.println("路径分隔符" + File.pathSeparator); System.out.println("名称分隔符" + File.separator); } public static void fileOpe() throws Exception { //创建文件 File file = new File("D:\\file.txt"); System.out.println(file.toString()); if (!file.exists()) { Boolean b = file.createNewFile(); System.out.println("创建结果:" + b); } else { System.out.println("文件已存在"); } //删除文件 /*直接删除 Boolean b2 = file.delete(); System.out.println("删除结果:" + b2); */ /*使用JVM退出时删除 file.deleteOnExit(); Thread.sleep(5000);//--->休眠5秒。5秒后文件自动删除 */ //获取文件信息 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())); //判断 System.out.println("文件是否可写:" + file.canWrite()); System.out.println("是否是文件:" + file.isFile()); System.out.println("文件是否隐藏:" + file.isHidden()); } }
-
示例(文件夹操作)
import java.io.File; import java.util.Date; public class FolderTest { public static void main(String[] args) { folderOpe(); } public static void folderOpe() { //创建文件夹 File dir = new File("D:\\aaa\\bbb\\ccc"); System.out.println(dir.toString()); if (!dir.exists()) { //fol.mkdir();//---->只能创建单级目录 Boolean b1 = dir.mkdirs();//---->能创建多级目录 System.out.println("创建结果:" + b1); } else { System.out.println("文件已存在"); } //删除文件夹 /* //直接删除: System.out.println("删除结果:" + dir.delete());//--->只删除最底层文件夹,且必须是空文件夹 */ /* //使用JVM删除 dir.deleteOnExit(); */ //获取文件夹信息 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())); //判断 System.out.println("是否是文件夹:" + dir.isDirectory()); System.out.println("是否是隐藏的:" + dir.isHidden()); //遍历文件夹 //获取文件夹内容 System.out.println("==========遍历文件夹=========="); File dir2 = new File("C:\\Users\\20416\\Desktop\\学习用图"); String[] files = dir2.list(); for (String file : files) { System.out.println(file); } } }
-
FileFilter接口
-
public interface FileFilter
- boolean accept(File pathname)
-
当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取的文件进行过滤,只有满足条件的文件才可出现在listFiles()的返回值中
-
示例
import java.io.File; import java.io.FileFilter; public class FileFilterTest { public static void main(String[] args) { fileFilterTest(); } public static void fileFilterTest() { File dir = new File("C:\\Users\\20416\\Desktop\\学习用图"); System.out.println("==========FileFilter接口的使用"); File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.getName().endsWith(".png")) { return true; } return false; } }); for (File file : files) { System.out.println(file.getName()); } } }
-
集合补充——Properties
-
Properties:属性集合
-
特点:
- 存储属性名和属性值
- 属性名和属性值都是字符串类型
- 没有泛型
- 和流有关
-
示例
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.Map; import java.util.Properties; import java.util.Set; public class PropertiesTest { public static void main(String[] args) throws Exception{ //创建集合 System.out.println("==========add=========="); Properties properties = new Properties(); //添加数据 properties.setProperty("username", "张三"); properties.setProperty("age", "20"); System.out.println(properties.toString()); //遍历 System.out.println("==========keyset=========="); Set<Object> set = properties.keySet(); for (Object o : set) { System.out.println(o + ":" + properties.get(o)); } System.out.println("==========entrySet=========="); Set<Map.Entry<Object, Object>> set2 = properties.entrySet(); for (Map.Entry<Object, Object> ob : set2) { System.out.println(ob.getKey() + ":" + ob.getValue()); } System.out.println("==========stringPropertyNames=========="); Set<String> strings = properties.stringPropertyNames(); for (String string : strings) { System.out.println(string + ":" + properties.get(string)); } //和流有关的方法 System.out.println("==========list方法=========="); PrintWriter pw = new PrintWriter("d:\\print.txt"); properties.list(pw); pw.close(); System.out.println("==========store方法=========="); FileOutputStream fos = new FileOutputStream("D:\\print.properties"); properties.store(fos, "注释"); fos.close(); System.out.println("==========load方法=========="); Properties properties2 = new Properties(); FileInputStream fis = new FileInputStream("D:\\print.properties"); properties2.load(fis); System.out.println(properties2.toString()); } }