精华内容
下载资源
问答
  • Java(2)-Java IO输入输出

    万次阅读 多人点赞 2012-04-01 11:28:55
    Java中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的...

     

     

    1.什么是IO


          Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。  

          Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO。

      流IO的好处是简单易用,缺点是效率较低。块IO效率很高,但编程比较复杂。 
          Java IO模型  :
          Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

     

    2.数据流的基本概念


            数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序可以是一段、一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。 

          “流是磁盘或其它外围设备中存储的数据的源点或终点。”

        在电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。这里总结从外存读取数据到内存以及将数据从内存写到外存中。对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。那又怎样把放在外存这个容器内的数据读取到内存这个容器以及怎么把内存这个容器里的数据存到外存中呢?

         在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:

             标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。

        流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。

    总结的基本概念如下:

    1) 数据流

        一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。

      

    2) 输入流(Input  Stream):

          程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道

         

     3) 输出流

        程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

             

    采用数据流的目的就是使得输出输入独立于设备。

    Input  Stream不关心数据源来自何种设备(键盘,文件,网络)
    Output  Stream不关心数据的目的是何种设备(键盘,文件,网络)

    4) 数据流分类:

    流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
     1)  字节流:数据流中最小的数据单元是字节
     2)  字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

     

     

    3. 标准I/O


          Java程序可通过命令行参数与外界进行简短的信息交换,同时,也规定了与标准输入、输出设备,如键盘、显示器进行信息交换的方式。而通过文件可以与外界进行任意数据形式的信息交换。

    1. 命令行参数

    public class TestArgs {
    	public static void main(String[] args) {
    		for (int i = 0; i < args.length; i++) {
    			System.out.println("args[" + i + "] is <" + args[i] + ">");
    		}
    	}
    }

    运行命令:java Java C VB
    运行结果:
    args[0] is <Java>
    args[1] is <C>
    args[2] is <VB>

     

    2. 标准输入,输出数据流

    java系统自带的标准数据流:java.lang.System:

    java.lang.System 
    public final class System  extends Object{ 
       static  PrintStream  err;//标准错误流(输出)
       static  InputStream  in;//标准输入(键盘输入流)
       static  PrintStream  out;//标准输出流(显示器输出流)
    }

    注意:
    (1)System类不能创建对象,只能直接使用它的三个静态成员。
    (2)每当main方法被执行时,就自动生成上述三个对象。

    1) 标准输出流 System.out

       System.out向标准输出设备输出数据,其数据类型为PrintStream。方法:

          Void print(参数)
          Void println(参数)

    2)标准输入流 System.in

        System.in读取标准输入设备数据(从标准输入获取数据,一般是键盘),其数 据类型为InputStream。方法:

            int read()  //返回ASCII码。若,返回值=-1,说明没有读取到任何字节读取工作结束。
             int read(byte[] b)//读入多个字节到缓冲区b中返回值是读入的字节数
    例如:
    import java.io.*;
    public class StandardInputOutput {
    	public static void main(String args[]) {
    		int b;
    		try {
    			System.out.println("please Input:");
    			while ((b = System.in.read()) != -1) {
    				System.out.print((char) b);
    			}
    		} catch (IOException e) {
    			System.out.println(e.toString());
    		}
    	}
    }
    等待键盘输入,键盘输入什么,就打印出什么:

     

    3)标准错误流

       System.err输出标准错误,其数据类型为PrintStream。可查阅API获得详细说明。

        标准输出通过System.out调用println方法输出参数并换行,而print方法输出参数但不换行。println或print方法都通 过重载实现了输出基本数据类型的多个方法,包括输出参数类型为boolean、char、int、long、float和double。同时,也重载实现 了输出参数类型为char[]、String和Object的方法。其中,print(Object)和println(Object)方法在运行时将调 用参数Object的toString方法。

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class StandardInputOutput {
    	public static void main(String args[]) {
    		String s;
    		// 创建缓冲区阅读器从键盘逐行读入数据
    		InputStreamReader ir = new InputStreamReader(System.in);
    		BufferedReader in = new BufferedReader(ir);
    		System.out.println("Unix系统: ctrl-d 或 ctrl-c 退出"
    				+ "\nWindows系统: ctrl-z 退出");
    		try {
    			// 读一行数据,并标准输出至显示器
    			s = in.readLine();
    			// readLine()方法运行时若发生I/O错误,将抛出IOException异常
    			while (s != null) {
    				System.out.println("Read: " + s);
    				s = in.readLine();
    			}
    			// 关闭缓冲阅读器
    			in.close();
    		} catch (IOException e) { // Catch any IO exceptions.
    			e.printStackTrace();
    		}
    	}
    }

     

    4.java.IO层次体系结构


         在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了

          Java I/O主要包括如下几个层次,包含三个部分:

       1.流式部分――IO的主体部分;

       2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

       3.其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

       主要的类如下:

         1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。

         2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

         3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

         Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

         4. Reader(文件格式操作):抽象类,基于字符的输入操作。

         5. Writer(文件格式操作):抽象类,基于字符的输出操作。

         6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作

     

         Java中IO流的体系结构如图:

         

     

     

    5. 非流式文件类--File类


    在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。
     
    作用:File类主要用于命名文件、查询文件属性和处理文件目录。
    public    class   File   extends Object 
        implements Serializable,Comparable
    {}

     

    File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。构造函数:
    1)File (String   pathname)   
         例:File  f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
    2)File (String  parent  ,  String child)
         例:File f2=new  File(“D:\\dir1","FileTest2.txt") ;//  注意:D:\\dir1目录事先必须存在,否则异常
    3)File (File    parent  , String child)
         例:File  f4=new File("\\dir3");
              File  f5=new File(f4,"FileTest5.txt");  //在如果 \\dir3目录不存在使用f4.mkdir()先创建
            一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。    
           1)public boolean exists( ) 判断文件或目录是否存在
           2)public boolean isFile( ) 判断是文件还是目录 
           3)public boolean isDirectory( ) 判断是文件还是目录
           4)public String getName( ) 返回文件名或目录名
           5)public String getPath( ) 返回文件或目录的路径。
           6)public long length( ) 获取文件的长度 
           7)public String[ ] list ( ) 将目录中所有文件名保存在字符串数组中返回。 
           File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
           1) public boolean renameTo( File newFile );    重命名文件
           2) public void delete( );   删除文件
           3)  public boolean mkdir( ); 创建目录
     
    例子:

     

    import java.io.File;
    import java.io.IOException;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		File dir = new File("\\root");
    		File f1 = new File(dir, "fileOne.txt");
    		File f2 = new File(dir, "fileTwo.java");
    		// 文件对象创建后,指定的文件或目录不一定物理上存在
    		if (!dir.exists())
    			dir.mkdir();
    		if (!f1.exists())
    			f1.createNewFile();
    		if (!f2.exists())
    			f2.createNewFile();
    		System.out.println("f1's AbsolutePath=  " + f1.getAbsolutePath());
    		System.out.println("f1 Canread=" + f1.canRead());
    		System.out.println("f1's len= " + f1.length());
    		String[] FL;
    		int count = 0;
    		FL = dir.list();
    		for (int i = 0; i < FL.length; i++) {
    			count++;
    			System.out.println(FL[i] + "is in \\root");
    		}
    		System.out.println("there are" + count + "file in //root");
    	}
    
    }

     

    说明:File类的方法:
    (1) exists()测试磁盘中指定的文件或目录是否存在
    (2) mkdir()创建文件对象指定的目录(单层目录)
    (3) createNewFile()创建文件对象指定的文件

    (4) list()返回目录中所有文件名字符串

     

    6. Java.IO流类库


    1. io流的四个基本类

          java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:

    基本数据流的I/O

    输入/输出

    字节流

    字符流

    输入流

    Inputstream

    Reader

    输出流

    OutputStream

    Writer

     
    IO框架:

     

        

     

     Java中其他多种多样变化的流均是由它们派生出来的:

          JDK1.4版本开始引入了新I/O类库,它位于java.nio包中,新I/O类库利用通道和缓冲区等来提高I/O操作的效率。

          在java.io包中, java.io.InputStream 表示字节输入流, java.io.OutputStream表示字节输出流,处于java.io包最顶层。这两个类均为抽象类,也就是说它们不能被实例化,必须生成子类之后才能实现一定的功能。

     

    2. io流的具体分类

    一、按I/O类型来总体分类:

         1. Memory 1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
                       2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream
         2.Pipe管道  实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream
         3.File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream
         4. ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream
         5.DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
         6.Printing 包含方便的打印方法 :PrintWriter、PrintStream
         7.Buffering缓冲  在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream
         8.Filtering 滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过
         9.Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream
        10.Counting计数  在读入数据时对行记数 :LineNumberReader、LineNumberInputStream
        11.Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream
        12.Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

    、按数据来源(去向)分类: 
    1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter 
    2、byte[]:ByteArrayInputStream, ByteArrayOutputStream 
    3、Char[]: CharArrayReader, CharArrayWriter 
    4、String: StringBufferInputStream, StringReader, StringWriter 
    5、网络数据流:InputStream, OutputStream, Reader, Writer 

     

     

    7. 字节流InputStream/OutputStream


     1. InputStream抽象类 

          InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream  的流都是向程序中输入数据的,且数据单位为字节(8bit);

    InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法: 
      (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
      (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的 
      (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。 
      (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用, 
      (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取 
      (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭. 

             主要的子类:

            

             1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作     
        2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用 
        3) StringBufferInputStream:把一个String对象作为InputStream 
        4) PipedInputStream:实现了pipe的概念,主要在线程中使用 
        5) SequenceInputStream:把多个InputStream合并为一个InputStream 

     

     2.OutputStream抽象类

      OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。 
      1. public void write(byte b[ ]):将参数b中的字节写到输出流。 
      2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。 
      3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。 
      4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。 
      5. public void close( ) : 关闭输出流并释放与流相关的系统资源。 

     

           主要的子类:

            

          1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中 
          2) FileOutputStream:把信息存入文件中 
          3) PipedOutputStream:实现了pipe的概念,主要在线程中使用 
          4) SequenceOutputStream:把多个OutStream合并为一个OutStream 

    流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。

    3. 文件输入流: FileInputStream类

          FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。

     

     

    作用:以文件作为数据输入源的数据流。或者说是打开文件,从文件读数据到内存的类。
    使用方法(1)    
       File  fin=new File("d:/abc.txt"); 
      FileInputStream in=new FileInputStream( fin);

     

    使用方法(2)
       FileInputStream  in=new  FileInputStream(“d: /abc.txt”);

    程序举例:
    将InputFromFile.java的程序的内容显示在显示器上

     

    import java.io.IOException;
    import java.io.FileInputStream;
    ;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try{	
    		       FileInputStream rf=new   FileInputStream("InputFromFile.java");
    		       int n=512;   byte  buffer[]=new  byte[n];   
    		       while((rf.read(buffer,0,n)!=-1)&&(n>0)){
    		           System.out.println(new String(buffer) );
    		        }
    		        System.out.println();
    		        rf.close();
    		} catch(IOException  IOe){	    
    		      System.out.println(IOe.toString());
    		}
    
    	}
    
    }

     

    4.文件输出流:FileOutputStream类

       作用:用来处理以文件作为数据输出目的数据流;或者说是从内存区读数据入文件

          FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。 
      创建一个文件流对象有两种方法: 
      方式1: 
       File   f=new  File (“d:/myjava/write.txt ");
            FileOutputStream  out= new FileOutputStream (f);
      方式2: 
      FileOutputStream out=new FileOutputStream(“d:/myjava/write.txt "); 
      方式3:构造函数将 FileDescriptor()对象作为其参数。 
      FileDescriptor() fd=new FileDescriptor(); 
      FileOutputStream f2=new FileOutputStream(fd); 
      方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。 
      FileOutputStream f=new FileOutputStream("d:/abc.txt",true); 
      注意: (1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。 

     

    程序举例:使用键盘输入一段文章,将文章保存在文件write.txt中
    import java.io.IOException;
    import java.io.FileOutputStream;
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try {
    			System.out.println("please Input from      Keyboard");
    			int count, n = 512;
    			byte buffer[] = new byte[n];
    			count = System.in.read(buffer);
    			FileOutputStream wf = new FileOutputStream("d:/myjava/write.txt");
    			wf.write(buffer, 0, count);
    			wf.close(); // 当流写操作结束时,调用close方法关闭流。
    			System.out.println("Save to the write.txt");
    		} catch (IOException IOe) {
    			System.out.println("File Write Error!");
    		}
    	}
    
    }

    5. FileInputStream流和FileOutputStream的应用

    利用程序将文件file1.txt 拷贝到file2.txt中。
    import java.io.File;
    import java.io.IOException;
    import java.io.FileOutputStream;
    import java.io.FileInputStream;
    
    public class TestFile {
    	public static void main(String args[]) throws IOException {
    		try {
    			File inFile = new File("copy.java");
    			File outFile = new File("copy2.java");
    			FileInputStream finS = new FileInputStream(inFile);
    			FileOutputStream foutS = new FileOutputStream(outFile);
    			int c;
    			while ((c = finS.read()) != -1) {
    				foutS.write(c);
    			}
    			finS.close();
    			foutS.close();
    		} catch (IOException e) {
    			System.err.println("FileStreamsTest: " + e);
    		}
    	}
    
    }
    

     

    6. 缓冲输入输出流 BufferedInputStream/ BufferedOutputStream

            

     

          

           计算机访问外部设备非常耗时。访问外存的频率越高,造成CPU闲置的概率就越大。为了减少访问外存的次数,应该在一次对外设的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问硬盘的次数,提高传输效率。

     

    BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。

    BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。

    1)将文件读入内存:

    BufferedInputStreamFileInputStream相接

      FileInputStream in=new  FileInputStream( “file1.txt ” );

      BufferedInputStream bin=new  BufferedInputStreamin); 

    2)将内存写入文件:

    BufferedOutputStream FileOutputStream相接

    FileOutputStreamout=new FileOutputStream(“file1.txt”);

    BufferedOutputStream  bin=new BufferedInputStream(out);


    3)键盘输入流读到内存
    BufferedReader标准的数据流相接 
     InputStreamReader sin=new InputStreamReader (System.in) ;
    BufferedReader bin=new             BufferedReader(sin);
    import java.io.*;
    
    public class ReadWriteToFile {
    	public static void main(String args[]) throws IOException {
    		InputStreamReader sin = new InputStreamReader(System.in);
    		BufferedReader bin = new BufferedReader(sin);
    		FileWriter out = new FileWriter("myfile.txt");
    		BufferedWriter bout = new BufferedWriter(out);
    		String s;
    		while ((s = bin.readLine()).length() > 0) {
    			bout.write(s, 0, s.length());
    		}
    
    	}
    }

    程序说明:
    从键盘读入字符,并写入到文件中BufferedReader类的方法:String readLine()
    作用:读一行字符串,以回车符为结束。
    BufferedWriter类的方法:bout.write(String s,offset,len)
    作用:从缓冲区将字符串s从offset开始,len长度的字符串写到某处。

     

    8. 字符流Writer/Reader


            Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    1. Reader抽象类

        用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

           

            1) FileReader :与FileInputStream对应  
               主要用来读取字符文件,使用缺省的字符编码,有三种构造函数: 
          (1)将文件名作为字符串 :FileReader f=new FileReader(“c:/temp.txt”); 
          (2)构造函数将File对象作为其参数。 
                  File f=new file(“c:/temp.txt”); 
                  FileReader f1=new FileReader(f); 
         (3)  构造函数将FileDescriptor对象作为参数 
                FileDescriptor() fd=new FileDescriptor() 
                FileReader f2=new FileReader(fd); 
                   (1) 用指定字符数组作为参数:CharArrayReader(char[]) 
                   (2) 将字符数组作为输入流:CharArrayReader(char[], int, int) 
              读取字符串,构造函数如下: public StringReader(String s); 
            2) CharArrayReader:与ByteArrayInputStream对应  
      3) StringReader : 与StringBufferInputStream对应 
      4) InputStreamReader 
            从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is); 
      5) FilterReader: 允许过滤字符流 
            protected filterReader(Reader r); 
      6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。 
         Public BufferReader(Reader r); 

          主要方法:

          (1)  public int read() throws IOException; //读取一个字符,返回值为读取的字符 

      (2)  public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/ 
      (3)  public abstract int read(char cbuf[],int off,int len) throws IOException; 
      /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/ 

    2. Writer抽象类

         写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

        

          1) FileWrite: 与FileOutputStream对应  
      将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。 
      Public FileWrite(file f); 
      
    2)  chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。 
          Public CharArrayWrite(); 
      3) PrintWrite:生成格式化输出 
          public PrintWriter(outputstream os); 
      4) filterWriter:用于写入过滤字符流 
          protected FilterWriter(Writer w); 
      5) PipedWriter:与PipedOutputStream对应   

          6) StringWriter:无与之对应的以字节为导向的stream  

          主要方法:

      (1)  public void write(int c) throws IOException; //将整型值c的低16位写入输出流 
      (2)  public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流 
      (3)  public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流 
      (4)  public void write(String str) throws IOException; //将字符串str中的字符写入输出流 
      (5)  public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流 
      (6)  flush( ) //刷空输出流,并输出所有被缓存的字节。 
      (7)close()    关闭流 public abstract void close() throws IOException

     

     

    3 .InputStream与Reader差别 OutputStream与Writer差别

     

    InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit)
    Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题

     

    import java.io.*;
    public class EncodeTest {
        private static void readBuff(byte [] buff) throws IOException {
           ByteArrayInputStream in =new ByteArrayInputStream(buff);
            int data;
            while((data=in.read())!=-1)   System.out.print(data+"  ");
            System.out.println();     in.close();     }
    
       public static void main(String args[]) throws IOException {
           System.out.println("内存中采用unicode字符编码:" );
           char   c='好';
           int lowBit=c&0xFF;     int highBit=(c&0xFF00)>>8;
           System.out.println(""+lowBit+"   "+highBit);
           String s="好";
           System.out.println("本地操作系统默认字符编码:");
           readBuff(s.getBytes());
           System.out.println("采用GBK字符编码:");
           readBuff(s.getBytes("GBK"));
           System.out.println("采用UTF-8字符编码:");      
           readBuff(s.getBytes("UTF-8"));      }
    }
    


    Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存

     

    Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

     

    9. FileWriter类(字符输出流类)


    构造方法:FileWriter fw = new FileWriter(String fileName);//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。

                   如: FileWriter fw = new FileWriter("C:\\1.txt");

                     FileWriter fw = new FileWriter(String fileName,boolean append);//创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。

                   如:FileWriter fw = new FileWriter("C:\\1.txt",ture); //表示在fw对文件再次写入时,会在该文件的结尾续写,并不会覆盖掉。

    主要方法: 

            void write(String str)   //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。此时在使用刷新方法就可以使数据保存到目的文件中去。

            viod flush()                //刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。

            viod close()               //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常。

    10. 如何选择IO流


        1)确定是数据源和数据目的(输入还是输出

                  源:输入流 InputStream Reader
                  目的:输出流 OutputStream Writer

        2)明确操作的数据对象是否是纯文本

                 是:字符流Reader,Writer
                 否:字节流InputStream,OutputStream

        3)明确具体的设备。

                 是硬盘文件:File++:

                 读取:FileInputStream,, FileReader, 

                  写入:FileOutputStream,FileWriter
                 
    是内存用数组

                      byte[]:ByteArrayInputStream, ByteArrayOutputStream
                     
    是char[]:CharArrayReader, CharArrayWriter
                 
    是String:StringBufferInputStream(已过时,因为其只能用于String的每个字符都是8位的字符串), StringReader, StringWriter
                 
    是网络用Socket流

                 是键盘:用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印

        3)是否需要转换流

                是,就使用转换流,从Stream转化为Reader,Writer:InputStreamReader,OutputStreamWriter 

        4)是否需要缓冲提高效率

           是就加上Buffered:BufferedInputStream, BufferedOuputStream, BuffereaReader, BufferedWriter
        5)是否需要格式化输出

     

    例:将一个文本文件中数据存储到另一个文件中。
         1)数据源和数据目的:读取流,InputStream Reader  输出:OutputStream Writer
         2)是否纯文本:是!这时就可以选择Reader Writer。
         3)设备:是硬盘文件。Reader体系中可以操作文件的对象是 FileReader FileWriter。

                FileReader fr = new FileReader("a.txt");  

                 FileWriter fw = new FileWriter("b.txt");  
         
    4)是否需要提高效率:是,加Buffer
                 BufferedReader bfr = new BufferedReader(new FileReader("a.txt");  );  
                 BufferedWriter bfw = new BufferedWriter(new FileWriter("b.txt");  );

    11. IOException异常类的子类


    1.public class  EOFException :
       非正常到达文件尾或输入流尾时,抛出这种类型的异常。
    2.public class FileNotFoundException:
       当文件找不到时,抛出的异常。
    3.public class InterruptedIOException:
       当I/O操作被中断时,抛出这种类型的异常。




     

    感谢您的支持,我会继续努力的! 扫码打赏,你说多少就多少

             

     

     

     

    展开全文
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...

    1.什么是IO

    Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。

    Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO。

    流IO的好处是简单易用,缺点是效率较低。块IO效率很高,但编程比较复杂。     Java IO模型  :       Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

    2.数据流的基本概念

    数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序可以是一段、一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。

    “流是磁盘或其它外围设备中存储的数据的源点或终点。”

    在电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。这里总结从外存读取数据到内存以及将数据从内存写到外存中。对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。那又怎样把放在外存这个容器内的数据读取到内存这个容器以及怎么把内存这个容器里的数据存到外存中呢?

    在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:

    标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。

    流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。

    总结的基本概念如下:

    1) 数据流:

    一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。

    1355473547_6986.jpg

    2) 输入流(Input  Stream):

    程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道

    1333248748_3106.jpg

    3) 输出流:

    程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

    1333248874_6866.jpg

    采用数据流的目的就是使得输出输入独立于设备。

    Input Stream不关心数据源来自何种设备(键盘,文件,网络) Output Stream不关心数据的目的是何种设备(键盘,文件,网络)

    4 数据流分类:

    流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种: 1) 字节流:数据流中最小的数据单元是字节 2)  字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

    3. 标准I/O

    Java程序可通过命令行参数与外界进行简短的信息交换,同时,也规定了与标准输入、输出设备,如键盘、显示器进行信息交换的方式。而通过文件可以与外界进行任意数据形式的信息交换。

    1. 命令行参数

    public class TestArgs {

    public static void main(String[] args) {

    for (int i = 0; i < args.length; i++) {

    System.out.println("args[" + i + "] is ");

    }

    }

    }

    public class TestArgs {

    public static void main(String[] args) {

    for (int i = 0; i < args.length; i++) {

    System.out.println("args[" + i + "] is ");

    }

    }

    }

    运行命令:java Java C VB

    运行结果:

    args[0] is

    args[1] is

    args[2] is

    2. 标准输入,输出数据流

    java系统自带的标准数据流:java.lang.System:

    java.lang.System

    public final class System  extends Object{

    static  PrintStream  err;//标准错误流(输出)

    static  InputStream  in;//标准输入(键盘输入流)

    static  PrintStream  out;//标准输出流(显示器输出流)

    }

    java.lang.System

    public final class System extends Object{

    static PrintStream err;//标准错误流(输出)

    static InputStream in;//标准输入(键盘输入流)

    static PrintStream out;//标准输出流(显示器输出流)

    }

    注意: (1)System类不能创建对象,只能直接使用它的三个静态成员。 (2)每当main方法被执行时,就自动生成上述三个对象。

    1) 标准输出流 System.out

    System.out向标准输出设备输出数据,其数据类型为PrintStream。方法:

    Void print(参数)

    Void println(参数)

    2)标准输入流 System.in

    System.in读取标准输入设备数据(从标准输入获取数据,一般是键盘),其数 据类型为InputStream。方法:

    int read()  //返回ASCII码。若,返回值=-1,说明没有读取到任何字节读取工作结束。

    int read(byte[] b)//读入多个字节到缓冲区b中返回值是读入的字节数

    例如:

    import java.io.*;

    public class StandardInputOutput {

    public static void main(String args[]) {

    int b;

    try {

    System.out.println("please Input:");

    while ((b = System.in.read()) != -1) {

    System.out.print((char) b);

    }

    } catch (IOException e) {

    System.out.println(e.toString());

    }

    }

    }

    import java.io.*;

    public class StandardInputOutput {

    public static void main(String args[]) {

    int b;

    try {

    System.out.println("please Input:");

    while ((b = System.in.read()) != -1) {

    System.out.print((char) b);

    }

    } catch (IOException e) {

    System.out.println(e.toString());

    }

    }

    }

    等待键盘输入,键盘输入什么,就打印出什么:

    1354093989_4632.jpg

    3)标准错误流

    System.err输出标准错误,其数据类型为PrintStream。可查阅API获得详细说明。

    标准输出通过System.out调用println方法输出参数并换行,而print方法输出参数但不换行。println或print方法都通 过重载实现了输出基本数据类型的多个方法,包括输出参数类型为boolean、char、int、long、float和double。同时,也重载实现 了输出参数类型为char[]、String和Object的方法。其中,print(Object)和println(Object)方法在运行时将调 用参数Object的toString方法。

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStreamReader;

    public class StandardInputOutput {

    public static void main(String args[]) {

    String s;

    // 创建缓冲区阅读器从键盘逐行读入数据

    InputStreamReader ir = new InputStreamReader(System.in);

    BufferedReader in = new BufferedReader(ir);

    System.out.println("Unix系统: ctrl-d 或 ctrl-c 退出"

    + "\nWindows系统: ctrl-z 退出");

    try {

    // 读一行数据,并标准输出至显示器

    s = in.readLine();

    // readLine()方法运行时若发生I/O错误,将抛出IOException异常

    while (s != null) {

    System.out.println("Read: " + s);

    s = in.readLine();

    }

    // 关闭缓冲阅读器

    in.close();

    } catch (IOException e) { // Catch any IO exceptions.

    e.printStackTrace();

    }

    }

    }

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStreamReader;

    public class StandardInputOutput {

    public static void main(String args[]) {

    String s;

    // 创建缓冲区阅读器从键盘逐行读入数据

    InputStreamReader ir = new InputStreamReader(System.in);

    BufferedReader in = new BufferedReader(ir);

    System.out.println("Unix系统: ctrl-d 或 ctrl-c 退出"

    + "\nWindows系统: ctrl-z 退出");

    try {

    // 读一行数据,并标准输出至显示器

    s = in.readLine();

    // readLine()方法运行时若发生I/O错误,将抛出IOException异常

    while (s != null) {

    System.out.println("Read: " + s);

    s = in.readLine();

    }

    // 关闭缓冲阅读器

    in.close();

    } catch (IOException e) { // Catch any IO exceptions.

    e.printStackTrace();

    }

    }

    }

    4.java.IO层次体系结构

    在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了

    Java I/O主要包括如下几个层次,包含三个部分:

    1.流式部分――IO的主体部分;

    2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

    3.其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

    主要的类如下:

    1. File(文件特征与管理):用于文件或者目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。

    2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

    3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    4. Reader(文件格式操作):抽象类,基于字符的输入操作。

    5. Writer(文件格式操作):抽象类,基于字符的输出操作。

    6. RandomAccessFile(随机文件操作):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。

    Java中IO流的体系结构如图:

    1355467587_4888.jpg

    5. 非流式文件类--File类

    在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

    作用:File类主要用于命名文件、查询文件属性和处理文件目录。

    public    class   File   extends Object

    implements Serializable,Comparable

    {}

    public class File extends Object

    implements Serializable,Comparable

    {}

    File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。构造函数: 1)File (String   pathname)

    例:File  f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt 2)File (String  parent  ,  String child)

    例:File f2=new  File(“D:\\dir1","FileTest2.txt") ;// 注意:D:\\dir1目录事先必须存在,否则异常 3)File (File    parent  , String child)      例:File  f4=new File("\\dir3");           File  f5=new File(f4,"FileTest5.txt");  //在如果 \\dir3目录不存在使用f4.mkdir()先创建

    一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。

    1)public boolean exists( ) 判断文件或目录是否存在        2)public boolean isFile( ) 判断是文件还是目录        3)public boolean isDirectory( ) 判断是文件还是目录       4)public String getName( ) 返回文件名或目录名        5)public String getPath( ) 返回文件或目录的路径。        6)public long length( ) 获取文件的长度        7)public String[ ] list ( ) 将目录中所有文件名保存在字符串数组中返回。

    File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:        1) public boolean renameTo( File newFile );    重命名文件        2) public void delete( );   删除文件        3)  public boolean mkdir( ); 创建目录

    例子:

    import java.io.File;

    import java.io.IOException;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    File dir = new File("\\root");

    File f1 = new File(dir, "fileOne.txt");

    File f2 = new File(dir, "fileTwo.java");

    // 文件对象创建后,指定的文件或目录不一定物理上存在

    if (!dir.exists())

    dir.mkdir();

    if (!f1.exists())

    f1.createNewFile();

    if (!f2.exists())

    f2.createNewFile();

    System.out.println("f1's AbsolutePath=  " + f1.getAbsolutePath());

    System.out.println("f1 Canread=" + f1.canRead());

    System.out.println("f1's len= " + f1.length());

    String[] FL;

    int count = 0;

    FL = dir.list();

    for (int i = 0; i < FL.length; i++) {

    count++;

    System.out.println(FL[i] + "is in \\root");

    }

    System.out.println("there are" + count + "file in //root");

    }

    }

    import java.io.File;

    import java.io.IOException;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    File dir = new File("\\root");

    File f1 = new File(dir, "fileOne.txt");

    File f2 = new File(dir, "fileTwo.java");

    // 文件对象创建后,指定的文件或目录不一定物理上存在

    if (!dir.exists())

    dir.mkdir();

    if (!f1.exists())

    f1.createNewFile();

    if (!f2.exists())

    f2.createNewFile();

    System.out.println("f1's AbsolutePath= " + f1.getAbsolutePath());

    System.out.println("f1 Canread=" + f1.canRead());

    System.out.println("f1's len= " + f1.length());

    String[] FL;

    int count = 0;

    FL = dir.list();

    for (int i = 0; i < FL.length; i++) {

    count++;

    System.out.println(FL[i] + "is in \\root");

    }

    System.out.println("there are" + count + "file in //root");

    }

    }

    说明:File类的方法: (1) exists()测试磁盘中指定的文件或目录是否存在 (2) mkdir()创建文件对象指定的目录(单层目录) (3) createNewFile()创建文件对象指定的文件

    (4) list()返回目录中所有文件名字符串

    6. Java.IO流类库

    1. io流的四个基本类

    java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:

    基本数据流的I/O

    输入/输出

    字节流

    字符流

    输入流

    Inputstream

    Reader

    输出流

    OutputStream

    Writer

    Java中其他多种多样变化的流均是由它们派生出来的:

    1333250374_3564.gif

    1333250382_9126.gif

    1333250341_6152.gif

    1333250133_8675.gif

    JDK1.4版本开始引入了新I/O类库,它位于java.nio包中,新I/O类库利用通道和缓冲区等来提高I/O操作的效率。

    在java.io包中, java.io.InputStream 表示字节输入流, java.io.OutputStream表示字节输出流,处于java.io包最顶层。这两个类均为抽象类,也就是说它们不能被实例化,必须生成子类之后才能实现一定的功能。

    1. io流的具体分类

    一、按I/O类型来总体分类:

    1. Memory 1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream                    2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream     2.Pipe管道实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream      3.File 文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream      4. ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream     5.DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream     6.Printing 包含方便的打印方法 :PrintWriter、PrintStream     7.Buffering缓冲 在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream      8.Filtering滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过      9.Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream     10.Counting计数  在读入数据时对行记数 :LineNumberReader、LineNumberInputStream     11.Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream     12.Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

    二、按数据来源(去向)分类:

    1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter

    2、byte[]:ByteArrayInputStream, ByteArrayOutputStream

    3、Char[]: CharArrayReader, CharArrayWriter

    4、String: StringBufferInputStream, StringReader, StringWriter

    5、网络数据流:InputStream, OutputStream, Reader, Writer

    7. 字节流InputStream/OutputStream

    1. InputStream抽象类

    InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream  的流都是向程序中输入数据的,且数据单位为字节(8bit);

    InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:

    (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。

    (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的

    (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。

    (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,

    (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取

    (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.

    主要的子类:

    1333250374_3564.gif

    1) FileInputStream把一个文件作为InputStream,实现对文件的读取操作

    2) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用

    3) StringBufferInputStream:把一个String对象作为InputStream

    4) PipedInputStream:实现了pipe的概念,主要在线程中使用

    5) SequenceInputStream:把多个InputStream合并为一个InputStream

    2.OutputStream抽象类

    OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。

    1. public void write(byte b[ ]):将参数b中的字节写到输出流。

    2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。

    3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。

    4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。

    5. public void close( ) : 关闭输出流并释放与流相关的系统资源。

    主要的子类:

    1333250382_9126.gif

    1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中       2) FileOutputStream:把信息存入文件中       3) PipedOutputStream:实现了pipe的概念,主要在线程中使用       4) SequenceOutputStream:把多个OutStream合并为一个OutStream

    流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。

    3. 文件输入流: FileInputStream类

    FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。

    1354189614_8795.jpg

    作用:以文件作为数据输入源的数据流。或者说是打开文件,从文件读数据到内存的类。 使用方法(1)       File fin=new File("d:/abc.txt");   FileInputStream in=new FileInputStream( fin);

    使用方法(2)   FileInputStream  in=new  FileInputStream(“d: /abc.txt”);

    程序举例: 将InputFromFile.java的程序的内容显示在显示器上

    1354189800_1523.jpg

    import java.io.IOException;

    import java.io.FileInputStream;

    ;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try{

    FileInputStream rf=new   FileInputStream("InputFromFile.java");

    int n=512;   byte  buffer[]=new  byte[n];

    while((rf.read(buffer,0,n)!=-1)&&(n>0)){

    System.out.println(new String(buffer) );

    }

    System.out.println();

    rf.close();

    } catch(IOException  IOe){

    System.out.println(IOe.toString());

    }

    }

    }

    import java.io.IOException;

    import java.io.FileInputStream;

    ;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try{

    FileInputStream rf=new FileInputStream("InputFromFile.java");

    int n=512; byte buffer[]=new byte[n];

    while((rf.read(buffer,0,n)!=-1)&&(n>0)){

    System.out.println(new String(buffer) );

    }

    System.out.println();

    rf.close();

    } catch(IOException IOe){

    System.out.println(IOe.toString());

    }

    }

    }

    4.文件输出流:FileOutputStream类

    作用:用来处理以文件作为数据输出目的数据流;或者说是从内存区读数据入文件

    FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。

    创建一个文件流对象有两种方法:

    方式1:

    File   f=new  File (“d:/myjava/write.txt ");

    FileOutputStream  out= new FileOutputStream (f);

    方式2:

    FileOutputStream out=new FileOutputStream(“d:/myjava/write.txt ");

    方式3:构造函数将 FileDescriptor()对象作为其参数。

    FileDescriptor() fd=new FileDescriptor();

    FileOutputStream f2=new FileOutputStream(fd);

    方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。

    FileOutputStream f=new FileOutputStream("d:/abc.txt",true);

    注意: (1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。

    程序举例:使用键盘输入一段文章,将文章保存在文件write.txt中

    1354190012_9885.jpg

    import java.io.IOException;

    import java.io.FileOutputStream;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try {

    System.out.println("please Input from      Keyboard");

    int count, n = 512;

    byte buffer[] = new byte[n];

    count = System.in.read(buffer);

    FileOutputStream wf = new FileOutputStream("d:/myjava/write.txt");

    wf.write(buffer, 0, count);

    wf.close(); // 当流写操作结束时,调用close方法关闭流。

    System.out.println("Save to the write.txt");

    } catch (IOException IOe) {

    System.out.println("File Write Error!");

    }

    }

    }

    import java.io.IOException;

    import java.io.FileOutputStream;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try {

    System.out.println("please Input from Keyboard");

    int count, n = 512;

    byte buffer[] = new byte[n];

    count = System.in.read(buffer);

    FileOutputStream wf = new FileOutputStream("d:/myjava/write.txt");

    wf.write(buffer, 0, count);

    wf.close(); // 当流写操作结束时,调用close方法关闭流。

    System.out.println("Save to the write.txt");

    } catch (IOException IOe) {

    System.out.println("File Write Error!");

    }

    }

    }

    5. FileInputStream流和FileOutputStream的应用

    利用程序将文件file1.txt 拷贝到file2.txt中。

    import java.io.File;

    import java.io.IOException;

    import java.io.FileOutputStream;

    import java.io.FileInputStream;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try {

    File inFile = new File("copy.java");

    File outFile = new File("copy2.java");

    FileInputStream finS = new FileInputStream(inFile);

    FileOutputStream foutS = new FileOutputStream(outFile);

    int c;

    while ((c = finS.read()) != -1) {

    foutS.write(c);

    }

    finS.close();

    foutS.close();

    } catch (IOException e) {

    System.err.println("FileStreamsTest: " + e);

    }

    }

    }

    import java.io.File;

    import java.io.IOException;

    import java.io.FileOutputStream;

    import java.io.FileInputStream;

    public class TestFile {

    public static void main(String args[]) throws IOException {

    try {

    File inFile = new File("copy.java");

    File outFile = new File("copy2.java");

    FileInputStream finS = new FileInputStream(inFile);

    FileOutputStream foutS = new FileOutputStream(outFile);

    int c;

    while ((c = finS.read()) != -1) {

    foutS.write(c);

    }

    finS.close();

    foutS.close();

    } catch (IOException e) {

    System.err.println("FileStreamsTest: " + e);

    }

    }

    }

    6. 缓冲输入输出流 BufferedInputStream/ BufferedOutputStream

    1355473479_8987.jpg

    计算机访问外部设备非常耗时。访问外存的频率越高,造成CPU闲置的概率就越大。为了减少访问外存的次数,应该在一次对外设的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问硬盘的次数,提高传输效率。

    BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。

    BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。

    1)将文件读入内存:

    将BufferedInputStream与FileInputStream相接

    FileInputStream in=new  FileInputStream( “file1.txt ” );

    BufferedInputStream bin=new  BufferedInputStream( in);

    2)将内存写入文件:

    将BufferedOutputStream与 FileOutputStream相接

    FileOutputStreamout=new FileOutputStream(“file1.txt”);

    BufferedOutputStream  bin=new BufferedInputStream(out);

    3)键盘输入流读到内存

    将BufferedReader与标准的数据流相接

    InputStreamReader sin=new InputStreamReader (System.in) ;

    BufferedReader bin=new             BufferedReader(sin);

    import java.io.*;

    public class ReadWriteToFile {

    public static void main(String args[]) throws IOException {

    InputStreamReader sin = new InputStreamReader(System.in);

    BufferedReader bin = new BufferedReader(sin);

    FileWriter out = new FileWriter("myfile.txt");

    BufferedWriter bout = new BufferedWriter(out);

    String s;

    while ((s = bin.readLine()).length() > 0) {

    bout.write(s, 0, s.length());

    }

    }

    }

    import java.io.*;

    public class ReadWriteToFile {

    public static void main(String args[]) throws IOException {

    InputStreamReader sin = new InputStreamReader(System.in);

    BufferedReader bin = new BufferedReader(sin);

    FileWriter out = new FileWriter("myfile.txt");

    BufferedWriter bout = new BufferedWriter(out);

    String s;

    while ((s = bin.readLine()).length() > 0) {

    bout.write(s, 0, s.length());

    }

    }

    }

    程序说明: 从键盘读入字符,并写入到文件中BufferedReader类的方法:String readLine() 作用:读一行字符串,以回车符为结束。 BufferedWriter类的方法:bout.write(String s,offset,len) 作用:从缓冲区将字符串s从offset开始,len长度的字符串写到某处。

    8. 字符流Writer/Reader

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

    1. Reader抽象类

    用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

    1333250341_6152.gif

    1) FileReader :与FileInputStream对应             主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:       (1)将文件名作为字符串 :FileReader f=new FileReader(“c:/temp.txt”);       (2)构造函数将File对象作为其参数。               File f=new file(“c:/temp.txt”);               FileReader f1=new FileReader(f);      (3)  构造函数将FileDescriptor对象作为参数            FileDescriptor() fd=new FileDescriptor()             FileReader f2=new FileReader(fd);                (1) 用指定字符数组作为参数:CharArrayReader(char[])                (2) 将字符数组作为输入流:CharArrayReader(char[], int, int)           读取字符串,构造函数如下: public StringReader(String s);       2) CharArrayReader:与ByteArrayInputStream对应    3) StringReader :与StringBufferInputStream对应   4) InputStreamReader       从输入流读取字节,在将它们转换成字符:Public inputstreamReader(inputstream is);   5) FilterReader:允许过滤字符流         protected filterReader(Reader r);   6) BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。      Public BufferReader(Reader r);

    主要方法:

    (1) public int read() throws IOException; //读取一个字符,返回值为读取的字符

    (2) public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/   (3) public abstract int read(char cbuf[],int off,int len) throws IOException;   /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/

    2. Writer抽象类

    写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:

    1333250133_8675.gif

    1) FileWrite: 与FileOutputStream对应   将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。   Public FileWrite(file f);   2)  chararrayWrite:与ByteArrayOutputStream对应 ,将字符缓冲器用作输出。       Public CharArrayWrite();   3) PrintWrite:生成格式化输出       public PrintWriter(outputstream os);   4) filterWriter:用于写入过滤字符流      protected FilterWriter(Writer w);   5) PipedWriter:与PipedOutputStream对应

    6) StringWriter:无与之对应的以字节为导向的stream

    主要方法:

    (1) public void write(int c) throws IOException; //将整型值c的低16位写入输出流

    (2) public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流

    (3) public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流

    (4) public void write(String str) throws IOException; //将字符串str中的字符写入输出流

    (5) public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流

    (6) flush( ) //刷空输出流,并输出所有被缓存的字节。

    (7)close()   关闭流 public abstract void close() throws IOException

    3 .InputStream与Reader差别 OutputStream与Writer差别

    InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit) Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题

    import java.io.*;

    public class EncodeTest {

    private static void readBuff(byte [] buff) throws IOException {

    ByteArrayInputStream in =new ByteArrayInputStream(buff);

    int data;

    while((data=in.read())!=-1)   System.out.print(data+"  ");

    System.out.println();     in.close();     }

    public static void main(String args[]) throws IOException {

    System.out.println("内存中采用unicode字符编码:" );

    char   c='好';

    int lowBit=c&0xFF;     int highBit=(c&0xFF00)>>8;

    System.out.println(""+lowBit+"   "+highBit);

    String s="好";

    System.out.println("本地操作系统默认字符编码:");

    readBuff(s.getBytes());

    System.out.println("采用GBK字符编码:");

    readBuff(s.getBytes("GBK"));

    System.out.println("采用UTF-8字符编码:");

    readBuff(s.getBytes("UTF-8"));      }

    }

    import java.io.*;

    public class EncodeTest {

    private static void readBuff(byte [] buff) throws IOException {

    ByteArrayInputStream in =new ByteArrayInputStream(buff);

    int data;

    while((data=in.read())!=-1) System.out.print(data+" ");

    System.out.println(); in.close(); }

    public static void main(String args[]) throws IOException {

    System.out.println("内存中采用unicode字符编码:" );

    char c='好';

    int lowBit=c&0xFF; int highBit=(c&0xFF00)>>8;

    System.out.println(""+lowBit+" "+highBit);

    String s="好";

    System.out.println("本地操作系统默认字符编码:");

    readBuff(s.getBytes());

    System.out.println("采用GBK字符编码:");

    readBuff(s.getBytes("GBK"));

    System.out.println("采用UTF-8字符编码:");

    readBuff(s.getBytes("UTF-8")); }

    }

    1354191297_8218.jpg Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存 Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。

    9. IOException异常类的子类

    1.public class  EOFException :   非正常到达文件尾或输入流尾时,抛出这种类型的异常。 2.public class FileNotFoundException:   当文件找不到时,抛出的异常。 3.public class InterruptedIOException:   当I/O操作被中断时,抛出这种类型的异常。

    五、文件的读写

    Java提供了一系列的读写文件的类和方法。在Java中,所有的文件都是字节形式的。Java提供从文件读写字节的方法。而且,Java允许在字符形式的对象中使用字节文件流。

    两个最常用的流类是FileInputStream和FileOutputStream,它们生成与文件链接的字节流。为打开文件,只需创建这些类中某一个类的一个对象,在构造函数中以参数形式指定文件的名称。这两个类都支持其他形式的重载构造函数。下面是这里将要用到的形式:

    FileInputStream(String fileName) throws FileNotFoundException

    FileOutputStream(String fileName) throws FileNotFoundException

    fileName指定需要打开的文件名。当创建了一个输入流而文件不存在时,引发FileNotFoundException异常。对于输出流,如果文件不能生成,则引发FileNotFoundException异常。如果一个输出文件被打开,所有原先存在的同名的文件被破坏。注意:在早期的Java版本中,当输出文件不能创建时FileOutputStream()引发一个IOException异常。这在Java 2中有所修改。当对文件的操作结束后,需要调用close( )来关闭文件。该方法在FileInputStream和FileOutputStream中都有定义。如下:voidclose( ) throws IOException

    为读文件,可以使用在FileInputStream中定义的read( )方法。这里用到的如下:intread( ) throws IOException

    该方法每次被调用,它仅从文件中读取一个字节并将该字节以整数形式返回。当读到文件尾时,read( )返回-1。该方法可以引发IOException异常。下面的程序用read()来输入和显示文本文件的内容,该文件名以命令行形式指定。注意try/catch块处理程序运行时可能发生的两个错误——未找到指定的文件或用户忘记包括文件名了。

    import java.io.*;classShowFile {public static voidmain(String args[])

    throws IOException

    {inti;

    FileInputStream fin;try{

    fin= new FileInputStream(args[0]);

    }catch(FileNotFoundException e) {

    System.out.println("File Not Found");return;

    }catch(ArrayIndexOutOfBoundsException e) {

    System.out.println("Usage: ShowFile File");return;

    }//read characters until EOF is encountered

    do{

    i=fin.read();if(i != -1) System.out.print((char) i);

    }while(i != -1);

    fin.close();

    }

    }

    向文件中写数据,需用FileOutputStream定义的write()方法。它的最简单形式如下:void write(intbyteval) throws IOException

    该方法按照byteval指定的数目向文件写入字节。尽管byteval作为整数声明,但仅低8位字节可以写入文件。如果在写的过程中出现问题,一个IOException被引发。下面的例子用write()拷贝一个文本文件:

    import java.io.*;classCopyFile {public static voidmain(String args[])

    throws IOException

    {inti;

    FileInputStream fin;

    FileOutputStream fout;try{//open input file

    try{

    fin= new FileInputStream(args[0]);

    }catch(FileNotFoundException e) {

    System.out.println("Input File Not Found");return;

    }//open output file

    try{

    fout= new FileOutputStream(args[1]);

    }catch(FileNotFoundException e) {

    System.out.println("Error Opening Output File");return;

    }

    }catch(ArrayIndexOutOfBoundsException e) {

    System.out.println("Usage: CopyFile From To");return;

    }//Copy File

    try{do{

    i=fin.read();if(i != -1) fout.write(i);

    }while(i != -1);

    }catch(IOException e) {

    System.out.println("File Error");

    }

    fin.close();

    fout.close();

    }

    }

    注意本程序中和前面ShowFile程序中处理潜在输入/输出错误的方法。不像其他的计算机语言,包括C和C++,这些语言用错误代码报告文件错误,而Java用异常处理机制。这样不仅是文件处理更为简洁,而且使Java正在执行输入时容易区分是文件出错还是EOF条件问题。在C/C++中,很多输入函数在出错时和到达文件结尾时返回相同的值(也就是说,在C/C++中,EOF情况与输入错误情况映射相同)。这通常意味着程序员必须还要编写特殊程序语句来判定究竟是哪种事件发生。Java中,错误通过异常引发,而不是通过read()的返回值。这样,当read( )返回-1时,它仅表示一点:遇到了文件的结尾。

    展开全文
  • 展开全部Java语言的输入e69da5e6ba...在Java类库中,IO部分的内容很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据,字符串流,对象,zip文件....本文的目的为大家做一...

    展开全部

    Java语言的输入e69da5e6ba9062616964757a686964616f31333330336364输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象。在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流....本文的目的是为大家做一个简要的介绍。

    流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样,如下图:

    Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的:

    在这其中InputStream和OutputStream在早期的Java版本中就已经存在了,它们是基于字节流的,而基于字符流的Reader和Writer是后来加入作为补充的。以上的层次图是Java类库中的一个基本的层次体系。

    在这四个抽象类中,InputStream和Reader定义了完全相同的接口:

    int read()

    int read(char cbuf[])

    int read(char cbuf[], int offset, int length)

    而OutputStream和Writer也是如此:

    int write(int c)

    int write(char cbuf[])

    int write(char cbuf[], int offset, int length)

    这六个方法都是最基本的,read()和write()通过方法的重载来读写一个字节,或者一个字节数组。

    更多灵活多变的功能是由它们的子类来扩充完成的。知道了Java输入输出的基本层次结构以后,本文在这里想给大家一些以后可以反复应用例子,对于所有子类的细节及其功能并不详细讨论。

    import java.io.*;

    public class IOStreamDemo {

    public void samples() throws IOException {

    //1. 这是从键盘读入一行数据,返回的是一个字符串

    BufferedReader stdin =new BufferedReader(new InputStreamReader(System.in));

    System.out.print("Enter a line:");

    System.out.println(stdin.readLine());

    //2. 这是从文件中逐行读入数据

    BufferedReader in = new BufferedReader(new FileReader("IOStreamDemo.java"));

    String s, s2 = new String();

    while((s = in.readLine())!= null)

    s2 += s + "\n";

    in.close();

    //3. 这是从一个字符串中逐个读入字节

    StringReader in1 = new StringReader(s2);

    int c;

    while((c = in1.read()) != -1)

    System.out.print((char)c);

    //4. 这是将一个字符串写入文件

    try {

    BufferedReader in2 = new BufferedReader(new StringReader(s2));

    PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

    int lineCount = 1;

    while((s = in2.readLine()) != null )

    out1.println(lineCount++ + ": " + s);

    out1.close();

    } catch(EOFException e) {

    System.err.println("End of stream");

    }

    }

    }

    对于上面的例子,需要说明的有以下几点:

    1. BufferedReader是Reader的一个子类,它具有缓冲的作用,避免了频繁的从物理设备中读取信息。它有以下两个构造函数:

    BufferedReader(Reader in)

    BufferedReader(Reader in, int sz)

    这里的sz是指定缓冲区的大小。

    它的基本方法:

    void close() //关闭流

    void mark(int readAheadLimit) //标记当前位置

    boolean markSupported() //是否支持标记

    int read() //继承自Reader的基本方法

    int read(char[] cbuf, int off, int len) //继承自Reader的基本方法

    String readLine() //读取一行内容并以字符串形式返回

    boolean ready() //判断流是否已经做好读入的准备

    void reset() //重设到最近的一个标记

    long skip(long n) //跳过指定个数的字符读取

    2. InputStreamReader是InputStream和Reader之间的桥梁,由于System.in是字节流,需要用它来包装之后变为字符流供给 BufferedReader使用。

    3. PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

    这句话体现了Java输入输出系统的一个特点,为了达到某个目的,需要包装好几层。首先,输出目的地是文件IODemo.out,所以最内层包装的是FileWriter,建立一个输出文件流,接下来,我们希望这个流是缓冲的,所以用BufferedWriter来包装它以达到目的,最后,我们需要格式化输出结果,于是将PrintWriter包在最外层。

    Java提供了这样一个功能,将标准的输入输出流转向,也就是说,我们可以将某个其他的流设为标准输入或输出流,看下面这个例子:

    import java.io.*;

    public class Redirecting {

    public static void main(String[] args) throws IOException {

    PrintStream console = System.out;

    BufferedInputStream in = new BufferedInputStream( new FileInputStream( "Redirecting.java"));

    PrintStream out = new PrintStream( new BufferedOutputStream( new FileOutputStream("test.out")));

    System.setIn(in);

    System.setOut(out);

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

    String s;

    while((s = br.readLine()) != null)

    System.out.println(s);

    out.close();

    System.setOut(console);

    }

    }

    在这里java.lang.System的静态方法

    static void setIn(InputStream in)

    static void setOut(PrintStream out)

    提供了重新定义标准输入输出流的方法,这样做是很方便的,比如一个程序的结果有很多,有时候甚至要翻页显示,这样不便于观看结果,这是你就可以将标准输出流定义为一个文件流,程序运行完之后打开相应的文件观看结果,就直观了许多。

    Java流有着另一个重要的用途,那就是利用对象流对对象进行序列化。下面将开始介绍这方面的问题。

    在一个程序运行的时候,其中的变量数据是保存在内存中的,一旦程序结束这些数据将不会被保存,一种解决的办法是将数据写入文件,而Java中提供了一种机制,它可以将程序中的对象写入文件,之后再从文件中把对象读出来重新建立。这就是所谓的对象序列化Java中引入它主要是为了RMI(Remote Method Invocation)和Java Bean所用,不过在平时应用中,它也是很有用的一种技术。

    所有需要实现对象序列化的对象必须首先实现Serializable接口。下面看一个例子:

    import java.io.*;

    import java.util.*;

    public class Logon implements Serializable {

    private Date date = new Date();

    private String username;

    private transient String password;

    Logon(String name, String pwd) {

    username = name;

    password = pwd;

    }

    public String toString() {

    String pwd = (password == null) ? "(n/a)" : password;

    return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

    Logon a = new Logon("Morgan", "morgan83");

    System.out.println( "logon a = " + a);

    ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));

    o.writeObject(a);

    o.close();

    int seconds = 5;

    long t = System.currentTimeMillis() + seconds * 1000;

    while(System.currentTimeMillis() < t) ;

    ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));

    System.out.println( "Recovering object at " + new Date());

    a = (Logon)in.readObject();

    System.out.println("logon a = " + a);

    }

    }

    类Logon是一个记录登录信息的类,包括用户名和密码。首先它实现了接口Serializable,这就标志着它可以被序列化。之后再main方法里ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));新建一个对象输出流包装一个文件流,表示对象序列化的目的地是文件Logon.out。然后用方法writeObject开始写入。想要还原的时候也很简单ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));新建一个对象输入流以文件流Logon.out为参数,之后调用readObject方法就可以了。

    需要说明一点,对象序列化有一个神奇之处就是,它建立了一张对象网,将当前要序列化的对象中所持有的引用指向的对象都包含起来一起写入到文件,更为奇妙的是,如果你一次序列化了好几个对象,它们中相同的内容将会被共享写入。这的确是一个非常好的机制。它可以用来实现深层拷贝。

    关键字transient在这里表示当前内容将不被序列化,比如例子中的密码,需要保密,所以没有被写入文件。

    对Java的输入输出功能,就浅浅的介绍到这里,本文的目的只是开一个好头,希望能让大家对Java输入输出流有个基本的认识。

    2Q==

    已赞过

    已踩过<

    你对这个回答的评价是?

    评论

    收起

    展开全文
  • JAVA基础(标准输入流

    千次阅读 2019-07-09 14:59:49
    System.inInputStream, 标准输入流, 默认可以从键盘输入读取字节数据 System.outPrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据 2,修改标准输入输出流 修改输入流: System.set...

    1,什么是标准输入输出流(

    • System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据

    • System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据

     

    2,修改标准输入输出流

    • 修改输入流: System.setIn(InputStream)

    • 修改输出流: System.setOut(PrintStream)

    【1】 SystemInOut

    public class Demo06_SystemInOut {
    
        public static void main(String[] args) throws IOException {
    
            //demo1();
    
            System.setIn(new FileInputStream("a.txt"));            //改变标准输入流
    
            System.setOut(new PrintStream("b.txt"));            //改变标注输出流
    
            
    
            InputStream is = System.in;                            //获取标准的键盘输入流,默认指向键盘,改变后指向文件
    
            PrintStream ps = System.out;                        //获取标准输出流,默认指向的是控制台,改变后就指向文件
    
            
    
            int b;
    
            while((b = is.read()) != -1) {
    
                ps.write(b);
    
            }
    
            //System.out.println();                                //也是一个输出流,不用关,因为没有和硬盘上的文件产生关联的管道
    
            is.close();
    
            ps.close();
    
            
    
        }
    
    
    
        public static void demo1() throws IOException {
    
            InputStream is = System.in;
    
            int x = is.read();
    
            System.out.println(x);
    
            
    
            is.close();
    
            
    
            InputStream is2 = System.in;
    
            int y = is2.read();
    
            System.out.println(y);
    
        }
    
    
    
    
    
    }

     

    3,修改标准输入输出流拷贝图片

    import java.io.FileInputStream;
    
    import java.io.FileNotFoundException;
    
    import java.io.IOException;
    
    import java.io.InputStream;
    
    import java.io.PrintStream;
    
    public class Test2 {
    
        public static void main(String[] args) throws IOException {
    
            System.setIn(new FileInputStream("元.jpg"));            //改变标准输入流
    
            System.setOut(new PrintStream("copy.jpg"));             //改变标准输出流
    
            
    
            InputStream is = System.in;
    
            PrintStream ps = System.out;
    
            
    
            byte[] arr = new byte[1024];
    
            int len;
    
            
    
            while((len = is.read(arr)) != -1) {
    
                ps.write(arr, 0, len);
    
            }
    
            is.close();
    
            ps.close();
    
        }
    
    }
    
    

     

     

    展开全文
  • 前几天用到了管道流,在...都把一个输入流定向到另一个输出流(个人感输出流定向到另一个输入流,相对来说)。下边的例子就是把程序的输出流重定向到一个文件(流)中。importjava.io.*;publicclassRedirect{public...
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • 一、什么是IOJava中I/O操作主要Java的进行输入,输出操作。Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。人核Java中表示...
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作. Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • java总结输入流输出流

    千次阅读 多人点赞 2018-05-11 15:50:00
    1.什么是IO Java中I/O操作主要指使用Java进行输入,输出操作. Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中...
  • java输入语句 System.in读取标准复输入设备数据(从标准输入获取数据,一般键盘),其数据类型为InputStream。Scanner in=new Scanner(System.in);新建一个扫描器,扫描你输入(从标准输入获取数据,一般键盘)的...
  • Java总结输入流输出流

    2017-05-31 11:13:00
    学习Java的同学注意了!... Java中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方...
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • 1什么是IOJava中I/O操作主要指使用Java进行输入,输出操作。Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作。Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • [JAVA]标准输入流笔记1

    2017-04-26 23:19:51
    主要是什么时候输入结束,才能把相应个数的数输入数组中。对这方面真的不是很了解,平时感觉很小的问题到了考试的时候才发现一脸懵逼,所以感觉还是多做笔记,不要以为不起眼就不好好弄,一定要懂得细节决定成败,多...
  • Java输入输出

    千次阅读 2013-11-04 10:25:43
     Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据的方式读写它的数据的方法。  ...
  • 1.什么是IOJava中I/O操作主要指使用Java进行输入,输出操作. Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示...
  • java输入流输出流

    2015-04-23 17:14:35
    1.什么是IO ... Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以
  • Java 输入输出

    2017-11-15 13:45:00
    Java中I/O操作主要指使用Java进行输入,输出操作.Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的...
  • java输入流输出流详解

    2017-09-23 11:43:19
     Java所有的I/O机制都基于数据进行输入输出,这些数据表示了字符或者字节数据的流动序列。Java的I/O提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据的方式读写它的数据的方法。  ...
  • I/O 是Input/Output(输入、输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出。2、流流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据。流与数据源,或数据源流向的媒介相关联。在Java IO...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 456
精华内容 182
关键字:

java标准输入流是什么

java 订阅