JAVA IO流

 JAVA IO流总结

 一.文件

      文件就是存储数据的地方,保存图片,视频,声音等。

      1.1 文件流

      文件在程序中都是以流的形式来操作的。

      流:数据在数据源和程序之间经历的路劲

      输入流:数据从数据源到程序(内存)的路径

      输出流:数据从程序到数据源(文件)的路径

      

      1.2常用的文件操作  

       1.2.1 创建文件对象,使用相关方法

     

1 //构建文件对象相关方法
2 new File(String pathname)
3 new File(File parent,String child)
4 new File(String parent,String child)
5 //调用方法
6 file.createNewFile()  //构建新文件

          

           /*  应用案例演示  */

  

 1 //创建文件
 2 public class demo1 {
 3     public static void main(String[] args) {
 4 
 5     }
 6     //方式1 new File(String pathname)  
 7     public void create01(){
 8         String filePath="e:\\news1.txt";
 9         File file=new File(filePath);
10         try { 
11             file.createNewFile();
12             System.out.println("文件创建成功");
13         } catch (IOException e) {
14             e.printStackTrace();
15         }
16     }
17 
18     //方式2
19     public void create02(){
20         File file = new File("e:\\");
21         String fileName="news2.txt";
22         File file1 = new File(file, fileName);
23         try {
24             file1.createNewFile();
25         } catch (IOException e) {
26             e.printStackTrace();
27         }
28     }
29 
30     //方式3
31     public void create03(){
32         String parentPath="e:\\";
33         String  fileName="news3.txt";
34         File file = new File(parentPath, fileName);
35         try {
36             file.createNewFile();
37         } catch (IOException e) {
38             e.printStackTrace();
39         }
40     }
41 }

           

            1..2.2 获取文件的相关信息,File的相关方法

      

      

@Test
public void method01(){
   File file=new File("e:\\a.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());  //是不是一个目录

}

        1.2.3 目录的操作和文件删除

        mkdir() 方法:创建一级目录

        mkdirs() 方法:创建多级目录

        delete 删除空目录或文件

  二.IO流原理、流的分类

         2.1.1 Java IO流原理

          1. I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。

           2.Java程序中,对输入输出操作以“流(stream)”的方式进行。

           3.输入input:读取外部数据

           4.输出output:将程序数据输出到磁盘,光盘等存储设备中

          2.1.2  分类

          字节流:8bit 二进制文件,字符流(按字符)文本文件

          分为:输入流,输出流

          按流的角色的不同分为:节点流,处理流/包装流

          

抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

           

           

        

         2.2.1FileInputStream 字节输入流介绍

             

@Test
 public void readFile(){
  String filePath="e:\\a.txt";
  int readLine=0;
  FileInputStream fileInputStream=null;
  try {
            //创建FileInputStream对象,用于读取文件
          fileInputStream=new FileInputStream(filePath);
           //从该输入流读取一个字节的数据,如果没有输入可用,此方法将阻止
            //如果返回-1,表示读取完毕
            while((readData=fileInputStream.read())!=-1){
                System.out.println((char)readData);//转成char形式
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭文件流,释放资源。
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  
}
/**
      使用  int read(byte[] b)方法提高效率
     */
@Test
  public void readFile01()
{
   byte[] buf =new byte[16]  //一次读取16个字节
   int readLen=0;
   FileInputStream fileInputStream=null;
   try{
   //创建FileInputStream对象,用于读取文件
    fileInputStream =new FileInputStream(filePath);
    //从该输入读取最多buf.length字节的数据到字节数组中
            //如果返回-1,表示读取完毕
            //如果读取正常,该方法将返回实际读取的字节数
            //   int read(byte[] b)
    while((readLen=fileInputStream.read(buf))!=-1){
    System.out.println(new String(buf,0,readLen));//转成char形式
}
   catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭文件流,释放资源。
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}
}

 

        2.2.2FileOutputStream 字节输出流介绍

                 案例1演示:在文件中写入字符串

 /**
     * 演示使用FileOutPutStream 将数据写入hello文件中
     */
    public void m3() {
        FileOutputStream fileOutputStream = null;
        String filePath = "e:\\a.txt";

        try {
            //1.new FileOutputStream(filePath)创建方式,当写入内容是,会覆盖原来内容
            //2.new FileOutputStream(filePath,true)是追加内容
            fileOutputStream = new FileOutputStream(filePath, true);
            fileOutputStream.write('a');//写入一个字节

            //写入字符串
            String str = "hello";
            //str.getBytes() 方法可以把字符串转成字符数组
            fileOutputStream.write(str.getBytes());

            //方法3.
            fileOutputStream.write(str.getBytes(), 0, str.length());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

         

             案例2:完成对图片/音乐的拷贝

    

@Test
public void fileCopy(){
    //   文件拷贝
        //1.创建文件输入流,将文件读入到程序
        //2.创建文件输出流,将读取到的文件数据,写入到指定文件
        FileInputStream fileInputStream=null;
        FileOutputStream fileOutputStream=null;
        String filePath="d:\\1.png";
        String filePath1="e:\\1.png";
        // 创建字节数组
        byte[] a=new byte[1024];
        int readLen=0;
        try{
         fileInputStream=new FileInputStream(filePath);
            fileOutputStream=new FileOutputStream(filePath1);
         while((readLen=fileInputStream.read(a))!=-1){
         //读取到后,就写入到文件,通过输出流对象
                //边读取边写
                fileOutputStream.write(a,0,readLen);
 }
          
}catch(IOException e){
  e.printStackTrace();
}
finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

 

         2.3 FileReader和FileWriter介绍

         2.3.1 FileReader相关方法:

            1) new FileReader(File/String)

            2) read:每次读取单个字符,返回该字符,如果到文件末尾返回-1

            3)read(char[]):批量读取多个字符到数组

            相关API:

            1)new String(char[]):将char[] 转换成String

            2)new String(char[] ,off,len):将char[] 的指定部分转换成String

 /**
         * 字符数组获取文件
         */
        String filePath="e:\\story.txt";
        FileReader fileReader=null;
        //1.创建FileReader对象
        int readLen=0;
        byte[] buf=new byte[1024];
        try {
            fileReader=new FileReader(filePath);
            //循环读取 使用read方法
            while((readLen=fileReader.read(buf))!=1){
                System.out.println(new String(buf,0,readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//关闭
            if(fileReader!=null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

            2.3.2 FileWriter相关方法:

            1)new FileWriter(File/String):覆盖模式,相当于流的指针在首端

            2) new FileWriter(File/String,true):追加模式,相当于流的指针在尾端

            3)write(int):写入单个字符

            4) write(char[]):写入指定数组

            5)write(char[],off,len):写入指定数组的指定部分

             6)wirte(string)

             7)write(string,off,len):写入字符串指定部分

             相关API:

              String类:toCharArray:将String转成char[]

                注意:FileWriter使用后,必须close或者flush。

      

 public static void main(String[] args) {
        String filePath="e:\\note.txt";
        FileWriter fileWriter=null;
        char[] chars={'a','b','c'};
        try {
            fileWriter=new FileWriter(filePath);
            //1.write(int) 写入单个字符
            fileWriter.write('魏');
            //2.write(char[])写入指定数组
            fileWriter.write(chars);
            //3.write(char[],off,len) :写入指定数组的指定部分
            fileWriter.write("魏沛然加油".toCharArray(),0,6);
            //4.write(string)
            fileWriter.write("你好世界");
            //5.write(string,off,len)
            fileWriter.write("helloWorld",0,6);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //fileWriter一定要关闭流,close,或者flush
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

        2.4 节点流和处理流

        2.4.1基本介绍

         1.节点流可以从一个特定的数据源读写数据,如FileReader,FileWriter

          2.处理流也叫包装流,如BufferedReader,BufferedWriter

         2.4.2 节点流和处理流的区别和联系

          1.节点流是底层流/低级流,直接跟数据源相连。

          2.处理流(包装流)包装节点流

   

          

package demo18io;
/*
用BufferedReader读取文本文件
*/
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class BufferedReader_ { public static void main(String[] args) throws IOException { String filePath="e:\\a.java"; //创建bufferedReader BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)); //读取 String line; //1.bufferedReader.readLine() 是按行读取文件 //2.当返回null时,表示文件读取完毕 while ((line=bufferedReader.readLine())!=null){ System.out.println(line); } //关闭流,只需要关闭BufferedReader,因为底层会自动去关闭节点流 bufferedReader.close(); } }

 

            

package demo18io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/*
用BufferedWriter写入字符串
 */
public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath="e:\\ok.txt";
        //创建BufferedWriter
        //1.new FileWriter(filePath,true)//表示以追加的方式写入
        //2.new FileWriter(filePath)//表示以覆盖的方式写入
        BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(filePath));
        bufferedWriter.write("hello");
        bufferedWriter.newLine();//插入一个和系统相关的换行
        //关闭外层流
        bufferedWriter.close();
    }
}

 

package demo18io;

import java.io.*;
/*
   综合使用BufferedReader和BufferedWriter完成文本文件拷贝
 */
public class BufferedCopy_ {
    public static void main(String[] args) {
        //1.BufferedReader和BufferedWriter是安装字符操作
        //2.不要去操作二进制文件,可能造成文件损坏
        String srcFilePath="e:\\a.java";
        String destFilePath="e:\\a1.java";
        BufferedReader br=null;
        BufferedWriter bw=null;
        String line;
        try {
            br=new BufferedReader(new FileReader(srcFilePath));
            bw=new BufferedWriter(new FileWriter(destFilePath));
            while ((line=br.readLine())!=null){
                //每读取一行,就写入
                bw.write(line);
                bw.newLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (br!=null){
                    br.close();
                }
                if (bw!=null){
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

 

 

 

             *介绍BufferedInputStream

               BufferedInputStream是字节流,在创建BufferedInutStream时,会创建一个内部缓冲区数组

               *介绍BufferedOutputStream

                 BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

                  演示:

               

package demo18io;

import java.io.*;

public class BufferedCopy02 {
    public static void main(String[] args) throws FileNotFoundException {
        String srcFilePath="e:\\a.java";
        String destFilePath="e:\\a3.java";
        //创建BufferedOutputStream对象,BufferedInputStream对象
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;

        try {
            //因为FileInputStream是InputStream子类
            bis=new BufferedInputStream(new FileInputStream(srcFilePath));
            bos=new BufferedOutputStream(new FileOutputStream(destFilePath));
            //循环读取文件,并且写入到destFilePath
            byte[] buff =new byte[1024];
            int readLen=0;
            //当返回-1时,就表示文件读取完毕
            while ((readLen=bis.read(buff))!=-1){
                bos.write(buff,0,readLen);
            }
            System.out.println("文件拷贝完毕");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            bis.close();
            bos.close();
        }

    }
}

 

           2.6 对象流- ObjectInputStream和ObjectOutputStream

             1.将int num=100 这个int数据保存到文件中,注意不是100数字,而是int 100,并且能够从文件中

               直接恢复int 100

            2.将Dog dog=new Dog("小黄",3)这个dog对象保存到文件中,并且能够从文件恢复

            3.上面两个要求,就是能够将基本数据类型或者对象进行序列化和反序列化操作

            ** 序列化和反序列化

          1.序列化就是在保存数据时,保存数据的值和数据类型

             2.反序列化就是在恢复数据时,恢复数据的值和数据类型

             3.需要让某个对象支持序列化机制,就必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

                   *Serializable  //标记接口,没有方法 

                .  *Externalizable //该接口有方法需要实现,因此我们一般实现上面的Serializable接口  

 

  3.1.1  对象流介绍

             功能:提供了对基本类型或对象类型的序列化和反序列化的方法

             ObjectOutputStream 提供序列化功能

             ObjectInputStream 提供反序列化功能

             演示:

 

public class Object_1 {
    public static void main(String[] args) throws IOException {
        String filePath="e:\\data.dat";
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据到e:\data.dat
        objectOutputStream.writeBoolean(true);
        objectOutputStream.writeChars(String.valueOf('s'));
        objectOutputStream.writeDouble(2.0);
        objectOutputStream.writeUTF("魏沛然");
         
    }
}

 

  使用ObjectInputStream读取data.dat并反序列化恢复数据

//1.创建流对象
  ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src\\data.dat"));
  //2.读取,注意顺序,要与序列化的顺序一致
    System.out.println(ois.readInt());
    System.out.println(ois.readBoolean());
    //3.关闭
    System.out.println(”以反序列化的方式读取okk“);

 

 

* 注意事项和细节说明

1)读写顺序要一致

2)要求序列化或反序列化对象,需要实现Serializable

3)序列化的类中建议添加SerialVersionUID,为了提高版本兼容性

4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员

5)序列化对象时,要求里面属性的类型也需要实现序列化接口

6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

 

4.1.1  标准输入输出流

System.in 标准输入           InputStream 类型          默认设备:键盘

System.out标准输出          PrintStream 类型          默认设备:显示器

  //System类的public final static InputStream in =null;
        //System.in 编译类型 InputStream
        //System.in 运行类型 BufferedInputStream
        System.out.println(System.in.getClass());

        //System.out public final static PrintStream out=null;
        // 编译类型 PrintStream
        // 运行类型 PrintStream
        System.out.println(System.out.getClass());

    

 

5.1.1转换流-InputStreamReader 和 OutputStreamWriter

   由文件乱码问题,引出了转换流

   

public static void main(String[] args) throws IOException{
              //读取e:\\a.txt文件到程序
              //思路
              //1.创建字符输入流 BufferedReader[处理流]
              //2.使用BufferedReader对象读取
              //默认情况下,读取文件安装utf-8编号,一个文字为三个字节
                 String filePath="e:\\a.txt";
        BufferedReader br=new BufferedReader(new FileReader(filePath));

        String s=br.readLine();
        System.out.println("读取的内容: "+ s);
        br.close();
}

 

*转换流介绍

1.InputStreamReader:Reader的子类,可以将InputStream(字节流)包装乘Reader字符流

2.OutputStreamWriter:Writer的子类,实现将OutputStream字节流包装成Writer字符流

3.当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题

4.可以在使用时指定编码格式(utf-8,gbk,gb2312,ISO8859-1等)

应用实例:

/**
 演示使用InputStreamReader转换成解决中文乱码问题
 将字节流FileInputStream转成字符流InputStreamReader,指定编码gbk/utf-8
 */
public class InputStreamReader_1 { public static void main(String[] args)throws IOException { String filePath="e:\\a.txt"; //1.吧FileInputStream转成InputStreamReader //2.指定编码gbk InputStreamReader isr=new InputStreamReader(new FileInputStream(filePath),"gbk"); //3.把InputStreamReader传入BufferedReader BufferedReader bf=new BufferedReader(isr); //4.读取 String s=bf.readLine(); System.out.println(s); //关流 bf.close(); } }

/*
实例2:将字节流FileOutputStream包装成字符流OutputStreamWriter,对文件进行写入
(按照gbk格式,可以指定其他,比如utf-8)
*/
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d:\\a.txt","gbk"));
//写入
osw.write("hello");
//3.关闭
osw.close();

 

6.1.1 打印流-PrintStream 和PrintWriter

       注意:打印流只有输出流,没有输入流

package demo18io;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * 打印流-PrintStream和PrintWriter
 * -打印流只有输出流,没有输入流
 */

public class PrintStream_1 {
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;
        //在默认情况下,printStream 输出数据的位置是 标准输出,即显示器
        out.print("打印流");
        //因为print底层使用的是write,所以可以直接调用write进行打印输出
        out.write("hello".getBytes());
        out.close();

        //可以修改打印流输出的位置
        System.setOut(new PrintStream("e:\\ti.txt"));


        PrintWriter printWriter=new PrintWriter(System.out);
    }
}

 

7.1.1 Propertise类

      看一个需求

       如下一个配置文件mysql.propertise

        ip=192.168.0.13

        user=root

       pwd=12345

       请问编程读取ip,pwd,user的值是多少

      

package demo18io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InaccessibleObjectException;

/*  Properties类
   properties读文件  配置文件
   1)专门用于读写配置文件的集合类
      配置文件格式:
      键=值
      键=值
   2)注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String
   3)Properties常用方法
      load:加载配置文件的键值对到Properties对象
      list:将数据显示到指定设备
      getProperty(key):根据键获取值
      setProperty(key,value):设置键值对到Properties对象
      store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,
      如果有中文,会存储为unicode码
 */
public class Properties_1 {//传统方法

    public static void main(String[] args) throws IOException {
        //读取mysql.properties文件,并且获取相应的IP等信息
        BufferedReader bufferedReader = new BufferedReader(new FileReader("src\\mysql.properties"));
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            String[] split = line.split("=");
            System.out.println(split[0]+split[1]);

        }

        bufferedReader.close();
    }
}

 

 *基本介绍

Properties类
   properties读文件  配置文件
   1)专门用于读写配置文件的集合类
      配置文件格式:
      键=值
      键=值
   2)注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String
   3)Properties常用方法
      load:加载配置文件的键值对到Properties对象
      list:将数据显示到指定设备
      getProperty(key):根据键获取值
      setProperty(key,value):设置键值对到Properties对象
      store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,
      如果有中文,会存储为unicode码

应用实例:
使用Properties来读取mysql文件

package demo18io;

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class Properties_2 {
    public static void main(String[] args) throws IOException {
        //使用Properties来读取mysql文件

        Properties properties = new Properties();
        //加载指定配置文件
        properties.load(new FileReader("src\\mysql.properties"));

        //把k-v对显示到控制台
        properties.list(System.out);//list(里面可以添加打印流)

        //根据键获取对应的值
        String user =properties.getProperty("user");
        String pwd=properties.getProperty("pwd");
        System.out.println(user);
        System.out.println('\n'+ pwd);
    }
}

应用实例:

使用Properties来创建配置文件,修改配置文件内容

public class Properties_3 {
    public static void main(String[] args) throws IOException {
        //使用Properties来创建配置文件,修改配置文件内容
        Properties properties = new Properties();
        //创建
        properties.setProperty("charset", "utf-8");
        properties.setProperty("user", "汤姆");
        properties.setProperty("pwd", "abc111");

        //将k-v存储文件中即可
        properties.store(new FileOutputStream("F:\\project\\basic-code\\day01-code\\src\\mysql2.properties"),null);
        System.out.println("保存配置文件成功");

    }
}

 



 

posted @ 2021-09-06 17:13  小魏子~  阅读(71)  评论(0)    收藏  举报