zoukankan      html  css  js  c++  java
  • JAVASE(十六) IO流 :File类、节点流、缓冲流、转换流、编码集、对象流

    个人博客网:https://wushaopei.github.io/    (你想要这里多有)

    1、File类型

    1.1.File类的理解

    1. File类是在java.io包下
    2. File可以理解成一个文件(.mp3  .mp4 .txt)或者一个目录
    3. File没向文件写入数据的功能。只创建,删除,文件大小等方法。
    4. File可以理解成流的终端。
    5. 我们经常将File的对象作为实参传入到流的构造器中
    6. File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。

    1.2. 如何实例化

    File file = new File("H:\aaa\abc.txt");
    File file = new File("H:/aaa/abc.txt");
    new File("H:\aaa", "abc.txt"); //H:\aaa\abc.txt

    绝对路径:包含盘符在内的完整路径
    相对路径:相对于当前的项目的路径。

    1.3 File 类的常见构造器:

    注意:File的静态属性String separator存储了当前系统的路径分隔符。

                在UNIX中,此字段为‘/’,在Windows中,为‘\’

    1.4.常用方法

                 

    1.5 案例

             

    2、IO流概述

    2.1概念:

    • I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
    • Java程序中,对于数据的输入/输出操作以”流(stream)” 的方式进行。
    • java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。

    2.2 Java IO原理

             ​                                                     

    2.3.流的分类

    • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)  
    • 按数据流的流向不同分为:输入流,输出流
    • 按流的角色的不同分为:节点流,处理流

            

    1. Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
    2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

    图示:

    2.4.流的体系结构(蓝色的部分是重点

    2.5 输入流、输出流

    • 节点流可以从一个特定的数据源读写数据

           

    • 处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

            

        

    (1)InputStream & Reader

           

    (2)OutputStream & Writer

         

    3、节点流(文件流)

    文件流(1)

               

            FileReader fr = null;
    	try{
    		fr = new FileReader("c:\test.txt");
    		char[] buf = new char[1024];
    		int len= 0;
    		while((len=fr.read(buf))!=-1){
    			System.out.println(new String(buf ,0,len));}
    	}catch (IOException e){
    		System.out.println("read-Exception :"+e.toString());}
    	finally{
    		if(fr!=null){
    			try{
    				fr.close();
    			}catch (IOException e){
    		System.out.println("close-Exception :"+e.toString());
    			} } }
    

    文件流 (2)

              

            FileWriter fw = null;
    	try{
    		fw = new FileWriter("Test.txt");
    		fw.write("text");
    	}
    	catch (IOException e){
    		System.out.println(e.toString());
    	}
    	finally{
    		If(fw!=null)
    		try{
    		 fw.close();
    		}
    		catch (IOException e){
    			System.out.println(e.toString());
                }	
            }
    

    注意:

    • 定义文件路径时,注意:可以用“/”或者“\”。
    • 在写入一个文件时,如果目录下有同名文件将被覆盖。
    • 在读取文件时,必须保证该文件已存在,否则出异常。

    字节流:

    FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                //1.创建File对象
                File file = new File("char8.txt");
                File file2 = new File("char9.txt");
                //2.创建流的对象
                fis = new FileInputStream(file);
                fos = new FileOutputStream(file2);
                //3.读内容和写内容
                byte[] b = new byte[1024];
                int len = 0;
                while ((len = fis.read(b)) != -1) {
                    //将数组中的内容写到目标文件中
                    fos.write(b, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                //4.关流
                try {
                    if(fos != null){
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if(fis != null){
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    

    字符流:

    /*
    	 * FileWriter
    	 */
    	@Test
    	public void test3() throws Exception{
    		
    		FileWriter writer = new FileWriter("jjj.txt");
    		
    		writer.write("中国你好我爱你么么哒".toCharArray());
    		
    		writer.close();
    	}
    	
    	/*
    	 * FileReader : 读取中文不会发生乱码的问题
    	 */
    	@Test
    	public void test() throws Exception{
    		
    		FileReader reader = new FileReader("aaa.txt");
    		
    		char[] c = new char[500];
    		int len = 0;
    		while((len = reader.read(c)) != -1){
    //			System.out.println(new String(c, 0, len));
    			for (int i = 0; i < len; i++) {
    				System.out.println(c[i]);
    			}
    		}
    		
    		reader.close();
    	}

    4、缓冲流的使用

    为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组

    根据数据操作单位可以把缓冲流分为:

    • BufferedInputStream 和 BufferedOutputStream
    • BufferedReader 和 BufferedWriter

    缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法

    对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush()将会使内存中的数据立刻写出

            

    4.1 处理流之一:缓冲流

                    File descFile = new File(desc);
    		File srcFile = new File(src);
    		
    		FileInputStream fis = new FileInputStream(srcFile);
    		BufferedInputStream bis = new BufferedInputStream(fis);
    		
    		
    		FileOutputStream fos = new FileOutputStream(descFile);
    		BufferedOutputStream bos = new BufferedOutputStream(fos);
    		
    		
    		byte[] b = new byte[1024];
    		int len = 0;
    		while((len = bis.read(b)) != -1){
    			bos.write(b, 0, len);
    		}
    		
    		
    		bos.close();
    		bis.close();
    		fis.close();
    		fos.close();
            /*
    	 * BufferedWriter
    	 */
    	@Test
    	public void test2() throws Exception{
    		FileWriter writer = new FileWriter("cdf.txt");
    		
    		BufferedWriter bw = new BufferedWriter(writer);
    		
    		bw.write("圆圆么么哒");
    		
    		bw.close();
    		writer.close();
    	}
    
    	
    	/*
    	 * BufferedReader
    	 */
    	@Test
    	public void test() throws Exception{
    		
    		FileReader reader = new FileReader("aaa.txt");
    		//创建缓冲字符流
    		BufferedReader br = new BufferedReader(reader);
    		
    		/*
    		 * 第一种读取文件内容
    		 */
    //		char[] c = new char[100];
    //		int len = 0;
    //		while((len = br.read(c)) != -1){
    //			System.out.println(new String(c,0,len));
    //		}
    		
    		/*
    		 * 第二种读取文件内容
    		 * readLine() : 读取一行
    		 */
    		String str="";
    		while((str = br.readLine()) != null){
    			System.out.println(str);
    		}
    		
    		br.close();
    		reader.close();
    	}

    5、转换流的使用

    作用:

    1. 将读取文件的字节流转换成字符流,将写入文件内容的字符流转成字节流
    2. 转换编码集 (读入的文件比如是UTF-8,写入的文件的可以变成GBK
    3. 注意:InputStreamReader设置的编码集必须和读取文件的编码集是一致的。

             

             

               

    代码:

                    // 读取的文件
    		File file = new File("demo.txt");
    		// 创建一个字节流,对接在demo.txt上
    		FileInputStream fis = new FileInputStream(file);
    		// 创建一个转换流 - 字节转字符
    		InputStreamReader isr = new InputStreamReader(fis);
    
    		// 写入的文件
    		File file2 = new File("demo2.txt");
    		// 创建一个字节流,对接在demo2.txt上
    		FileOutputStream fos = new FileOutputStream(file2);
    		// 创建一个转换流 - 字符转字节
    		OutputStreamWriter osw = new OutputStreamWriter(fos);
    
    		char[] c = new char[1024];
    		int len = 0;
    		while ((len = isr.read(c)) != -1) {
    			osw.write(c, 0, len);
    		}
    
    		osw.close();
    		isr.close();
    		fos.close();
    		fis.close();

    图示:

                    

    6、字符编码集

            

             

    7、其他流的使用:标准输入输出流、打印流

    7.1 标准输入输出流

    • System.in和System.out分别代表了系统标准的输入和输出设备
    • 默认输入设备是键盘,输出设备是显示器
    • System.in的类型是InputStream
    • System.out的类型是PrintStream,其是OutputStream的子类FilterOutputStream 的子类
    • 通过System类的setIn,setOut方法对默认设备进行改变。    
                public static void setIn(InputStream in)
                public static void setOut(PrintStream out)

    代码示例:

        /*
         * 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
         * 直至当输入“e”或者“exit”时,退出程序。
         */
        @Test
        public void test2() throws Exception{
            /*
             * 1.从控制台读取数据
             * 2.将字节流转成字符流
             * 3.使用缓冲流
             */
             //将字节流转换成字符流
            InputStreamReader isr = new InputStreamReader(System.in);
            //创建字符缓冲流
            BufferedReader br = new BufferedReader(isr);
            while(true){
                //读取控制台上的数据
                String str = br.readLine();
                //判断如果是"e"/"exit"那么就退出程序,否则全部转成大写并输出
                if("e".equalsIgnoreCase(str) || "exit".equalsIgnoreCase(str)){
                    //关流
                    br.close();
                    isr.close();
                    return;
                }else{
                    System.out.println(str.toUpperCase());
                }
            }
        }

    7.2 打印流

          

    代码:

    @Test
        public void test() {
            /*
             * 第一步 创建一个连接text.txt的管道
             * 第二步  将输入到控制台的管道改成输入到text.txt
             * 第步  输入内容
             */
            FileOutputStream fos = null;
            try {
                //创建一个输出流
                fos = new FileOutputStream(new File("text.txt"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            
            // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '
    ' 时都会刷新输出缓冲区)
            PrintStream ps = new PrintStream(fos, true);
            
            
            
            /*
             * 第二步  将输入到控制台的管道改成输入到text.txt
             */
            // 把标准输出流(控制台输出)改成文件
            System.setOut(ps);  //在程序运行时只能设置一次。
    
            
            /*
             *  第步  输入内容
             */
            for (int i = 0; i <= 10; i++) {
                System.out.print("a");
            }
            
            ps.close();
    
        }
    

    7.3 数据流

              

    代码:

        /*
         * 输入流
         *
         * 注意 : 写入数据的格式  和 读取数据的格式必须一致
         */
        @Test
        public void test() throws Exception{
            
            FileInputStream fis = new FileInputStream("abc.txt");
            DataInputStream dis = new DataInputStream(fis);
            
            
            String readUTF = dis.readUTF();
            int readInt = dis.readInt();
            boolean boo = dis.readBoolean();
            
            System.out.println(readUTF);
            System.out.println(readInt);
            System.out.println(boo);
            
            dis.close();
            fis.close();
            
        }
        
        /*
         * 输出流
         */
        @Test
        public void test2() throws Exception{
            FileOutputStream out = new FileOutputStream("abc.txt");
            DataOutputStream dos = new DataOutputStream(out);
            
            dos.writeUTF("abcde");
            dos.writeInt(10);
            dos.writeBoolean(true);
            
            
            dos.close();
            out.close();
        }
    

    7.4 对象流的使用

    序列化 :用ObjectOutputStream类保存基本类型数据或对象的机制 (保存对象,或者发送对象)
    反序列化 :用ObjectInputStream类读取基本类型数据或对象的机制(读取对象,接收对象)

    * 注意:

    1. 序列化对象的类必须实现Serializable接口
    2. 序列化对象的类的属性除基本类型外,也必须全部实现Serializable接口
    3. 需要声明一个 serialVersionUID (如果不显示声明系统会默认填加一个)
    4. 不能序列化static和transient修饰的成员变量

    代码:

            /*
    	 * ObjectInputStream
    	 */
    	@Test
    	public void test() throws Exception{
    		FileInputStream fis = new FileInputStream("aaa.txt");
    		ObjectInputStream ois = new ObjectInputStream(fis);
    		
    		Person p = (Person) ois.readObject();
    		p.show();
    		Person p2 = (Person) ois.readObject();
    		p2.show();
    		
    		
    		
    		ois.close();
    		fis.close();
    		
    	}
    	/*
    	 * ObjectOutputStream
    	 */
    	@Test
    	public void test2() throws Exception{
    	
    		FileOutputStream fos = new FileOutputStream("aaa.txt");
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    		
    		//写数据
    		oos.writeObject(new Person("aa",18,new Address("aaaa",20)));
    		oos.writeObject(new Person("bb",18,new Address("bbbb",20)));
    		
    		oos.close();
    		
    	}

    9、RandomAccessFile类的使用

    需求:
    文件中的内容 : abcdefg   
    需求:  在c的后面插入AAA

    1. 先将指针移动到c的后面
    2. 读取c后面的所数据并保存到一个临时变量中
    3. 指针回移,移动到c的后面
    4. 写入需要插入的数据
    5. 写入临时变量中的数据

    代码

            @Test
    	public void test4() throws Exception{
    		RandomAccessFile accessFile = new RandomAccessFile("access.txt", "rw");
    		//移动指针到c后面
    		accessFile.seek(3);
    		//将c后面的数据读出并保存到一个临时变量中。
    //		String str = accessFile.readLine();
    		String str = "";
    		//读取插入位置后面的所内容
    		byte[] b = new byte[1024];
    		int len = 0;
    		while((len = accessFile.read(b)) != -1){
    			str += new String(b,0,len);
    		}
    		//指针回移
    		accessFile.seek(3);
    		//插入数据
    		accessFile.write("AAA".getBytes());
    		accessFile.write(str.getBytes());
    		//关流
    		accessFile.close();
    	}
  • 相关阅读:
    软件工程周总结09
    单词统计
    第一期冲刺03
    第一期冲刺02
    第一期冲刺01
    人月神话阅读笔记03
    团队冲刺四
    团队冲刺三
    团队冲刺二
    单词统计
  • 原文地址:https://www.cnblogs.com/wushaopei/p/12259592.html
Copyright © 2011-2022 走看看