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("保存配置文件成功");
    }
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号