JavaI/O流【笔记】

I/O流

1、什么是I/O流

​ I:input输入

​ O:output输出

​ 输入/输出流(读写文件/数据)

2、I/O分类

1、按照数据的处理格式
  • 字节流:处理二进制数据(图片/音频/视频/…)
    • InputStream:字节输入流
    • OutputStream:字节输出流
  • 字符流:处理字符(txt/…)
    • Reader:字符输入流
    • Writer:字符输出流
2、按照数据的流向

​ 输入流

​ 输出流

注意:如何判断使用输入流还是输出流?

以程序为参照物,观察数据的流向,如果数据流向程序,使用输入流,如果数据从程序流出,使用输出流

3、字节流

1、字节输入流
  • InputStream :抽象类
    • FileInputStream :操作文件(重点)
    • BufferedInputStream:字节缓冲流( 了解)
1、InputStream常用方法
  • int read()读一个(效率低)
  • int read(byte[] b)读多个(提高效率)
  • int read(byte[] b,int off,int len)
  • void close()关闭

FileInputStream读文件的步骤

​ 1、找到目标文件(路径)

​ 2、和目标文件建立数据通道(流)

​ 3、读文件 read()

​ 4、关闭通道(释放资源)

BufferedInputStream读文件的步骤

​ 1、找到目标文件(路径)

​ 2、和目标文件建立数据通道(流)

​ 3、建立缓冲流数据通道

​ 4、使用缓冲流读数据

​ 5、关闭缓冲通道(释放资源)

 public static void main(String[] args) {
        //1、读取文件
        //(1)找到目标文件
        String path = "C:\\Users\\贺天\\Desktop\\a.txt";
        FileInputStream in = null;//in是局部变量,局部是没有初始值,必须要给初始值

        try {
            //(2)和目标文件建立输入流通道
            in = new FileInputStream(path);
            //(3)读取文件内容
            //1、read():读一个,读取的内容是-1,代表读完了
            
            int content=0;//定义变量,保存赢取内容
            //循环
            //(content=inread()):读取一个字节,保存到变量content中
            while((content = in.read())!=-1){//如果读取的内容不是-1
                //没有读完
                System.out.print((char)content);//打印读取内容
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                //(4)关闭通道
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
   

FileNotFundException:找不到文件异常

字节流去读取字符:有可能出现乱码

//read(byte b)
//读取文件内容
String path = "C:\\Users\\贺天\\Desktop\\a.txt";
        FileInputStream in = null;//in是局部变量,局部是没有初始值,必须要给初始值
try {
            //(2)和目标文件建立输入流通道
            in = new FileInputStream(path);
//缓冲数组
byte[] buf = new byte[1024*8];//默认8字节
int length = 0;//定义变量,保存读取长度
//循环
//(length = in.read(buf)):读取内容保存到缓冲数buf中,length代码读取长度
while((length = in.read(buf))!=-1){//如果读取的长度为-1,读完了
    //没有读完
    System.out.println(Arrays.toString(buf));
}
    catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                //(4)关闭通道
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
//读文件:缓冲字节输入流(仅做了解,实际用不上)
//注意:缓冲流不具备读写能力,要依赖具备读写能力的流
public static void main(String[] args){
    long startTime = System.currentTimeMillis();
    //(1)找目标文件 
    String path ="\\\";
    //(2)建立数据通道
        fileInputStream in = null;
    try{
        in = new FileInputStream(path);   
    //(3)创建缓冲流通道    
    BufferedInputStream bufIn = new  BufferedInputStream(in);
    //(4)使用缓冲流读数据
         byte[] buf = new byte[1024 * 8];
        int length = 0;//定义变量,保存读取长度
        while((length = bufIn.read(buf))!=-1){
            System.out.println(Arrays.toString(buf));
        }
         }catch(Exception e){
        e.printStackTrace();
    }finally{
        //(5)释放资源
        in.close();
    }
    
}
2、字节输出流
  • OutputStream :抽象类
    • FileOutputStream :
1、FileOutputStream常用方法

write(int b):写一个

write(byte[] b):写多个

write(byte[] b,int off,int len)

close():关闭

2、写数据步骤:

1、找到目标文件

2、建立数据通道

3、使用通道写数据

4、关闭通道

//写数据 write(int b)
public static void test1(){
    //(1)找到目标文件 
    String path = "C:\Users\贺天\Desktop\b.txt";
    try{
        //(2)建立数据通道
    FileOutputStream out = new FileOutputStream(path,true);//true:拼接;加false:覆盖(默认)
    //(3)使用通道写数据
    out.write("hello world".getBytes());//字符串转字节数组
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //(4)关闭通道
        out.close();
    }
    
    
    
}
注意:stream:字节/二进制

​ input:输入

​ output:输出

​ Buffered:缓冲

3、拷贝图片:边读边写
write(byte b[] ,int off,int len)
    b:要写的数组
        off:偏移量,从数组那个位置开始写(一般是0)
            len:要读取的长度

注意:使用字节流去写字符要手动进行编码,然后再写

4、字符流

读写字符

字符流:字节流+编码/解码(字符流:直接去写字符)

编码:把能看懂的字符转换成看不懂的二进制数据

解码:把看不懂的二进制数据转换成能看懂的字符

1、读数据
  • Reader
    • FileReader
    • BufferedReader
      • String readLine() 每次读一行,注意:不会读取换行操作
public static void main(String[])throws Exception{
    //1、找到目标文件,建立数据通道
    FileReader reader = new FileReader("\\");
    //2、读取数据
    //定义变量,保存读取内容
    int content = 0;
    //循环:不停地去读
    while((content = reader.read())!=-1){
        System.out.println((char)content);
    }
        //3关闭通道
        reader.close();
}

使用缓冲数组(效率高)

public static void main(String[])throws Exception{
    //1、找到目标文件,建立数据通道
    FileReader reader = new FileReader("\\");
    //2、读取数据
    //定义缓冲数组
    char[] buf = nwe char[1024*8];
    //定义变量,保存每次读取长度
    int length = 0;
    //循环:不停地去读
    while((length = reader.read())!=-1){
        System.out.println(new String(buf,0,length);
    }
        //3关闭通道
        reader.close();
}
//读数据,使用缓冲类
//注意:使用缓冲类不能直接读写数据
public static void main(String[] args)throws Exception{
    //1、找到目标文件,建立数据通道
     FileReader reader = new FileReader("\\");
    //2、创建缓冲类
    BufferedReader bufReader = new BufferedReader(reader);
    //3、使用bufferedReader读取数据
    //定义字符串,保存每次读取内容
    String content = "";
    //循环读取
    while((content = bufReader.readLine())!=null){
        System.out.print(content+"\r\n");//content:每次读取一行的数据,不再换行,需要手动加上换行
        
    }
    //4、关闭缓冲类,关闭数据通道
    bufReader.close();
    reader.close();
}
2、写数据
  • Writer
    • FileWriter
    • BufferedWriter
//不用缓冲类写数据
public static void main(String[])throws Exception{
    //1、找到目标文件,建立数据通道
    FileWriter reader = new FileWriter("\\");
    //2、使用通道写数据
    writer.write("hello world,你好!");
    //3关闭通道
    reader.close();
}
//使用缓冲类写数据
public static void main(String[] args)throws Exception{
    //1、找到目标文件,建立数据通道
    FileWriter writer = new FileWriter("\\");
    //2、创建缓冲类通道
        BufferedWriter buf = new BufferedWriter(writer);
    //3、使用通道写数据
    bufferedWriter.write("hello world,你好!");
    //4、关闭通道
    bufferedWriter.close();
}
3、拷贝文件
public static void main(String[] args)throws Exception{
    //1、找到目标文件,建立数据通道、创建缓冲通道
    BufferedReader bufReader = new BufferedReader(new FileReader("\\"));
    //2、和目标文件建立通道:输出
    BufferedWriter bufWriter = new BufferedWriter(new FileWriter("\\"));
    //3、循环
    //定义变量保存读取内容
    Sting consent = "";
    while((consent =bufReader.readLine())!=null){
        bufWriter.writer(consent+"\r\n");//换行方案一
        //bufWriter.write(consent);
        //bufWriter.newLine();//方案二
    }
    //4、关闭通道
    bufReader.close();
    bufWriter.close();
}

5、转换流

把字节流转换成字符流

(1)输入字节流转成字符流
public static void main(String[] args)throws Exception{
    //(1)字节流
    FileInputStream in = new FileInputStream("\\");
    //(2)转字符流
    InputStreamReader reader = new InputStreamReader(in);
    //创建缓冲数组
    char[] buf = new char[1024*8];
    //定义变量保存每次读取长度
    int length = 0 ;
    //循环
    while((length= reader.read(buf))!=null){
        System.out.println(new String(buf,0,length));
    }
    reader.close();
}
(2)输出字节流转成字符流
public static void main(String[] args)throws Exception{
    //(1)字节流
    FileOutputStream out = new FileOutputStream("\\");
    //(2)转字符流
    InputStreamWriter writer = new OutputStreamReader(out);
    writer.write("hello world");
    //(3)关闭通道
    writer.close();
}

6、对象流

读写java对象()

序列化:把java对象

反序列化:

public void Student() implements Serializable{
    private int xh;
    private String name;
    private String sex;
    
}
1、把java对象写到文件中

序列化(活化)

public static void main(String[] args)throws Exception{
    Student student = new Student();
    student.setXh(120);
    student.setName("小明");
    student.setSex("男");
    //写
    	//1、找到目标文件 ,建立通道
    FileOutputStream out = FileOutputStream("student.txt");
    //2、创建对象流
    ObjectOutputStream objOut = new ObjectOutputStream(out);
    //3写数据
    objOut.writeObject(student);
    //4、关闭数据通道
    objOut,close();
}
2、从文件中读取java对象

反序列化(钝化)

public static void test2(){
    //1、找到目标文件,建立数据通道
    FileInputStream in = new FileInputStream("student.txt");
    //2、创建对象流
    ObjectInputStream objIn = new ObjectInputStream(in);
    //3、读数据
    Student student = (Student)objIn.readObject(student);
    //4、关闭通道
    objIn.close();
    
}

注意:创建对象会调用对应的构造函数?

​ 反序列化时没有调用构造函数

问题:修改类中的成员后,反序列化失败:

​ serialVersionUID:根据类,属性方法…计算得来的值

​ 通过对象流序列化对象时,会把UID写入到文件中

​ 修改类中的属性uid的值就会发生改变

解决:1、重新序列化

​ 2、在实体类中把serialVersionUID写死

private static final long serialVersionUID = 1L;

7、File类

File类:文件(文档/目录)类(封装文件 )

1、构造函数

File(String pathname)

public static void test1(){
    //(1)File(String pathname):直接传文件路径
    File file = new File("\\");
}

File (String parent,String child)

public static void test1(){
    //(1)File (String parent,String child)
    //parent:父路径   child:文件名
    File file = new File("\\","b.txt");
}

File(File parent,String child)

public static void test1(){
    //(1)File(File parent,String child)
    //parent:父路径对应的File对象   child:文件名
    File file = new File(new File("\\"),"b.txt");
}
2、常用方法

1、boolean exists(),判断文件是否存在

File file1 = new File("\\c.txt");
//判断文件是否存在file1.exists()
System.out.println("file存在吗?"+file1.exists());
//判断是不是文件isFile()
System.out.println("file是文件吗"+file1.isFile());
//判断是不是文件夹isDirectory()
System.out.println("file是文件夹吗?"+file1.isDirectory())
if(!file1.exists()){//判断文件是否存在
    if(file1.isFile()){
        //创建文件
        file1.createNewFile();
    }
    //获取操作
    String name = file1.getName();//获取文件路径
    System.out.println("name ="+name);
    String parent = file1.getParent();//获取文件名
    System.out.println("Parent="+parent);
    String path = file1.getPath();//获取完整的文件路径
    System.out.println("path="+path);
}
//创建文件夹
public static void test3(){
    //创建file对象
    File file1 = new File("\\a");
    //判断:是否存在
    if(!file1.exists()){//如果不存在
        //创建文件夹 mkdir():只能创建单级目录
        file1.mkdir();
    }
    File file2 = new File("\\a\\b");
    if(!file1.exists()){//如果不存在
        //创建多级目录 mkdirs()
        file1.mkdirs();
    }
}

获取所有文件

String[] list()

public static void test3(){
    //创建File对象
    File file1 = new File("\\");
    //获取目录中的所有文件String[] list()
    String[] list = file.list();
    for(String name :list){
        System.out.println(name);
    }
}

File[] listFiles()获取目录中所有文件对象

//获取目录中所有文件对象:File[] listFiles()
File[] files = file.listFiles();
for(File file1 : files){
    System.out.println(file1);
}

String[] list(FilenameFilter filter)获取目录中过滤后的文件

//获取目录中过滤后的所有文件String[] list(FilenameFilter filter)
//FilenameFilter filter:文件名过滤器
String[] list1 = file.list(new filenameFilter({
    public boolean accept(File dir,String name){
        //过滤代码:只要java源文件(以.java结尾的文件)
        //name:
        if(name.endsWith(".java")){//判断是不是java源文件
            //是
            return true;//要
        }
        return false;//不要
    }
}));

File[] listFiles(FilenameFilter filter)获取目录中过滤后的文件对象

File[] list2 = file.listFiles(new FilenameFilter(){
    public boolean accept(File dir,String name){
        //只要图片
        if(name.endWith(".png")||name.endsWith(".jpg")){
            return true;//要
        }
        return false;//不要
    }
});

删除

public static void test5(){
    //创建File对象
    File file = new File("\\a.txt");
  	//删除文件
    file.delete();//删除文件或空的文件夹
    //删除文件夹
    File file2 = new("\\a");
    file2.delete();
  
}

使用File对象进行I/O流操作

public static void test6(){
    //1 找到目标对象
    File file = new File("\\a.txt");
    //2、建立数据通道
    FileReader reader = new FileReader(file);
    //3、读数据
    char[] buf = new char[1024*8];
    int length = 0;
    while((length = reader.read(buf))!=-1){
        System.out.println(new String(buf,0,length));
    }
    //4、关闭通道
    reader.close();
}
  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值