精华内容
下载资源
问答
  • 输入输出有关的类在java.io包下,jdk1.4起加了java.nio包,jdk1.7对其做了改进,称为nio2。 按中处理的数据是以字节(8位)为单位还是以字符(16位)为单位分为字节和字符字节: InputStream和...

    输入输出流有关的类在java.io包下,jdk1.4起加了java.nio包,jdk1.7对其做了改进,称为nio2。


    按流中处理的数据是以字节(8位)为单位还是以字符(16位)为单位分为字节流和字符流

    字节流: InputStream和OutputStream


    InputStream

    InputStream是抽象类,不能直接用new InputStream()构造实例。 FileInputStream是InputStream的子类,可以生成实例。 FileInputStream有三个构造方法,最常用的构造方法如下:

    Public FileInputStream(String fileName) throws FileNotFoundException
    Public FileInputStream(File file) throws FileNotFoundException
    //fileName用来指定输入文件名及其路径,file是一个File对象

    字节流的层次结构

    InputStream类的read()方法:逐字节以二进制的原始方式读取数据

    public int read();//读入一个字节,-1表示无
    public int read(byte b[]);//返回读入的字节数
    public int read(byte[] b,int off.int len);//返回从某个位置开始制定长度的字节数


    OutputStream

    常用方法:

    //写一个字节
    void write( int ) throws IOException 
    //关闭输出流
    void close( ) throws IOException 
    //强行将缓冲区的数据写到目的地。
    void flush( ) throws IOException 
    //写一个字节数组
    void write(byte[ ] b) throws IOException 
        void write(byte[ ] b, int offset, int length ) throws IOException 

    OutputStream是抽象类,不能直接用new OutputStream()构造实例。 FileOutputStream是OutputStream的子类,可以生成实例。 FileOutputStream最常用的构造方法如下:

    Public FileOutputStream(String name) throws FileNotFoundException
    Public FileOutputStream(String name,boolean append) throws FileNotFoundException
    
    //Name用来指定输入文件名及其路径,append为true时数据将添加到文件已有内容的末尾



    利用字节流复制文件

    import java.io.*;
    class CopyAFile 
    {
        public static void main(String[] args) 
        {
            InputStream in;
            OutputStream out;
            try
            {
                in=new FileInputStream("test.txt");
                out=new FileOutputStream("copyResult.txt");
    //          out=new FileOutputStream("copyResult.txt",true);
                int aByte;
                aByte=in.read();
                while (aByte!=-1)
                {
                    out.write(aByte);
                    aByte=in.read();
                }
                in.close();
                out.close();
                System.out.println("文件复制完毕。test.txt已经复制到copyResult.txt中。");
            }
            catch(FileNotFoundException e)
            {
                System.out.println("当前目录下文件test.txt不存在!");
            }
            catch(IOException e)
            {
                System.out.println("发生输入输出错误!");
            }
        }
    }




    字符流: Reader和Writer

    字符流不一定对应两个字节,要考虑到编码问题。

    字符流层次结构

    Reader类读取的是字符,而不是字节。
    Reader类的重要方法read():

    public int read();//需要将int转为char
    public int read(char b[]);
    public int read(char[] b,int off,int len)




    节点流和过滤流

    节点流(Node Stream) :直接与原始数据存在的特定介质(如磁盘文件或其他外部设备、内存某区域或其他程序)打交道的流,在流的序列中离程序最远。
    过滤流 (Filter Stream):使用其它的流作为输入源或输出目的地,对流中的数据提供进一步处理的流。其他的流可以是节点流,也可以是另一种过滤流。过滤流不能单独使用

    一个输入流链或输出流链中一定有且只有一个节点流;可以没有,也可以有多个过滤流。

    过滤流和节点流的套接:

    InputStream in;
    in=new BufferedInputStream(new FileInputStream("test.txt"));
    
    BufferedReader in = new BufferedReader(new FileReader(file));
    
    BufferedReader in2 = new BufferedReader(new inputStreamReader(new FileInputStream(file),"utf-8"));
    s = in2.readLine();

    流的套接

    标准输入输出流和错误流

    1.System.out: -PrintStream类型
    把输出送到缺省的显示(通常是显示器)

    2.System.in - InputStream类型
    从标准输入获取输入(通常是键盘)

    3.System.err - PrintStream类型
    out的用法大家已熟知了,err的用法与out一样

    System是final类,in,out,err是System的静态成员变量,因此可以用System.in等形式直接使用。

    由于System,.in是InputStream类型,因此需要包装 :

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    br.readLine();

    注:
    1.输入/输出流的方法会抛出异常,因此必须进行异常处理
    2.标准输入/输出/错误流对象System.in, System.out、 System.err 始终存在 ,不需要实例化,也 不需要关闭

    最后附上两张图
    1、常用节点流:
    常用节点流
    2.常用过滤流:
    常用过滤流

    展开全文
  • JAVA IO一、相关概念1、分类:区别和联系 一、相关概念 I/O: Input/Output Stream,文件输入输出。 1、分类: 根据读写操作/数据流动的方向不同分为:输入 和 输出(站在程序的角度)。 其中输入就是指...

    一、相关概念

    I/O流: Input/Output Stream,文件输入输出流。

    1、分类:

    • 输入流 和 输出流:(站在程序的角度) 根据读写操作/数据流动的方向区分。

      • 其中输入流就是指读取文件中的内容输入到程序中的流,也就是读文件。
      • 其中输出流就是指将程序中的内容输出到文件中的流,也就是写文件。
    • 字节流 和 字符流:根据读写操作的基本单位分。

      • 参考: https://blog.csdn.net/yogima/article/details/78705411
      • 其中字节流就是指以字节为基本单位进行读写的流,可以处理任何文件。字节(8位 )
      • 字符流就是指以字符(2个字节)为基本单位进行读写的流,只能处理文本文件。字符(16位)。Reader和Writer
    • 数据传输方式:

      • 节点流(Node Stream 直接和文件打交道)
      • 包装流(又称处理流、过滤流、缓冲流)程序和文件之间有管道,不直接接触。
    • 缓冲流:

      • 什么是缓冲流:参考 https://www.cnblogs.com/aademeng/articles/10880511.html
      • 意义:在内存与硬盘之间创建一个大小合适的缓冲区,当内存和硬盘进行数据访问时,能提高访问硬盘的次数,提高效率。
        • 是一个包装流,目的起缓冲作用.包括:
        • BufferedInputStream:字节输入缓冲流
        • BufferedOutputStream:字节输出缓冲流
        • BufferedReader:字符输入缓冲流
        • BufferedWriter::字符输出缓冲流
          字节流图解
          字符流
          字符流套接

    区别和联系

    1、节点流和处理流

    • (1)节点流是低级流,直接跟数据源相接。

      • 处理流(也叫包装流)把节点流包装了一层,属于修饰器设计模式,不会直接与数据源相连,通过处理流来包装节点流既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
    • (2)处理流的功能主要体现在以下两个方面:

      • 1.性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
      • 2.操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的内容,而不是输入/输出一个或多个水滴处理流可以嫁接在任何已存在的流的基础上。
    • 节点流(Node Stream) :直接与原始数据存在的特定介质(如磁盘文件或其他外部设备、内存某区域或其他程序)打交道的流,在流的序列中离程序最远。

    • 过滤流 (Filter Stream):使用其它的流作为输入源或输出目的地,对流中的数据提供进一步处理的流。其他的流可以是节点流,也可以是另一种过滤流。过滤流不能单独使用。

    • 一个输入流链或输出流链中一定有且只有一个节点流;可以没有,也可以有多个过滤流。

    2、字符流和字节流

    代码

    • 1、字节流: InputStream和OutputStream
      • InputStream
        InputStream是抽象类,不能直接用new InputStream()构造实例。 FileInputStream是InputStream的子类,可以生成实例。 FileInputStream有三个构造方法,最常用的构造方法如下:
        
        Public FileInputStream(String fileName) throws FileNotFoundException
        Public FileInputStream(File file) throws FileNotFoundException
        //fileName用来指定输入文件名及其路径,file是一个File对象
        
        InputStream类的read()方法:逐字节以二进制的原始方式读取数据
        
        public int read();//读入一个字节,-1表示无
        public int read(byte b[]);//返回读入的字节数
        public int read(byte[] b,int off.int len);//返回从某个位置开始制定长度的字节数
        
      • OutputStream
        构造方法:
        OutputStream是抽象类,不能直接用new OutputStream()构造实例。 FileOutputStream是OutputStream的子类,可以生成实例。 FileOutputStream最常用的构造方法如下:
        
        Public FileOutputStream(String name) throws FileNotFoundException
        Public FileOutputStream(String name,boolean append) throws FileNotFoundException
        //Name用来指定输入文件名及其路径,append为true时数据将添加到文件已有内容的末尾
        
        常用方法:
        //写一个字节
        void write( int ) throws IOException 
        //关闭输出流
        void close( ) throws IOException 
        //强行将缓冲区的数据写到目的地。
        void flush( ) throws IOException 
        //写一个字节数组
        void write(byte[ ] b) throws IOException 
            void write(byte[ ] b, int offset, int length ) throws IOException 
        
    • 利用字节流复制文件
    import java.io.*;
    class CopyAFile 
    {
        public static void main(String[] args) 
        {
            InputStream in;
            OutputStream out;
            try
            {
                in=new FileInputStream("test.txt");
                out=new FileOutputStream("copyResult.txt");
    //          out=new FileOutputStream("copyResult.txt",true);
                int aByte;
                aByte=in.read();
                while (aByte!=-1)
                {
                    out.write(aByte);
                    aByte=in.read();
                }
                in.close();
                out.close();
                System.out.println("文件复制完毕。test.txt已经复制到copyResult.txt中。");
            }
            catch(FileNotFoundException e)
            {
                System.out.println("当前目录下文件test.txt不存在!");
            }
            catch(IOException e)
            {
                System.out.println("发生输入输出错误!");
            }
        }
    }
    
    • 2、字符流: Reader和Writer

      • 字符(16位)流不一定对应两个字节,要考虑到编码问题。
      • 只能操作文本文件。
      Reader类读取的是字符,而不是字节。 
      Reader类的重要方法read():
      
      public int read();//需要将int转为char
      public int read(char b[]);
      public int read(char[] b,int off,int len)
      
    • 3、滤流和节点流的套接:

    InputStream in;
    in=new BufferedInputStream(new FileInputStream("test.txt"));
    BufferedReader in = new BufferedReader(new FileReader(file));
    
    BufferedReader in2 = new BufferedReader(new inputStreamReader(new FileInputStream(file),"utf-8"));
    s = in2.readLine();
    

    套接流

    嵌套的IO流关闭的问题

    参考:https://blog.csdn.net/menghuanzhiming/article/details/77945822

    • 当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法

    一般情况下是:

    • 先打开的后关闭,后打开的先关闭;
    • 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
    • 例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
    • 如果将节点流关闭以后再关闭处理流,会抛出IO异常;
    展开全文
  • JAVA:IO流 之 节点流与处理流(2)

    万次阅读 多人点赞 2017-05-15 15:37:24
    1. 流的分类 按数据流的方向不同:输入流,输出流。 按处理数据单位不同:字节流,字符流。 (1) 字节流:数据流中最小的数据单元是字节。...(2)程序通过一个间接流类去调用节点流类,以达到更加灵活方...

    微信扫一扫关注该公众号
    在这里插入图片描述

    #1. 流的分类

    • 按数据流的方向不同:输入流,输出流。

    • 按处理数据单位不同:字节流,字符流。
      (1) 字节流:数据流中最小的数据单元是字节。
      (2)字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

    • 按功能不同:节点流,处理流。
      (1)程序用于直接操作目标设备所对应的类叫节点流。
      (2)程序通过一个间接流类去调用节点流类,以达到更加灵活方便地读写各种类型的数据,这个间接流类就是处理流。
      #2. 节点流
      ##2.1 节点流的类型
      这里写图片描述

    • (1)File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream。、

    • (2)Memory
      1)从/向内存数组读写数据: CharArrayReader与 CharArrayWriter、ByteArrayInputStream与ByteArrayOutputStream。
      2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream。

    • (3)Pipe管道流。 实现管道的输入和输出(进程间通信): PipedReader与PipedWriter、PipedInputStream与PipedOutputStream。
      ##2.2 节点流执行的图示
      这里写图片描述
      #3. 处理流
      ##3.1 处理流的类型
      这里写图片描述

    • (1)Buffering缓冲流:在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader与BufferedWriter、BufferedInputStream与BufferedOutputStream。

    • (2)Filtering 滤流:在数据进行读或写时进行过滤:FilterReader与FilterWriter、FilterInputStream与FilterOutputStream。

    • (3)Converting between Bytes and Characters 转换流:按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader):InputStreamReader、OutputStreamWriter。

    • (4)Object Serialization 对象流 :ObjectInputStream、ObjectOutputStream。

    • (5)DataConversion数据流: 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream 。

    • (6)Counting计数流: 在读入数据时对行记数 :LineNumberReader、LineNumberInputStream。

    • (7)Peeking Ahead预读流: 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream。

    • (8)Printing打印流: 包含方便的打印方法 :PrintWriter、PrintStream。
      ##3.2 处理流执行的图示
      这里写图片描述
      ##3.3 缓冲流

    • 【1】对I/O进行缓冲是一种常见的性能优化,缓冲流为I/O流增加了内存缓冲区,增加缓冲区的两个目的:
      (1)允许Java的I/O一次不只操作一个字符,这样提高䇖整个系统的性能;
      (2)由于有缓冲区,使得在流上执行skip、mark和reset方法都成为可能。

    • 【2】缓冲流:它是要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,
      提高了读写的效率,同时增加了一些新的方法。例如:BufferedReader中的readLine方法,
      BufferedWriter中的newLine方法。

    • 【3】J2SDK提供了4种缓存流,常用的构造方法为:

    //字符输入流
    BufferedReader(Reader in)//创建一个32字节的缓冲区
    BufferedReader(Reader in, int size)//size为自定义缓存区的大小
    
    //字符输出流
    BufferedWriter(Writer out)
    BufferedWriter(Writer out, int size)
    
    //字节输入流
    BufferedInputStream(InputStream in)
    BufferedInputStream(InputStream in, int size)
    
    //字节输出流
    BufferedOutputStream(OutputStream in)
    BufferedOutputStream(OutputStream in, int size)
    
    • 【4】其他
      (1)缓冲输入流BufferedInputSTream除了支持read和skip方法意外,还支持其父类的mark和reset方法;
      (2)BufferedReader提供了一种新的ReadLine方法用于读取一行字符串(以\r或\n分隔);
      (3)BufferedWriter提供了一种新的newLine方法用于写入一个行分隔符;
      (4)对于输出的缓冲流,BufferedWriter和BufferedOutputStream,写出的数据会先在内存中缓存,
      使用flush方法将会使内存的数据立刻写出。

    • 示例1:

    import java.io.*;
    public class TestBufferStream1 {
      public static void main(String[] args) {
        try {
          FileInputStream fis = new FileInputStream(
    		  "d:\\JavaProject\\demo13\\ProcessingStream\\TestBufferStream1.java");
          BufferedInputStream bis = new BufferedInputStream(fis);
          int c = 0;
          System.out.println((char)bis.read());
          System.out.println((char)bis.read());
          bis.mark(100);/*在当前输入流的当前位置上做一个标志,允许最多再读入100个字节*/
          for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
            System.out.print((char)c+" ");
          }
          System.out.println(); 
          bis.reset();/*把输入指针返回到以前所做的标志处*/
          for(int i=0;i<=10 && (c=bis.read())!=-1;i++){
            System.out.print((char)c+" ");
          }
          bis.close();
        } catch (IOException e) {e.printStackTrace();}
      }
    }
    
    • 示例2:
    import java.io.*;
    public class TestBufferStream2
    {
    	public static void main(String[] args)
    	{
    	try{
    	BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\JavaProject\\demo13\\BufferStream\\dat2.txt"));
    	BufferedReader br = new BufferedReader(new FileReader("D:\\JavaProject\\demo13\\BufferStream\\dat2.txt"));
    	String s = null;
    	for(int i=0;i<10;i++)
    	{
    		s = String.valueOf(Math.random());//产生一个小于1的正的随机数,并转换成字符串形式
    		bw.write(s);//把字符串s写入到dat2.txt文件中
    		bw.newLine();//写入一个行分隔符
    	}
    	bw.flush();//使用flush方法将会使内存的数据立刻写出
    
    	while((s=br.readLine()) != null)
    	{
    		System.out.println(s);
    	}
    	bw.close();
    	br.close();
    	}
    	catch(IOException e)
    	{
    		e.printStackTrace();
    	}
    
    	}
    }
    

    ##3.4 转换流

    • 转换流有两种:
      (1)InputStreamReader:将字节流转换为字符流;
      (2)OutputStreamWriter:将字符流转换为字节流。
    • 什么时候使用转换流?由以下分析: 流对象很多,就要明确使用哪个流对象。
    通过三点来完成: 
    	1、明确数据的来源和数据到达的目的地。
    	             来源:输入流 [InputStream,Reader]。 
    	             目的:输出流 [OutputStream,Writer]。 
    	2、操作的数据是否是纯文本。  
    	             是:字符流,使用Reader与Writer; 
    	             否:字节流,使用InputStream与OutputStream。 
    	3、明确要使用哪个具体的对象。 通过设备来进行区分: 
    	             源设备:内存用数组,硬盘就加file,键盘用System.in; 
    	             目的设备:内存用数组,硬盘就加file,键盘用System.out。 
    	4、明确是否还需要其他额外功能:例如 
    	            (1)是否需要较高的效率,即是否需要使用缓冲区,是就加上Buffered;
    	            (2)是否需要转换,是,就使用转换流,InputStreamReader 和 OutputStreamWriter。
    
    • 用一个例子简单的说明: 将键盘录入的数据保存到一个文件中,输入“over”时表示录入结束。 详细分析:
    源:从InputStream,Reader中选择; 因为是键盘录入的是纯文本,所以使用Reader。 
    设备:键盘,所以用System.in; 发现System.in是字节流的操作,与Reader(字符流)矛盾,
    这时就要用到转换流 InputStreamReader 。为了提高操作效率,使用缓冲技术,选择BufferedReader。 
    
    目的:从 OutputStream,Writer中选择。 因为是文本文件,所以选择Writer。 
    设备:硬盘上,一个文件,选择FileWriter。 为了提高操作效率,使用缓冲技术,选择BufferedWriter。 
    
    • 示例1:
    import java.io.*; 
    	class ReadinFile 
    		{ 
    			public static void main(String[] args)throws IOException //这里为了方便阅读,先不做异常处理。 
    			{ 
    				BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); 
    				BufferedWriter bufw=new BufferedWriter(new FileWriter("readin.txt")); 
    				String line=null; 
    				while((line=bufr.readLine())!=null) 
    				{ 
    					if("over".equals(line)) break; 
    					bufw.write(line); 
    					bufw.newLine(); 
    				} 
    				bufw.close(); 
    				bufr.close(); 
    			} 
    		}
    
    • 示例2:
    import java.io.*;
    public class TestTransForm 
    {
    	public static void main(String[] args) throws IOException //这里为了方便阅读,先不做异常处理。 
    	{
    		InputStreamReader isr = new InputStreamReader(System.in);
    		BufferedReader br = new BufferedReader(isr);
    		OutputStreamWriter osw = new OutputStreamWriter(
    			                     new FileOutputStream("D:\\JavaProject\\demo13\\TransStream\\TransForm.txt",true));
    		BufferedWriter bw = new BufferedWriter(osw);
    		String str = null;
    		str = br.readLine();
    		while(str != null)
    		{
    			if(str.equalsIgnoreCase("exit")) break;
    			bw.write(str);
    			bw.newLine();
    			str = br.readLine();
    		}
    		br.close();
    		bw.close();
    	}
    }
    
    • 注意:
      (1)构造方法:public FileOutputStream(String name,boolean append) throws FileNotFoundException
      如果append为True,输出字节流就写入文件的末尾,而不是开头(覆盖原来的内容);
      如果append为False,输出字节流就写入文件的开头,即覆盖原来的内容从文件开始处写内容。
      (2)构造方法:public FileOutputStream(String name) throws FileNotFoundException
      每次覆盖原文件的内容,从文件开始处写内容。

    ##3.5 数据流——数据的存储和数据恢复

    • 数据流:DataInputStream和DataOutputStream
      (0)DataInputStream和DataOutputStream是面向字节的,因此要使用InputStream和OutputStream。
      (1)DataInputStream和DataOutputStream分别继承InputStream和OutputStream,
      它们属于处理流,需要分别“套接”在InputStream和OutputStream类型的节点流上。
      (2)DataInputStream和DataOutputStream提供了可以存取与机器无关的Java原始类数据(如:int,double等)的方法。
      (3)DataInputStream和DataOutputStream的构造方法:
         DataInputStream(InputStream in)
    	 DataOutputStream(OutputStream out)
    
    • 示例1:
    import java.io.*;
    public class TestDataStream
    {
    	public static void main(String[] args) throws IOException
    	{
    		FileOutputStream fout = new FileOutputStream("D:/JavaProject/demo13_IO/DataStream/demo.txt",true);
    	    BufferedOutputStream bout = new BufferedOutputStream(fout);
    	    DataOutputStream dout = new DataOutputStream(bout);
    		/*DataOutputStream,BufferedOutputStream,FileOutputStream这里使用了流栈。*/
    
    	    dout.writeInt(110);
    	    dout.writeUTF("hello,中国");
    	    dout.writeFloat(3.14f);
    	    dout.writeChar(97);/*97对应的是'a'*/
            dout.close();/*如果正在使用一个流栈,程序关闭最上面的一个流也就自动的关闭了栈中的所有底层流。*/
    		
    		FileInputStream fin = new FileInputStream("D:/JavaProject/demo13_IO/DataStream/demo.txt");
    		BufferedInputStream bin = new BufferedInputStream(fin);
    		DataInputStream din = new DataInputStream(bin);
    		
    		int i = din.readInt();
    		String str = din.readUTF();
    		float f = din.readFloat();
    		char c = din.readChar();
    		fin.close();/*如果正在使用一个流栈,程序关闭最上面的一个流也就自动的关闭了栈中的所有底层流。*/
            System.out.println("int:"+i+"\nString:"+str+"\nfloat:"+f+"\nchar:"+c);
    	}
    	
    }
    
    • 编译,运行:
    D:\JavaProject\demo13_IO\DataStream>javac TestDataStream.java
    
    D:\JavaProject\demo13_IO\DataStream>java TestDataStream
    int:110
    String:hello,中国
    float:3.14
    char:a
    
    • 注意:
            int i = din.readInt();
    		String str = din.readUTF();
    		float f = din.readFloat();
    		char c = din.readChar();
    		/*此段代码的顺序不能乱,要保证先写入的先读出来的原则,否则会出现错误。
    		*    因此,我们在写代码的时候,我们必须:
    		*         要么为文件中的数据采用固定的格式;
    		*         要么将额外的信息保存到文件中,以便能够对其进行解析以确定数据的寻访位置。
    		*/
    
    展开全文
  • IO原理及的分类 IO原理 I/O是Input/Output的缩写, I/O技术是非常...java.io包下提供了各种“”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。 输入input**:**读取外部数据(磁盘...

    IO流原理及流的分类

    IO原理

    • I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。

    • Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。

    • java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
      在这里插入图片描述

    • 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。

    • 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

    流的分类

    • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)

    • 数据流的流向不同分为:输入流,输出流

    • 按流的角色的不同分为:节点流,处理流

    (抽象基类)字节流字符流
    输入流InputStreamReader
    输出流OutputStreamwriter

    各种流的原理和运行过程:
    在这里插入图片描述

    IO流体系

    在这里插入图片描述

    InputStream & OutputStream

    • InputStream 和 OutpitStream字节输入/输出的基类。

    • InputStream(典型实现:FileInputStream

      • int read():从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
      • int read(byte[] b):从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。
      • int read(byte[] b, int off, int len):将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1。
      • public void close() throws IOException
        • 关闭此输入流并释放与该流关联的所有系统资源。
    • OutputStream(典型实现:FileOutputStream

      • void write(int b):将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。
      • void write(byte[] b):将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。
      • void write(byte[] b,int off,int len):将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
      • public void flush()throws IOException :刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。
      • public void close() throws IOException:关闭此输出流并释放与该流关联的所有系统资源。
    • 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源

    • FileInputStream 用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader。

    • FileOutputStream 从指定字节写入文件中。要写入字符流,需要使用 FileWriter。

    节点流(文件流)

    FileInputStream&FileOutputStream
    读取文件:

    1. 建立一个流对象,将已存在的一个文件加载进流。
    2. 创建一个临时存放数据的数组。
    3. 调用流对象的读取方法将流中的数据读入到数组中。
    4. 关闭资源。
    //建立一个流对象,将已存在的一个文件加载进流。
    FileReader fr = null;
    try {
        fr = new FileReader(new File("c:\\test.txt"));
        //创建一个临时存放数据的数组。
        char[] buf = new char[1024];
        int len;
        //调用流对象的读取方法将流中的数据读入到数组中。
        while ((len = fr.read(buf)) != -1) {
            System.out.print(new String(buf, 0, len));
        }
    } catch (IOException e) {
        System.out.println("read-Exception :" + e.getMessage());
    } finally {
        if (fr != null) {
            try {
                //关闭资源。
                fr.close();
            } catch (IOException e) {
                System.out.println("close-Exception :" + e.getMessage());
            }
        }
    }
    
    

    写入文件:

    1. 创建流对象,建立数据存放文件。
    2. 调用流对象的写入方法。将数据写入流。
    3. 关闭流资源,并将流中的数据清空到文件。
    //创建流对象,建立数据存放文件。
    FileWriter fw = null;
    try {
        fw = new FileWriter(new File("Test.txt"));
        //调用流对象的写入方法。将数据写入流。
        fw.write("xiaowangzi");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {//关闭流资源,并将流中的数据清空到文件。
        if (fw != null)//判断是否为空,不为空在关闭
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
        }
    }
    
    

    注意点:

    • 定义文件路径时,注意:可以用“/”或者“\”。

    • 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖。

    • 如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容。

    • 在读取文件时,必须保证该文件已存在,否则报异常。

    • 字节流操作字节,比如:.mp3,.avi,.rmvb,mp4,.jpg,.doc,.ppt

    • 字符流操作字符,只能操作普通文本文件。最常见的文本文件:.txt,.java,.c,.cpp 等语言的源代码。尤其注意.doc,excel,ppt这些不是文本文件。

    缓冲流

    • 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。

    在这里插入图片描述

    • 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
      • BufferedInputStream BufferedOutputStream
      • BufferedReader BufferedWriter

    缓冲流原理:

    在这里插入图片描述
    在这里插入图片描述
    代码实现:

    BufferedReader br = null;
    BufferedWriter bw = null;
    try {
        // 创建缓冲流对象:它是处理流,是对节点流的包装
        br = new BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
        bw = new BufferedWriter(new FileWriter("d:\\IOTest\\dest.txt"));
        String str;
        while ((str = br.readLine()) != null) { // 一次读取字符文本文件的一行字符
            bw.write(str); // 一次写入一行字符串
            bw.newLine(); // 写入行分隔符
        }
        bw.flush(); // 刷新缓冲区
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭IO流对象
        try {
            if (bw != null) {
                bw.close(); // 关闭过滤流时,会自动关闭它所包装的底层节点流
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (br != null) {
                br.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    

    转换流

    • Java API提供了两个转换流:
      • InputStreamReader:将InputStream转换为Reader
      • OutputStreamWriter:将Writer转换为OutputStream

    InputStreamReader

    • 实现将字节的输入流按指定字符集转换为字符的输入流。

    • 需要和InputStream“套接”。

    • 构造器

      • public InputStreamReader(InputStream in)
      • public InputSreamReader(InputStream in,String charsetName)
    如: Reader isr = new InputStreamReader(System.in,”gbk”);
    

    OutputStreamWriter

    • 实现将字符的输出流按指定字符集转换为字节的输出流。

    • 需要和OutputStream“套接”。

    • 构造器

      • public OutputStreamWriter(OutputStream out)
      • public OutputSreamWriter( OutputStream out,String charsetName)

    转换流原理:

    在这里插入图片描述

    代码实现:

    public void testMyInput() throws Exception {
        FileInputStream fis = new FileInputStream("dbcp.txt");
        FileOutputStream fos = new FileOutputStream("dbcp5.txt");
    
        InputStreamReader isr = new InputStreamReader(fis, "GBK");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
    
        BufferedReader br = new BufferedReader(isr);
        BufferedWriter bw = new BufferedWriter(osw);
    
        String str = null;
        while ((str = br.readLine()) != null) {
            bw.write(str);
            bw.newLine();
            bw.flush();
        }
        bw.close();
        br.close();
    }
    
    

    常见的编码表

    • ASCII:美国标准信息交换码。

      • 用一个字节的7位可以表示。
    • ISO8859-1:拉丁码表。欧洲码表

      • 用一个字节的8位表示。
    • GB2312:中国的中文编码表。最多两个字节编码所有字符

    • GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码。

    • Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。

    • UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

    标准输入、输出流

    • 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”时,退出程序。

    System.out.println("请输入信息(退出输入e或exit):");
    // 把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
    try {
        while ((s = br.readLine()) != null) { // 读取用户输入的一行数据 --> 阻塞程序
            if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) {
                System.out.println("安全退出!!");
                break;
            }
            // 将读取到的整行字符串转成大写输出
            System.out.println("-->:" + s.toUpperCase());
            System.out.println("继续输入信息");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null) {
                br.close(); // 关闭过滤流时,会自动关闭它包装的底层节点流
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    

    打印流

    • 实现将基本数据类型的数据格式转化为字符串输出

    • 打印流:PrintStreamPrintWriter

      • 提供了一系列重载的print()和println()方法,用于多种数据类型的输出
      • PrintStream和PrintWriter的输出不会抛出IOException异常
      • PrintStream和PrintWriter有自动flush功能
      • PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。
      • System.out返回的是PrintStream的实例

    代码实现:

    PrintStream ps = null;
    try {
        FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
        // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
        ps = new PrintStream(fos, true);
        if (ps != null) {// 把标准输出流(控制台输出)改成文件
            System.setOut(ps);
        }
        for (int i = 0; i <= 255; i++) { // 输出ASCII字符
            System.out.print((char) i);
            if (i % 50 == 0) { // 每50个数据一行
                System.out.println(); // 换行
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ps != null) {
            ps.close();
        }
    }
    
    

    对象流

    ObjectInputStream和OjbectOutputSteam

    • 用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

    • 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制

    • 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

    • ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

    对象的序列化

    • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

    • 如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。否则,会抛出NotSerializableException异常

      • Serializable
      • Externalizable
    • 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

      • private static final long serialVersionUID;
      • serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
      • 如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
    • 若某个类实现了 Serializable 接口,该类的对象就是可序列化的:

      • 创建一个 ObjectOutputStream
      • 调用 ObjectOutputStream 对象的 writeObject(对象)方法输出可序列化对象
      • 注意写出一次,操作flush()一次
    • 反序列化

      • 创建一个 ObjectInputStream
      • 调用 readObject**()** 方法读取流中的对象

    序列化过程:
    将内存中的java对象或基本数据类型的变量写出到文件中或通过网络传输出去
    代码实现:

    @Test
    public void test1() throws IOException{
    	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));	
    	oos.writeObject(new String("Tom"));
    	oos.writeObject(new String("Jerry"));
    	
    	oos.writeObject(new Person("Jack",12));
    	oos.writeObject(new Person("Jack",12,new Dog("大黄")));
    	
    	oos.close();
    }
    

    反序列化过程:
    将文件中的数据还原为内存中的java对象或基本数据类型的变量
    代码实现:

    @Test
    public void test2() throws ClassNotFoundException, IOException{
    	ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
        String s1 = (String) ois.readObject();
    	String s2 = (String) ois.readObject();
    	
    	Person p1 = (Person) ois.readObject();
    	Person p2 = (Person) ois.readObject();
    	
    	System.out.println(s1);
    	System.out.println(s2);
    	System.out.println(p1);
    	System.out.println(p2);
    	
    	ois.close();
    }
    

    实现序列化的对象所属的类需要满足:

    • 自定义类的对象要想实现序列化需要满足:

      1.需要实现接口:Serializable

      2.需要显式的提供全局常量serialVersionUID,用来唯一的标识当前类

      3.要求对象的实例变量也必须是可序列化的。

      • String、基本数据类型本身就可以序列化
    • 注意:

      • ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

    随机存取文件流

    • 构造器

      • public RandomAccessFile(File file, String mode)
      • public RandomAccessFile(String name, String mode)
    • 创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:

      • r:以只读方式打开
      • rw:打开以便读取和写入
      • rwd:打开以便读取和写入;同步文件内容的更新
      • rws:打开以便读取和写入;同步文件内容和元数据的更新

    RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件

    • 支持只访问文件的部分内容

    • 可以向已存在的文件后追加内容

    使用说明:

    1. RandomAccessFile直接继承于Object,实现了DataInput和DataOutput。
    2. RandomAccessFile既可以作为一个输入流,也可以作为一个输出流。
    3. RandomAccessFile输出到的文件如果不存在,在输出过程中会自动创建,RandomAccessFile输出到的文件如果存在,则是对文件内容的覆盖,默认从文件开头写入数据。

    代码实例:

    public void test1() throws Exception{
    	//1.
    	RandomAccessFile raf1 = new RandomAccessFile("timg.jpg", "r");
    	RandomAccessFile raf2 = new RandomAccessFile("timg4.jpg", "rw");
    	//2.
    	byte[] buffer = new byte[1024];
    	int len;
    	while((len = raf1.read(buffer)) != -1){
    		raf2.write(buffer, 0, len);
    	}
    	//3.
    	raf2.close();
    	raf1.close();
    }
    

    作为一个输出流。
    3. RandomAccessFile输出到的文件如果不存在,在输出过程中会自动创建,RandomAccessFile输出到的文件如果存在,则是对文件内容的覆盖,默认从文件开头写入数据。

    代码实例:

    public void test1() throws Exception{
    	//1.
    	RandomAccessFile raf1 = new RandomAccessFile("timg.jpg", "r");
    	RandomAccessFile raf2 = new RandomAccessFile("timg4.jpg", "rw");
    	//2.
    	byte[] buffer = new byte[1024];
    	int len;
    	while((len = raf1.read(buffer)) != -1){
    		raf2.write(buffer, 0, len);
    	}
    	//3.
    	raf2.close();
    	raf1.close();
    }
    

    就写到这里啦,后天就是十一了,去转转散散心。不过博客不会停更的,放心哈。
    换了一个编辑器如果有什么错误请大家指出啊。

    上一篇文章:JavaIO流_上(File类的使用)
    下一篇文章:JavaIO流_下(NIO.2中Path、Paths、Files类的使用)

    展开全文
  • java输入输出节点流过滤流

    千次阅读 2016-12-09 19:58:30
    java的IO使用装饰者模式,装饰者模式分为装饰者和被装饰者,对应的就是java IO的节点流过滤流节点流就是基本流,过滤流保证节点流,添加特色功能,在构造函数中有一个InputStream参数,这是我区分节点流过滤...
  • Java中是指计算中流动的缓冲区。 从外部设备流向中央处理器的数据成为“输入”,反之成为“输出”。 字符和字节的主要区别:  1.字节读取的时候,读到一个字节就返回一个字节;字符使用了字节...
  • (1)一个人只要自己不放弃自己,整个世界也不会放弃你. (2)天生我才必有大用 (3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而...节点流过滤流2.OutputStream3.输出流写数据的逻辑4.过滤流5.BufferedOu.
  • java根据过滤条件显示树形结构,其中包括所需要的jar包
  • 数据压缩,文件传输 Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入、压缩输入、文件输出、实例化缓冲区、写入数据到文件、关闭输入、关闭套接字关闭输出、输出错误信息等Java编程小技巧...
  • FilterInputStream 和 ...要使用过滤流,首先必须把它连接到某个输入输出节点流上,通常在构造方法的的参数中指定所要连接的节点流: FilterInputStream(InputStream in); FilterOutputStream(Outputstream out); ...
  • Java输入输出

    千次阅读 多人点赞 2017-02-18 17:07:20
    Java输入输出
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java ...
  • 什么是节点流和处理流?

    千次阅读 2020-07-03 19:26:49
    按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader. 处理流:是对一个已存在的流的连接和封装,通过所封装的流的...
  • 关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作引擎 asp.net工作引擎 java工作引擎. 开发者表单 拖拽式表单 工作系统CCBPM节点访问规则接收人规则 适配数据库: oralce,mysql,sqlserver,...
  • 流可以根据数据单位分为字节流和字符流,根据数据流方向分为输入流和输出流,根据功能分为字节...涉及到过滤流,能提高读写的速率(BufferedOutputStream)或者提供读写java中的基本数据类型的功能(DataOutputStream)
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入、压缩输入、文件输出、实例化缓冲区、写入数据到文件、关闭输入、关闭套接字关闭输出、输出错误信息等Java编程小技巧。 Java数组倒置...
  • Java IO --- 节点流过滤流

    千次阅读 2012-11-06 21:21:53
     过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或者输出流链接创建的。 (2)在InputStream类和OutputStream类子类中,FilterInputStream和FilterOutputStream过滤抽象类又派生出  ...
  • 关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作引擎 asp.net工作引擎 java工作引擎. 开发者表单 拖拽式表单 工作系统CCBPM节点访问规则接收人规则 适配数据库: oralce,mysql,sqlserver,...
  • JavaIO详解

    万次阅读 多人点赞 2017-08-15 14:37:30
    【I/O】 Input/Output:输入输出机制 输入机制:允许java程序获取外部设备的数据(磁盘,光盘,网络等)。 输出机制:保留java程序中的数据,输出到外部设备上(磁盘,光盘等)。 【可以看出,IO的入出是以...
  • 是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以“”的方式进行。设备可以是文件,网络,内存等。 具有方向性,至于是输入还是输出则是一个相对的概念【取决...
  • Java程序中,对于数据的输入/输出操作以“”(Stream)方式进行;Java提供了各种各样的“”类,用以获取不同种类的数据:程序中通过标准的方法输入或输出数据。 读入写出 是用来读写数据的,java有一个...
  • java面试题2019_java面试题及答案_java面试题库

    千次阅读 多人点赞 2019-05-16 09:31:30
    1、一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制? 2、Java有没有goto? 3、&和&&的区别? 4、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 5、short s1 = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,103
精华内容 16,841
关键字:

java节点流过滤流

java 订阅