Java学习☕ | Java300集课程笔记整理2.0(IO流)

本文详细介绍了Java中的File类和File对象,包括如何创建和使用。接着探讨了编码和解码的过程,展示了如何进行字节和字符串之间的转换。进一步讲解了文件字节输入流和输出流的使用,包括单个字节读取和分段读取,以及文件字节输出流的写入操作。此外,还涉及到了文件字符输入输出流的读写,文件拷贝,字节数组输入输出流的使用,以及如何通过对接流实现文件内容的复制。最后,通过实例展示了如何将图片读取为字节数组并写入新的文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


学习视频(Java300集):https://www.bilibili.com/video/BV1ct411n7oG

一、File类和File对象

  • 测试代码
package com.ljh.io;
import java.io.File;

/*
测试io和File类:File只是一个路径表示形式,可以构建一个文件、不存在的路径以及文件夹
1,构建File对象
2,相对路径和绝对路径
    1)有盘符:绝对路径
    2)没有盘符:相对路径
 */
public class Test_io_File {
    public static void main(String[] args) {

        //构建一个路径,最好用/来分隔
        String path = "D:/workplace_java/Pro01/io.PNG";

        /*利用File的构造器构建File对象,三种方法*/

        //1、直接用路径名称
        File src1 = new File(path);

        //2、父子结合(2种方法)
        File src2 = new File("D:/workplace_java/Pro01","io.PNG");
        src2 = new File("D:/workplace_java","Pro01/io.PNG");

        //3、用父构建的对象和子的名称结合
        File src3 = new File(new File("D:/workplace_java/Pro01"),"io.PNG");

        //打印路径的长度
        System.out.println(src1.length());
        System.out.println(src2.length());
        System.out.println(src3.length());

        /*测试相对路径和绝对路径*/

        //绝对路径
        File src = new File(path);
        System.out.println(src.getAbsoluteFile());//打印绝对路径

        //相对路径
        src = new File("io.PNG");
        System.out.println(src.getAbsoluteFile());

        //一个不存在的文件也能构建出绝对路径
        src = new File("abc.png");
        System.out.println(src.getAbsoluteFile());
    }
}
  • 测试结果

二、测试编码和解码(Encode&Decode)

2.1 编码(Encode)

  • 测试代码:
package com.ljh.io;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/*
编码:字符(字符串)->字节
 */
public class ContentEncode {
    public static void main(String[] args) throws UnsupportedEncodingException {

        String m = "java永远的神";

        /*转化成字节数组*/

        //使用默认的工程字符集(UTF-16LE,小端,每个字符都是2个字节)
        byte[] datas = m.getBytes();
        System.out.println(datas.length);

        //使用GBK编码,中文字符2个字节,英文字符1个字节
        datas = m.getBytes("GBK");
        System.out.println(datas.length);
    }
}
  • 测试结果:

2.2 解码(Decode)

  • 测试代码:
package com.ljh.io;

import java.io.UnsupportedEncodingException;

/*
解码:字节->字符串
 */
public class ContentDecode {
    public static void main(String[] args) throws UnsupportedEncodingException {

        String m = "java永远滴神";

        //先转成字节数组
        byte[] datas = m.getBytes();

        /*再转回字符串*/

        String m2 = new String(datas,0, datas.length,"UTF-8");
        System.out.println(m2);

        /*出现乱码的情况*/

        //1)字符数不够(一个中文2个字节,最后的“神”少了一个,所以出现乱码)
        String m3 = new String(datas,0,datas.length-1,"UTF-8");
        System.out.println(m3);

        //2)字符集不一致
        String m4 = new String(datas,0, datas.length,"GBK");
        System.out.println(m4);
    }
}
  • 测试结果:

三、文件字节输入流

操作流程:

  1. 创建源
  2. 选择流
  3. 操作(读取)
  4. 释放资源

3.1 单个字节读取

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件字节输入流(单个字节读取):
1,创建源
2,选择流
3,操作
4,释放资源
 */
public class IOtest01 {
    public static void main(String[] args) {

        //1,创建源
        File src = new File("abc.txt");

        //2,选择流(输入流)
        InputStream is = null;

        try {
            is = new FileInputStream(src);

            try {
                //如果遇到不存在的数据(文件末尾),就返回-1,故当遇到-1时就结束循环
                int temp;
                while((temp = is.read())!= -1)//需要将is.read()赋值给一个变量才能继续访问下一个数据。直接用is.read()会出错
                    System.out.println((char)temp);

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

            //4,释放资源
            if(null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • abc.txt(源文件):
  • 测试结果:

3.2 分段读取

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件字节输入流(分段读取)
 */
public class IOtest01_1 {
    public static void main(String[] args) {

        //1,创建源
        File src = new File("abc.txt");

        //2,选择流(输入流)
        InputStream is = null;

        try {
            is = new FileInputStream(src);

            //3,操作(分段读取)
            byte[] flush = new byte[3];//作为缓冲容器,每3个读取一次(每三个为一段)
            int len = -1;//记住读取的长度
            while(true){
                try {
                    if (!((len = is.read(flush))!= -1)) break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //字节数组->字符串(解码)
                String msg = new String(flush,0,len);
                System.out.println(msg);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {

            //4,释放资源
            if(null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 源文件与上图一致
  • 测试结果:

四、文件字节输出流

操作流程:

  1. 创建源
  2. 选择流
  3. 操作(写入)
  4. 释放资源
  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件字节输出流
1、创建源
2、选择流
3、操作(写入)
4、释放资源
 */
public class IOtest02 {
    public static void main(String[] args) {

        //1,创建源(创建不存在的文件)
        File dest = new File("dest.txt");

        //2、选择流(输出流)
        OutputStream os = null;

        try {
            os = new FileOutputStream(dest);

            //3,操作(写入数据)
            String msg = "java is nb";//写入数据内容
            byte[] datas = msg.getBytes();//字符串->字节数组(编码)

            try {
                os.write(datas,0, datas.length);//按字节大小写入
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.flush();//最好要写上,刷新
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
        	//4,释放资源
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}
  • 测试结果(得到的文件):

五、文件字符输入输出流

操作流程:

  1. 创建源
  2. 选择流
  3. 操作(读取)
  4. 释放资源

5.1 实现输入流

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件字符输入流
1,创建源
2,选择流
3,操作(读取)
4,释放资源
 */
public class IOtest03 {
    public static void main(String[] args) {

        //1,创建源
        File src = new File("abc.txt");

        //2,选择流(输入流)
        Reader reader = null;

        try {
            reader = new FileReader(src);

            //3,操作(分段读取)
            char[] flush = new char[1024];//作为缓冲容器,每k(1024个字节)读取一次,可读取中文
            int len = -1;//记住读取的长度
            while(true){
                try {
                    if (!((len = reader.read(flush))!= -1)) break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //字符数组->字符串
                String msg = new String(flush,0,len);
                System.out.println(msg);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
			//4,释放资源
            if(null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 源文件内容:
  • 测试结果:

5.2 实现输出流

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件字符输出流
1、创建源
2、选择流
3、操作(写入)
4、释放资源
 */
public class IOtest04 {
    public static void main(String[] args) {

        //1,创建源(创建不存在的文件)
        File dest = new File("dest1.txt");

        //2、选择流(输出流)
        Writer writer = null;

        try {
            writer = new FileWriter(dest);

            //3,操作(写入数据)
            String msg = "java is 牛逼\r\n失败乃成功之母";//写入数据内容(可含中文)
            char[] datas = msg.toCharArray();//字符串->字符数组

            writer.write(datas);//可不指定大小
            writer.flush();//记得刷新
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
        	//4,释放资源
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 测试结果(得到文件内容):

六、文件拷贝(利用文件字节输入输出流)

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
文件拷贝:文件字节输入、输出流
利用文件字节输入输出流的代码进行合并即可得到文件拷贝的程序
 */
public class IOtest_copy {
    public static void main(String[] args) {

        //1,创建源(两个源)
        File src = new File("p.png");//源头
        File dest = new File("p_copy.png");//目的源

        //2,选择流(输入、输出流)
        InputStream is = null;
        OutputStream os = null;

        try {
            is = new FileInputStream(src);
            os = new FileOutputStream(dest);

            try {
                //3,操作(分段读取,再写入)
                byte[] flush = new byte[1024];//1k为单位
                int len = -1;
                while((len = is.read(flush))!= -1)//需要将is.read()赋值给一个变量才能继续访问下一个数据。直接用is.read()会出错
                    os.write(flush,0,len);

                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {

            //4,释放资源,先打开的后释放(输入的先打开)
            if(null != os) {//先释放os
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != is) {//再释放is
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 测试结果:
  1. 源文件(原图片):
  2. 目的文件:

七、字节数组输入输出流

7.1 实现输入流

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
字节数组输入流:
1,创建源:源是字节数组,不要太大
2,选择流
3,操作
4,释放资源:可以不用处理
 */
public class IOtest05 {
    public static void main(String[] args) {

        //1,创建源
        byte[] src = "show me the code".getBytes();//字节数组作为源

        //2,选择流(输入流)
        ByteArrayInputStream is = null;//直接用子类创建对象,因为要用到特殊方法

        try {
            is = new ByteArrayInputStream(src);

            try {
                //3,操作,用分段读取
                byte[] flush = new byte[5];
                int len = -1;
                while((len = is.read(flush))!= -1) {
                    String msg = new String(flush, 0, len);
                    System.out.println(msg);
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }finally {

            //4,释放资源(可以不写)
            if(null != is) {
                try {
                    is.close();//此时close是空方法
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 测试结果:

7.2 实现输出流

  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
字节数组输出流
1、创建源:内部维护,不用自己创建
2、选择流:不关联源
3、操作(写入)
4、释放资源:可以不用处理
5、要获取资源
 */
public class IOtest06 {
    public static void main(String[] args) {

        //1,创建源(可不写)
        byte[] dest = null;//可以不写,只为了风格统一

        //2、选择流(输出流)
        ByteArrayOutputStream os = null;//直接用子类创建对象,因为要用到特殊方法

        try {
            os = new ByteArrayOutputStream();

            //3,操作(写入数据)
            String msg = "show me the code";//写入数据内容
            byte[] datas = msg.getBytes();//字符串->字节数组(编码)

            os.write(datas,0, datas.length);//按字节大小写入
            try {
                os.flush();//最好要刷新一下
            } catch (IOException e) {
                e.printStackTrace();
            }

            //获取资源
            dest = os.toByteArray();
            String str = new String(dest,0,dest.length);
            System.out.println(str+"的长度为"+dest.length);
        } finally {
            //4,释放资源(可不写)
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 测试结果:

八、对接流

对接流的实现:

  • 图片读取到字节数组(程序为中转站)
  1. 图片到程序:FileInputStream
  2. 程序到字节数组:ByteArrayOutputStream
  • 字节数组写入到文件(程序为中转站)
  1. 字节数组到程序:ByteArrayInputStream
  2. 程序到文件:FileOutputStream
  • 测试代码:
package com.ljh.io;

import java.io.*;

/*
对接流
1、图片读取到字节数组中
2、字节数组写入到文件中
 */
public class IOtest07 {
    public static void main(String[] args) {

        //调用方法
        byte[] datas = fileToByteArray("p.png");
        System.out.println("图片大小为"+datas.length);
        byteArrayToFile(datas,"p_data.png");
    }

    /*1,图片读取到字节数组中
        1)图片到程序:FileInputStrean
        2)程序到字节数组:ByteArrayOutputStream*/
    public static byte[] fileToByteArray(String filePath) {

        //1,创建源
        File src = new File(filePath);
        byte[] dest = null;

        //2,选择流
        InputStream is = null;
        ByteArrayOutputStream os = null;

        try {
            is = new FileInputStream(src);
            os = new ByteArrayOutputStream();

            try {
                //3,操作
                byte[] flush = new byte[1024*10];//每10k读取一次
                int len = -1;
                while((len = is.read(flush))!= -1)//需要将is.read()赋值给一个变量才能继续访问下一个数据。直接用is.read()会出错
                    os.write(flush,0,len);//写到os(字节数组)里面

                os.flush();

                return os.toByteArray();//返回获取到的资源
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {

            //4,释放资源(可不写os的释放)
            if(null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

     /*2,字节数组写入到文件中
        1)字节数组到程序:ByteArrayInputStream
        2)程序到文件:FileOutputStream*/
    public static void byteArrayToFile(byte[] dest, String filePath) {

        //1,创建源
        File src = new File(filePath);

        //2,选择流
        ByteArrayInputStream is = null;
        OutputStream os = null;

        try {
            is = new ByteArrayInputStream(dest);
            os = new FileOutputStream(src);

            try {
                //3,操作
                byte[] flush = new byte[1024*10];//每10k读取一次
                int len = -1;
                while((len = is.read(flush))!= -1)//需要将is.read()赋值给一个变量才能继续访问下一个数据。直接用is.read()会出错
                    os.write(flush,0,len);//写到os(字节数组)里面

                os.flush();

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

            //4,释放资源(可不写is的释放)
            if(null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 源文件(原图片):
  • 测试结果及得到的文件:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值