栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础-IO流

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础-IO流

IO流 1、概述 1.1、流的分类:
  • 按操作数据单位分:字节流byte(8bit),字符流char[](16 bit)
  • 按流向分:输入流、输出流
  • 按角色分:节点流:直接作用在文件上、处理流(在节点流的基础上再加上个流)

注意:在UTF-8的中文占三个字节,UniCode、GBK中占俩字节

抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter
作用图片、视频(非文本)用于处理文本文件

​ 作用:用于处理设备之间的数据传输。如:读/写文件、网络通讯

1.2、IO流体系
分类字节输入流字节输出流字符输入流字符输出流
抽象基类InputStreamOutputStreamReaderWriter
访问文件(节点流)FileInputStreamFileOutputStreamFileReaderFileWriter
访问数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
访问管理PipedInputStreamPipedOutputStreamPipedReaderPipedWriter
访问字符串StringReaderStringWriter
缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter
转换流InputStreamReaderOutputStreamWriter
对象流ObjectInputStreamObjectOutputStream
打印流PringOutputStreamPrintWriter
推回输入流PushbackInputStreamPushbackReader
特殊流DataInputStreamDataOutputStream

​ 记忆:从不同的角度:主要以尾部为主:如果以InputStream输入流、OutputStream输出流结尾,则为字节流。如果以Reade输入流、Writer输出流结尾,则为字符流

字符输入流

重点说明:

  1. read()的理解:返回读入的一个字符,如果达到文件末尾,返回-1,表示已读完
  2. 异常的处理:为了保证流资源一定可以执行关闭操作,需要try-catch-finally处理
  3. 读入文件一定存在,否则报FileNotFoundException
    @Test
    public void IOS(){
        
        FileReader reader = null;
        try {
            //实例化file类的对象,指明要操作的文件
            File file = new File("Sleep.txt");
            //提供具体的字符流
             reader = new FileReader(file);
             //定义一个整形变量记录每次读入数据个数
            int data;
            //循环读取文件中的字符,当文件中的字符等于-1时,则不在读取
            //表示读取完
            while((data = reader.read()) != -1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //防止找不到文件,报空指针异常,造成流未关闭
                if(reader != null)
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
@Test
    public void testIOS2(){
        FileReader fileReader = null;
        try {
            File file = new File("Sleep.txt");

            fileReader = new FileReader(file);
            //每次读取5个字符
            char[] chars = new char[5];
            //记录每次读入到chars数组中的字符个数
            int len;
            while ((len = fileReader.read(chars)) != -1) {
                for (int i = 0; i < len; i++) {
                    System.out.print(chars[i]);
                }
//                String string = new String(chars,0,len);
//                System.out.print(string);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fileReader != null){
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

改变:
    //每次读取5个字符
            char[] chars = new char[5];
            //int len;
            while ((fileReader.read(chars)) != -1) {
                String string = new String(chars,0,chars.length);
                System.out.print(string);
            }

字符输出流:

重点说明

  1. 输出操作:对应的File对应硬盘中文件可以不存在,如果不存在,会在输出过程中自动创建

  2. File对应硬盘中文件存在:

    • 如果流使用的构造器是:FileWriter(file,false)/FileWriter(file),对原有的数据文件进行覆盖
    • 如果流使用的构造器是:FileWriter(file,true),则不会对原有的数据文件进行覆盖,而是在原有的数据文件之后做添加操作
@Test
    public void testIOS3(){
        
        FileWriter fileWriter = null;
        FileWriter fileWriters = null;
        try {
            File file = new File("ten.txt");
            fileWriter = new FileWriter(file,true);
            fileWriters = new FileWriter(file,false);
            String is = "从前从前n" +
                    "有一座山n" +
                    "山上有座庙n" +
                    "庙里有个和尚n" +
                    "和尚说n" +
                    "施主:从哪来,到哪去呀n" +
                    "施主说:我从东土大唐来,去到西天取经";
            String i = "《中央日报》是韩国较全面、值得信赖的新闻载体之一,同时也是平面媒体的创新者。其推行的编辑管理模式首获成功。《中央日报》是韩国人较爱读的报纸,以其可靠、深入的新闻报道吸引了韩国高级知识分子和高收入读者的关注。《中央日报》还是韩国第一家创办教育报的媒体,致力于培养未来读者群。该报还同《国际先驱论坛》合作出版英文日报《JoongAng Daily》。另外,中央日报集团还出版有韩文版《新闻周刊》、《福布斯》、《时尚》等国际性杂志。除此之外,《中央日报》还通过因特网提供音视频的时代华纳动画片和美国有线电视新闻网新闻服务。1995年,《中央日报》创办了亚洲首家因特网新闻服务网。这家网站也一直是最受欢迎的新闻媒体网站。";
            fileWriter.write(is,0,is.length());
            fileWriter.write("《中央日报》");//直接写
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileWriter != null){
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else if (fileWriters != null){
                try {
                    fileWriters.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

结论:

  1. 对于文本文件(.txt,.java、.c、.c++…),使用字符流处理
  2. 对于非文本文件、视频文件(.jpg、.mp3、.mp4、.avi、.doc、.ppt…),使用字节流处理

字节输入流、字节输出流

重点说明:读取非文本文件时,不能使用string进行读取

​ 目的:实现对图片的复制

@Test
public void testIOS5(){
        //重点说明:读取非文本文件时,不能使用string进行读取
        //创建类对象
    FileInputStream inputStream = null;
    FileOutputStream outputStream = null;
    try {
        File file = new File("beauty.jpg");
        File Copyfile = new File("beauty3.jpg");
        //创建流
        inputStream = new FileInputStream(file);
        outputStream = new FileOutputStream(Copyfile);
        //读取操作
        //因为是字节流,所以用到byte[]数组
        byte[] bytes = new byte[5];
        //定义一个变量记录读取字节个数
        int len;
        //循环
        while ((len = inputStream.read(bytes)) != -1){
            outputStream.write(bytes,0,len);
//            String s = new String(bytes,0,len);
//            System.out.println(s);
        }
        System.out.println("复制成功!");
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            if (inputStream != null){
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (outputStream != null){
                outputStream.close();
    }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	}
}
字符缓冲读、写流
  * */
    @Test
    public void TestOutputStream(){

        //造文件
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            File First = new File("six.txt");
            File Second = new File("Error.txt");
            //造流
            FileReader fir = new FileReader(First);
            FileWriter fwr = new FileWriter(Second);
            //造缓冲流
            bufferedReader = new BufferedReader(fir);
            bufferedWriter = new BufferedWriter(fwr);
            //读取细节
            //小推车,容纳十个字符
            char[] BufferChar = new char[10];
            //定义一个计算长度
            int len;
            //循环读取,直至-1
            while ((len =bufferedReader.read(BufferChar)) != -1){
                bufferedWriter.write(BufferChar,0,len);
                //string的缓冲字符
                StringWriter writer = new StringWriter();
                writer.write(BufferChar,0,len);
                System.out.println(writer);
            }
             //String len;
            //readLine()该方法没有换行符,所有语句全部都成为一条句子
            //while ((len =bufferedReader.readLine()) != null){
                //bufferedWriter.write(len);
                //newLine():添加换行符
               // bufferedWriter.newLine();
           // }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bufferedReader != null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedWriter != null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
字节读、写缓冲流
@Test
    public void testBufferInOnPutStream(){
        BufferedInputStream Bfis = null;
        BufferedOutputStream Bfos = null;
        try {
            //造文件
            File Target = new File("beauty.jpg");
            File Result = new File("beauty3.jpg");
            //造流
            FileInputStream fis = new FileInputStream(Target);
            FileOutputStream fos = new FileOutputStream(Result);
            //造字节缓冲流
            Bfis = new BufferedInputStream(fis);
            Bfos = new BufferedOutputStream(fos);
            //读写操作
            byte[] BuffByte = new byte[10];
            //定义计算长度
            int len;
            //循环读取
            while ((len = Bfis.read(BuffByte)) != -1){
                Bfos.write(BuffByte,0,len);
            }
            System.out.println("缓冲流复制完成");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (Bfis != null){
                try {
                    Bfis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (Bfos != null){
                try {
                    Bfos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
缓冲流总结:
  1. 缓冲流
    • BufferedInputStream
    • BufferedOutputStream
    • BufferedReader
    • BufferedWriter
  2. 作用:缓冲流内部提供了一个缓冲区:默认值为8192,并且提供了flush()方法,每次刷新的时候,不管缓冲区有多少数据,都会被读、写出去,当读写数据快到该默认值时,会自动刷新当前的默认空间,提高流的读取、写入速度。
转换流

定义:

  1. 转换流–>属于字符流
    • InputStreamReader:将一个字节的输入流转换为字符的输入流
    • OutputStreamWriter:将自已字符的输出流转换为字节的输出流
  2. 作用:提供字节流与字符流之间的转换
  3. 解码:从字节、字节数组 —> 字符数组、字符

​ 编码: 从字符数组、字符 —> 字节、字节数组

4.字符集

重点注意:

  
            streamReader = new InputStreamReader(fileInputStream,"gbk");

 
    @Test
    public void testInputStreamReader(){
        InputStreamReader streamReader = null;
        try {
            //创建字节流,将字节文件导入
            FileInputStream fileInputStream = new FileInputStream("eight.txt");
            //创建字符转换流
            //streamReader = new InputStreamReader(fileInputStream);
            
            //定义字符编码格式,默认为UTF-8的编码格式
            streamReader = new InputStreamReader(fileInputStream,"gbk");
            //定义小推车,一次装十个字节
            char[] ReaderChar = new char[10];
            //抓取长度
            int len;
            //循环
            while ((len = streamReader.read(ReaderChar)) != -1){
                String s = new String(ReaderChar,0,len);
                System.out.println(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (streamReader != null){
                try {
                    streamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
对象流

一、定义

  1. 对象流:ObjectInputStream、ObjectOutputStream
  2. 作用:用于存储和读取基本数据类型数据或对象的处理流,强大之处是可以把Java中的对象写入到数据源中,也能从数据源中还原回来。
    • 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
    • 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
  3. 注意:①ObjectInputStream和ObjectOutputStream不能序列化static和transient修饰的成员变量。②要想实现可序列化操作,除了实现序列化接口以外,还必须保证其内部属性都是可序列化的,默认情况下基本数据类型都是可序列化的

二、简述序列化

  1. 何为对象序列化机制?

    • 允许把内存中的Java对象转换成与平台无关的二进制流持久的存储在磁盘中。通过网络编程的方式将二进制流传输到另一个网络节点。如:ObjectInputStream
    • 当其他网络程序获取到该二进制流,就可以自动转换成Java对象
  2. 好处

    • 可将任何实现了Serializable接口的对象转换为字节数据,使其在保存和传输时可被还原
    • 如果需要让某个对象支持序列化机制,则必须让对象所处的类及其属性是可序列化的,让某个类实现可序列化,必须实现如下俩接口之一:Serializable、Externalizable,否则会抛出NotSerializableException异常
  3. 实例:

  4. public class Person implements Serializable {
        //在传输的过程中保证序列化对象的唯一性,防止在传输多个序列化对象时错乱
        public static final long serialVersionUID = 15L;
        private int age;
        private String name;
    //    private int id;
    //    @Override
    //    public String toString() {
    //        return "Person{" +
    //                "age=" + age +
    //                ", name='" + name + ''' +
    //                ", id=" + id +
    //                '}';
    //    }
    //
    //    public int getId() {
    //        return id;
    //    }
    //
    //    public void setId(int id) {
    //        this.id = id;
    //    }
    
    //    public Person(int id) {
    //        this.id = id;
    //    }
    
        public Person(int age, String name) {
            this.age = age;
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        @Override
        public String toString() {
            return "Person{" +
                    "age=" + age +
                    ", name='" + name + ''' +
                    '}';
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    
    //方法
     
        @Test
        public void testSerializable(){
            ObjectOutputStream oos = null;
            FileOutputStream fos = null;
            try {
                //造文件
                fos = new FileOutputStream("Object.dat");
                //造流
                oos = new ObjectOutputStream(fos);
                //方法
                //序列化对象
                Person person = new Person(22,"习大大");
                oos.writeObject(person);
                //
                String s = new String("I like beijing");
                oos.writeObject(s);
                oos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关流
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        @Test
        public void testBackSerializable(){
            ObjectInputStream ois = null;
            try {
                //造文件
                FileInputStream fis = new FileInputStream("Object.dat");
                //造流
                ois = new ObjectInputStream(fis);
                //拿出序列化对象的数据
                Object obj = ois.readObject();
                Person person = (Person) obj;
                System.out.println(person);
                //方法
                Object o = ois.readObject();
                String st = (String) o;
                System.out.println("反序列化出来的字符串:"+st);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }finally {
                //关流
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
RamdomAccessFile类
  1. 定义

    • 创建RamdomAccessFile类实例需要指定一个mode参数,该参数指定RamdomAccessFile的访问模式;
      1. r:以只读的方式打开
      2. rw:读取和写入
      3. rwd:读取和写入,同时同步文件内容的更新
      4. rws:读取和写入,同时同步文件内容和元数据的更新
    • 如果模式为只读r。则不会创建文件,而是读取一个已经存在的文件,如果读取的文件不存在则会出现异常。如果模式为读写rw,如果文件不存在则会创建文件,如果文件存在则不会创建
    • JDK1.6上写到,每次write数据时,“rw"模式,数据不会立即写到硬盘中,而"rwd”,数据会被立即写到硬盘中,如果写数据的过程中出现异常,"rwd"模式中的数据被保存到硬盘中,而"rw"的数据则全部丢失
  2. 使用

    • RandomAccessFile的使用
        1、直接继承于java.lang.Object类,实现了DataOutput,DataInput、Closeable接口
        即为输入流,又为输出流
        2、作为输出流时,写出到的文件如果不存在,在执行过程中会自动创建文件
        如果文件存在,则会对原有文件内容进行覆盖(默认情况下从头覆盖)
      注意:在写的过程中,mode必须为‘rw’,因为RandomAccessFile并没有定义‘w'为写
          
           @Test
          public void TestRandomAccessFile() {
              RandomAccessFile raf = null;
              RandomAccessFile rafs = null;
              try {
                  //造文件、造流
                  raf = new RandomAccessFile(new File("beauty.jpg"), "r");
                  rafs = new RandomAccessFile(new File("beauty6.jpg"), "rw");
                  //定义一个字节数组小车
                  byte[] bytes = new byte[1024];
                  //定义一个读取常量,记录
                  int len;
                  //读
                  while ((len = raf.read(bytes)) != -1) {
                      //写
                      rafs.write(bytes, 0, len);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  //关流
                  if (raf != null) {
                      try {
                          raf.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
      
                  }
                  if (rafs != null) {
                      try {
                          rafs.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
          
          @Test
          public void testRW(){
              //测试是否全部覆盖还是覆盖长度
              RandomAccessFile accessFile = null;
              try {
                  accessFile = new RandomAccessFile("sevenEleven.txt","rw");   accessFile.write("shenghuojiuxiangyibawuqingdekedao".getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }finally {
                  if (accessFile != null){
                      try {
                          accessFile.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      
       
          @Test
          public void testAppend(){
              RandomAccessFile raf = null;
              try {
                  raf = new RandomAccessFile(new File("sevenEleven.txt"),"rw");
                  //将指针调到下标为3的位置
                  raf.seek(3);
                  //保存指针为3后面的所有数据到stringBuilder中
                  StringBuilder stringBuilder = new StringBuilder((int) new File("sevenEleven.txt").length());
                  byte[] bytes = new byte[20];
                  int len;
                  while ((len = raf.read(bytes)) != -1){
                      stringBuilder.append(new String(bytes,0,len));
                  }
                  //调回指针到3的位置,写入"sdksd"
                  raf.seek(3);
                  raf.write("sdksd".getBytes());
                  //将stringBuilder中的数据写入到文件中
                  raf.write(stringBuilder.toString().getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }finally {
                  if (raf != null) {
                      try {
                          raf.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      

###原创文章----南山程序猿

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/843082.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号