Java进阶IO流

IO流

  • IO流的分类:
    • 按照流的方向,IO流分为:
      • 输入流
      • 输出流
    • 按照流的内容,IO流分为:
      • 字节流:适合操作所有文件,音频,视频,图片,文本文件的复制转移等。
      • 字符流:只适合操作纯文本文件,读写txt,Java文件等
  • 以下都属于抽象类:
    • 字节输入流InputStream
    • 字节输出流OutputStream
    • 字符输入流Reader
    • 字符输出流Writer

文件字节输入流

public class IOTest {
    public static void main(String[] args) throws Exception {
        //1.创建文件字节输入流管道与源文件接通
        InputStream is = new FileInputStream("D:/aaa/qq.txt");

        //2.开始读取文件中的字节并输出,每次读取一个字节
        //定义一个变量记住每次读取的一个字节
        int b;
        while ((b = is.read()) != -1) {
            System.out.print((char) b);//打印读到的字节并且转换为char字符
        }
        //每次读取一个字节会导致性能较差,并且读取汉字输出一定会乱码。
       

        //3.开始读取文件中的字节并输出,每次读取多个字节
        //定义一个字节数组记住每次读取的字节
        byte[]bytes=new byte[1024];
        int len;//定义一个变量记住每次读取多少个字节
        while((len=is.read(bytes))!=-1){
            //把读取到的字节数组转换成字符串输出
            String str=new String(bytes,0,len);//代表从第一个字节开始读多少个字节,否则会出现不符合预期的字符。
            System.out.println(str);
        }
        //依然无法避免读取汉字出现乱码的问题,存在截断汉字字节的可能性。
        //除非定义一个与文件一样大的字节数组,一次性读取完文件的全部字节。(只适用于读取一个小文件)
        
        //一次性读完文件的全部字节,可以避免读取汉字被截断的缺陷,但只适用于读取一个小文件
        byte[] bytes =is.readAllBytes();
        String str=new String(bytes);
        System.out.println(str);
         is.close();
    }
}

文件字节输出流

public class IOTest { 
    public static void main(String[] args) throws Exception {
        //1.创建文件字节输出流管道与目标文件接通
       // OutputStream os = new FileOutputStream("D:/aaa/ww/txt");//覆盖管道,每次执行会将原来的数据清空
        OutputStream os = new FileOutputStream("D:/aaa/ww/txt",true);//每次执行是在原文件内容下追加内容
        //2.写入数据
        os.write(97);//写入一个字节数据
        os.write('b');//写入一个字符数据
        os.write('白');//写入一个字符数据,出现乱码,因为write一次写一个字节
        os.write("\r\n".getBytes());//在文件中进行换行,\r\n表示回车并换行

        //3.写一个字节数组出去
        byte[] bytes="中文汉字33ad".getBytes();//将字符串转成字符数组存储起来
        os.write(bytes);
        //4.写一个字节数组的一部分出去
        os.write(bytes,0,3);//从第一个字节开始 写三个字节 出去
        os.close();//关闭管道,释放资源
    }
}
  • 进行文件复制操作

    public class IOTest {
        public static void main(String[] args) throws Exception {
            //将文件夹aaa下的文件a.txt复制到bbb下并且取名为b.txt
            InputStream is=new FileInputStream("D;/aaa/a.txt");//要从文件中读取字节,进行管道连接
            OutputStream os=new FileOutputStream("D;/bbb/b.txt");//要写入字节到文件,进行管道连接
            byte[] bytes=new byte[1024];//一次读数组大小的字节
            int len;//记录真实读取到的长度
            while((len=is.read(bytes))!=-1){
                os.write(bytes,0,len);//将读取到的字节写入新文件中
            }
            System.out.println("复制成功");
            is.close();
            os.close();
        }
    }
    
  • 捕获异常,对上面代码进行优化

    public class IOTest {
        public static void main(String[] args) throws Exception {
            //将文件夹aaa下的文件a.txt复制到bbb下并且取名为b.txt
    
            try (//这里放置资源对象,用完之后,最终会自动调用其close方法关闭
                    InputStream is=new FileInputStream("D;/aaa/a.txt");//要从文件中读取字节,进行管道连接
                    OutputStream os=new FileOutputStream("D;/bbb/b.txt");//要写入字节到文件,进行管道连接
            ){
                byte[] bytes=new byte[1024];//一次读数组大小的字节
                int len;//记录真实读取到的长度
                while((len=is.read(bytes))!=-1){
                    os.write(bytes,0,len);//将读取到的字节写入新文件中
                }
                System.out.println("复制成功");
    
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    

文件字符输入流和文件字符输出流与上面的同理

  • xx.flush();//刷新缓冲区,将缓冲区中的数据全部写出去,否则数据不会同步到文件中,会随内存消失。
  • xx.close();//包含刷新功能。

高级流

  • 缓冲流
    • BufferedInputStream
    • BufferedOutputStream
    • BufferedReader
    • BufferedWriter
  • 对上面的复制功能代码进行改造:
public class IOTest {
    public static void main(String[] args) throws Exception {
        //将文件夹aaa下的文件a.txt复制到bbb下并且取名为b.txt

        try (//这里放置资源对象,用完之后,最终会自动调用其close方法关闭
                InputStream is=new FileInputStream("D;/aaa/a.txt");//要从文件中读取字节,进行管道连接
             //把低级的字节输入流包装成高级的缓冲字节输入流
             InputStream bis=new BufferedInputStream(is);
                OutputStream os=new FileOutputStream("D;/bbb/b.txt");//要写入字节到文件,进行管道连接
             //把低级的字节输出流包装成高级的缓冲字节输出流
             OutputStream cis=new BufferedOutputStream(os);
        ){
            byte[] bytes=new byte[1024];//一次读数组大小的字节
            int len;//记录真实读取到的长度
            while((len=bis.read(bytes))!=-1){
                cis.write(bytes,0,len);//将读取到的字节写入新文件中
            }
            System.out.println("复制成功");

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
  • 缓冲字符输入流
public class Test3 {
    public static void main(String[] args) {
        try(    //创建文件字符输入流与源文件接通
                Reader fr =new FileReader("D:/aaa/a.txt");
                //创建缓冲字符输入流包装低级的字符输入流
                BufferedReader br =new BufferedReader(fr);
        ){
//            char[] chs = new char[1024];
//            int len;
//            while((len=br.read(chs))!=-1){
//                String s = new String(chs,0,len);
//                System.out.println(s);
//            }
            System.out.println(br.readLine());//读出一行
            //使用循环改进,来按照行读取数据
            //定义一个字符串变量用于记住每一次读取的一行数据
            String line;
            while((line=br.readLine())!=null){
                System.out.println(line);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
  • 缓冲字符输出流

    • 新增一个包装了的换行功能
    • xx.newLine();
  • 字符输入转换流:InputStreamReader

    • 解决不同编码时,字符流读取文本内容乱码问题
    • 先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了。
public class Test3 {
    public static void main(String[] args) {
       try(     //先提取文件的原始字节流
               InputStream is=new FileInputStream("D://aaa/a.txt");
               //指定字符集,把原始字节流转换成字符输入流
               InputStreamReader isr=new InputStreamReader(is,"GBK");//GBK为文件本身的字符集,但我的字符集为UTF-8
               //创建缓冲字符输入流包装低级的字符输入流
               BufferedReader br=new BufferedReader(isr);
               ){
           String line;
           while((line=br.readLine())!=null){
               System.out.println(line);
           }

       }catch (Exception e){
           e.printStackTrace();
       }
    }
}
  • 打印流:printStream(字节输出流),printWriter(字符输出流)
    • 打印到文件中,实现打印啥出去就是啥。(打印97,就是97而不是a)
public class Test3 {
    public static void main(String[] args) {
        try (
           // PrintStream ps = new PrintStream("D:\\test3.txt");//字节输出流打印,但不支持追加内容,只有低级输出流才有追加数据的功能
            PrintStream ps = new PrintStream(new FileOutputStream("D:\\test3.txt",true));//字节输出流打印,这样就支持追加内容
            PrintWriter pw = new PrintWriter("D:\\test3.txt");//字符输出流打印
                ) {
                ps.println('a');
                pw.println('胡');

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 特殊数据流

    • 特殊数据字节输入流:DataInputStream

      DataInputStream dis = new DataInputStream(new FileInputStream("D:/aaa/a.txt"));
       System.out.println(dis.readInt());
      System.out.println(dis.readUTF());
      //读写类型要相互对应,观察输出流内容
      
    • 特殊数据字节输出流:DataOutputStream

      • 允许把数据和类型一并写出去(看起来像是乱码,但是其实并不是,适用于通信)
      DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:/aaa/a.txt"));
      dos.writeInt(23);
      dos.writeUTF("哈喽");
      

IO框架

  • 需要下载IO资源库
public class IO {
    public static void main(String[] args) throws Exception{
        //拷贝文件
        FileUtils.copyFile(new File("D:/a.txt"),new File("D:/b.txt"));
        //拷贝文件夹
        FileUtils.copyDirectory(new File("D:/aaa"),new File("D:.bbb"));
        
    }
}
posted @ 2025-11-30 22:45  芒果学代码  阅读(0)  评论(0)    收藏  举报