IO流
1.文件
保存数据的地方
2.文件流
文件在程序中以流的形式来操作的
流:数据在数据源(文件)和程序(内存)之间的经历的路程
输入流:数据从数据源(文件)到程序(内存)的路程
输出流:数据从程序(内存)到数据源(文件)的路程
3.文件的创建
1.方式一:new File(String pathname)//根据文件路径直接创建
public static void create01() throws IOException { String file="D:\\creat01.txt"; File file1 = new File(file); file1.createNewFile(); System.out.println("文件创建成功"); }
2.方式2:new(File parent,String child)根据父目录文件+子路径
@Test public void create02() throws IOException { File file = new File("D:\\"); String children="create02.txt"; File file1 = new File(file, children); //执行方法创建文件 file1.createNewFile();//file1还在内存中通过createNewFile();才能写入到硬盘中 }
3.new(String parent,String child)根据父目录+子路径构建
//3.new(String parent,String child)根据父目录+子路径构建 @Test public void create03 () throws IOException { String parent="d:\\"; String fileName="create03.txt"; File file = new File(parent, fileName); file.createNewFile(); }
4.获取文件信息
@Test //获取文件信息 public void Information(){ //创建文件对象 File file = new File("D:\\create03.txt"); //获取文件名 System.out.println(file.getName()); //获取绝对路径 System.out.println(file.getAbsolutePath()); //获得文件的父目录 System.out.println(file.getParent()); //文件大小 按字节计算 System.out.println(file.length()); //判断文件是否存在 System.out.println(file.exists()); //判断是不是一个文件 System.out.println(file.isFile()); //判断是不是一个目录 System.out.println(file.isDirectory()); }
5.目录操作
6.IO流的原理及分类
1.Java Io流原理
1.Input/Output,用于数据传输
2.对于数据的输入和输出操作是以流(stream)的方式进行
3.java.io包下提供各种“流”类和接口
4.输入input:读取外部数据(磁盘)到程序(内存中)
5.输出Output:将程序(内存)数据输出到磁盘等设备
2.流的分类
1.按操作的数据单位不同分为:字节流(8bit)二进制文件,字符流(按字符)文本文件
2.按数据流的流向:输入流和输出流
3.按角色分:节点流、处理流/包装流
都是抽象类
7.InputStream(字节输入流)
1.FileInputStream
1.读取D:\hello.txt 单个字节读取
@Test //读取D:\\hello.txt public void read01() throws IOException{ File file = new File("D:\\hello.txt"); FileInputStream fileInputStream = new FileInputStream(file); int readDate=0; //从此输入流中读取一个数据字节。 while ((readDate=fileInputStream.read())!=-1){ System.out.printf("%c",(char)readDate); } //关闭文件流释放资源 fileInputStream.close(); }
优化
@Test //读取D:\\hello.txt public void read02() throws IOException{ File file = new File("D:\\hello.txt"); FileInputStream fileInputStream = new FileInputStream(file); int readLen=0; byte [] buf=new byte[8]; //从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。 while ((readLen=fileInputStream.read(buf))!=-1){ //将字节转化为字符串 System.out.println(new String(buf,0,readLen)); } fileInputStream.close(); }
8.OutputStream(字节输出流)
1.FileOutputStream
@Test public void write01() throws IOException { String path="D:\\a.txt"; File file = new File(path); //当没有a.txt文件时会自动创建 FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write('c'); System.out.println("写入成功"); fileOutputStream.close(); }@Test public void write02() throws IOException { String path="D:\\a.txt"; File file = new File(path); String str="hello"; //当没有a.txt文件时会自动创建 //不会将之前的文件内容覆盖,而是在之前文件内容后面追加 FileOutputStream fileOutputStream = new FileOutputStream(file,true); fileOutputStream.write(str.getBytes(),0,str.length()); System.out.println("写入成功"); fileOutputStream.close(); }
9.文件拷贝
//将D:\\1.png 拷贝到E盘 @Test public void fileCopy() throws IOException { //创建路径 String srcPath="D:\\1.png"; String destPath="E:\\1.png"; //创建文件输入流对象 FileInputStream fileInputStream = new FileInputStream(srcPath); //创建文件输出流对象 FileOutputStream fileOutputStream = new FileOutputStream(destPath); //定义一个字节提高读取效率 byte []buf=new byte[1024]; int readLen=0; while((readLen=fileInputStream.read(buf))!=-1){ //一边读一边写 fileOutputStream.write(buf,0,readLen); } System.out.println("拷贝完毕"); //关闭资源 if(fileInputStream!=null){ fileInputStream.close(); } if (fileOutputStream!=null){ fileOutputStream.close(); } }
10.文件字符流的说明
注意:FileWriter使用后,必须要关闭(close)或者刷新(flush),否则写入不到指定的文件
11.FileReader
//读取test.txt 编码格式为UTF-8 @Test public void testReader() { //创建读取路径 String path="D:\\test.txt"; FileReader fileReader = null; //通过一个字符一个字符的读取 int data=0; try { fileReader = new FileReader(path); while ((data=fileReader.read())!=-1){ System.out.print((char)data); } } catch (IOException e) { e.printStackTrace(); }finally { //关闭资源 try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("读取ok"); }@Test public void testReader2() { //创建读取路径 String path = "D:\\test.txt"; FileReader fileReader = null; int len = 0; char[] buf = new char[8]; try { fileReader = new FileReader(path); while ((len = fileReader.read(buf)) != -1) { System.out.print(new String(buf, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("读取ok"); }
12.FileWriter
@Test public void testWriter() throws IOException { String path="D:\\note.txt"; FileWriter fileWriter = new FileWriter(path,true); fileWriter.write("风雨过后就是彩虹"); //FileWriter使用后,必须要关闭(close)或者刷新(flush),否则写入不到指定的文件 fileWriter.close(); }
13.节点流和处理流
1.节点流可以从一个特定的数据源读写数据,如FileWriter、FileReader
2.处理流(也叫包装流)是”连接“在已存在的流(节点流或处理流)之上,为程序提供更强大的读写功能。BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流是可以任意的,只要是Reader子类
节点流和处理流的区别和联系
1.节点流是底层流/低级流,直接跟数据源相连接
2.处理流(包装流)包装节点流,既可以消除不同节点流之间的差异,也可以提供更方便的方法来完成输入、输出
3.处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
处理流的功能主要体现在以下两个方面
1.性能高:主要以增加缓冲的方式来提高输入、输出的效率
2.操作便捷:处理流可以提供一系列便捷的方法来一次输入、输出大批量的数据,使用方便更加灵活
14.BufferReader
1.按行读取
@Test public void testBufferReader() throws IOException { String path="D:\\test.txt"; FileReader file = new FileReader(path); BufferedReader bufferedReader = new BufferedReader(file); //进行按行读取 String line; while((line=bufferedReader.readLine())!=null){ System.out.println(line); } //关闭资源,底层会自动关闭节点流 bufferedReader.close(); }
15.BufferWriter
@Test public void test01() throws IOException { String path="D:\\note.txt"; /*public void newLine()throws IOException 写如一行*/ FileWriter fileWriter = new FileWriter(path); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.newLine();//写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 ('\n') 符。 bufferedWriter.write("hello",0,2); //关闭资源 bufferedWriter.close(); }
16.Buffer拷贝
不要去操作二进制文件如声音、视频、二进制文档 如果操作会造成文件损坏
/* * 将D:\\test.text拷贝到E:\\test.text * */ @Test public void copy() throws IOException { String srcPath="D:\\test.txt"; String destPath="E:\\test.text"; FileReader fileReader = new FileReader(srcPath); FileWriter fileWriter = new FileWriter(destPath); BufferedReader bufferedReader = new BufferedReader(fileReader); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); String line; //按行读取 while((line=bufferedReader.readLine())!=null){ //每次写之前前进行换行 bufferedWriter.newLine(); bufferedWriter.write(line); } //关闭资源 if (bufferedWriter!=null){//bufferedWriter不等于null,才有关闭流的可能;一定要对此进行判断 bufferedWriter.close(); } if (bufferedReader!=null){ bufferedReader.close(); } System.out.println("拷贝完毕"); }
17.字节处理流
二进制文件的拷贝
/* 对二进制文件进行处理 将D:\Love Story.m4a拷贝到E:\Love Story.m4a */ @Test public void copy() throws IOException { String src="D:\\Love Story.m4a"; String dest="E:\\Love Story.m4a"; FileInputStream fileInputStream = new FileInputStream(src); FileOutputStream fileOutputStream = new FileOutputStream(dest); BufferedInputStream bs = new BufferedInputStream(fileInputStream); BufferedOutputStream bo=new BufferedOutputStream(fileOutputStream); int data=0; byte[]buf=new byte[8]; while ((data=(bs.read(buf)))!=-1){ bo.write(buf); } if(bs!=null){ bs.close(); } if(bo!=null){ bo.close(); } }
18.对象流
ObjectInputStream和ObjectOutputStream
序列化和反序列化
1.序列化:在保存数据时,保存数据的值和保存数据的类型
2.反序列化:在恢复数据时,恢复数据的值和类型
3需要让某个对象支持序列化机制,则必须让其可序列化,该类必须实现两个接口之一: Serializable//这是一个标记接口,没有方法
Externalizable//该接口有实现方法
1.ObjectOutPutStream
public static void main(String[] args) throws IOException { //序列化数据到data.txt String pathClass="D:\\data.txt"; //节点流 直接操作数据 FileOutputStream fileOutputStream = new FileOutputStream(pathClass); //包装节点流 ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream); oos.write(100);//int=>Integer(Integer实现了Serializable) oos.close(); }
2.ObjectInputStream
public static void main(String[] args) throws IOException { //反序列化的文件 String pathClass="D:\\data.txt"; FileInputStream fileInputStream = new FileInputStream(pathClass); ObjectInputStream ois = new ObjectInputStream(fileInputStream); //读取反序列化的顺序要和你保存反序列化的顺序一致 System.out.println(ois.readInt()); ois.close(); }
3.注意事项
1.序列化和反序列化时读写顺序一致
2.要求序列化或反序列化对象,需要实现Serializable
3.序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
4.序列化对象时默认将里面的所有属性都进行序列化,但除了static或transient修饰的成员
5.序列化对象时要求属性的类型也需要实现序列化接口
6.序列化具备可继承性,也就是如果某类已经实现了序列化,则他所有的子类已经默认实现序列化
19.标准输入输出流
标准输入流:
编译时期:InputStream 运行时期:BufferInputStream
20.转换流
可以解决乱码问题,指定编码方式
1.InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
//将fileInputStream转换成InputStreamReader public class InputStreamReader_ { public static void main(String[] args) throws IOException { String path="E:\\a.txt"; //将FileInputStream转化成InputStreamReader //设置对应的编码集 InputStreamReader isr = new InputStreamReader(new FileInputStream(path), "gbk"); BufferedReader bufferedReader = new BufferedReader(isr); //读取 String line = bufferedReader.readLine(); //关闭外层流 System.out.println(line); bufferedReader.close(); } }
2.OutPutStreamWriter:Writer的子类,实现OutputStream(字节流)包装成Writer(字符流)
3.当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题
public class OutputStreamWriter_ { public static void main(String[] args) throws IOException { String path="E:\\b.txt"; FileOutputStream fileOutputStream = new FileOutputStream(path); OutputStreamWriter ost = new OutputStreamWriter(fileOutputStream, "gbk"); BufferedWriter bw = new BufferedWriter(ost); bw.write("你好李焕英"); System.out.println("ok"); //关闭外层资源 bw.close(); } }
4.可以在使用时指定编码格式
21.打印流
PrintStream和PrintWriter
public class PrintStream_ { public static void main(String[] args) throws IOException { PrintStream out=System.out; //在默认情况下,PrintStream输出数据的位置是显示器 /*public void print(String s) { if (s == null) { s = "null"; } write(s); }*/ out.print("hello "); //因为print底层使用的是write,所以我们可以直接调用writer进行打印输出 out.write("hello".getBytes()); out.close(); //可以去修改打印流输出的位置 /* * 1.输出修改到"E:\\t.txt" * 2."hello"也会输出到"E:\\t.txt" * 3. public static void setOut(PrintStream out) { checkIO(); setOut0(out); } * */ System.setOut(new PrintStream("E:\\t.txt")); System.out.println("hello"); } }
public class PrintWriter_ { public static void main(String[] args) throws IOException { PrintWriter writer = new PrintWriter(new FileWriter("E:\\t2.txt")); writer.print("hello"); writer.close();//flush+关闭流,才会将数据写入到文件 } }
22.properties
1.文件格式
键值对形式存在
2.注意
键值对不需要有空格,值不需要用引号引起来,默认类型是String
3.常见方法
public class Properties_ { public static void main(String[] args) throws Exception { //使用properties读取文件 //加载该文件 Properties pro = new Properties(); pro.load(new FileReader("src\\jdbc.properties")); // 输出 pro.list(System.out); //根据key获取value String property = pro.getProperty("jdbc.url"); System.out.println(property); } }public class Properties_2 { public static void main(String[] args) throws IOException { //Properties底层是HashTable //创建properties文件 Properties properties = new Properties(); properties.setProperty("hello","45"); properties.setProperty("1","123"); //第二个参数指的是生成文件注释 properties.store(new FileWriter("src\\jdbc2.properties"),null); System.out.println("创建完毕"); } }