java基础之IO(重点)

来源:互联网 发布:彩虹六号软件 编辑:程序博客网 时间:2024/06/15 05:20

(一)java.io包

Java.io 包包含了所有操作输入、输出需要的类。对于数据的输入和输出操作以流(stream)的方式进行。

注意:流本质就是一个数据序列,可以抽象理解为接水的管道。

1、分类

1、基于字节操作的I/O接口:InputStreamOutputStream

2、基于字符操作的I/O接口:WriterReader

3、基于磁盘操作的I/O接口:File

4、基于网络操作的I/O接口: Socket(不在java.io包下)

按数据流方向的不同分为输入流和输出流(输入和输出就是按程序来划分的)

按处理数据单位不同分为字节流和字符流(字节流相当于最原始的流,按一个个字节操作数据即:二进制数        字符流就是按一个个字符操作数据,一个字符就是两个字节,直接可以操作中文)

按照功能不同分为节点流和处理流

sdk中所提供的所有的流类型都分别继承一下四个抽象流类型,是抽象类,不是接口。

注意:输入流和输出流是按程序作为参照的,不是硬盘文件。对于程序,写就是输出,读就是输入。

   字节流  字符流       输入流  InputStream  Reader   输出流  OutputStream  Writer

可以把上面四个抽象类,理解为四个管道。管道的一端接文件,一端接程序。


(二)InputStream(输入字节流)抽象类

继承自InputStream的流都是用于向程序中输入数据,且数据的单位是字节(8位)

1、InputStream的基本方法(都会抛出IOException)

int  read()方法  读取一个字节并以整数的形式返回(0-255),如果返回-1表示已到输入流的末尾。

int  read(byte[]  buffer):读取一系列字节并存储到一个数组buffer,返回实际读取的字节数。返回-1.表示已读到输入流末尾。buffer是缓存,相当于用水桶来接水,先把水桶接满,然后在去倒水。

int  read(byte[] buffer,int  begin,int  length)

void close():关闭流释放内存资源


(三)OutputStream(输出字节流)抽象类  与InputStream对应

继承自OutputStream的流都是用于向程序中输出数据,且数据的单位是字节(8位)

void  write(int  b)  :表示向输出流写入一个字节数据,该字节数据为参数b的低八位。

void  write(byte[]  buffer)

void  write (byte[]  buffer,int  begin,int  length)

void close():关闭流释放内存资源

void  flush():将输出流中缓冲的数据全部写出到目的地。

注意:在close()方法之前,应该先调用flush()方法。


(四)Reader(输入字符流)字符流是解决中文操作。

继承自Reader的流都是向程序中输入数据,并且数据的单位是字符(16位)。

int   read()

int  read(char[]  cbuffer)

int read(char[]  cbuffer , int  begin, int  length)

void close()


(五)Writer(输出字符流)

继承自Writer的流都是向程序中输出数据,并且数据的单位是字符(16位)。

void  write(int  c):写入单个字符,要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。

void  write(char[]  cbuffer)

void  write(char[] cbuffer, int  begin , int length)

void  write(String  string)  :将一个字符串中的字符写入到输出流。

注意:为啥能写入一个字符串,因为字符串有一个方法:char[]   toCharArray()方法:字符串对象可以通过该方法把自己转换为一个字符数组。编译器会自动调用该方法。

void  write (String  string, int   begin, int  length)

void  close()

void  flush():将输出流中的缓冲数据全部写出到目的地

注意:在close()方法之前,应该先调用flush()方法。


(六)节点流类型(节点相当于数据源)(重点)

读写一个文件:

1、首先获取这个文件,获取该文件的路径加文件名:String path = getPath()+File.separator+getName()

2、利用File类,通过File类的构造方法获得文件对象,构造方法:File(String directoryPath, String filename)或者File(File dirObj, String filename)

3、利用节点流来读写文件的内容,FileInputStream(File  file)或者FileInputStream(String  filename)

  1. File file = new File ("hello.txt");   
  2. FileInputStream in=new FileInputStream(file);   
  3. InputStreamReader inReader=new InputStreamReader(in,"utf-8");   
  4. BufferedReader bufReader=new BufferedReader(inReader); 

    1. InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));   
    2.   while((ch = isr.read())!=-1)   
    3.   {   
    4.    System.out.print((char)ch);   
    5.   }  

    FileInputStream类以二进制输入/输出,I/O速度快且效率搞,但是它的read()方法读到的是一个字节(二进制数据),很不利于人们阅读。 

    而FileReader类弥补了这个缺陷,可以以文本格式输入/输出,非常方便;比如可以使用while((ch = filereader.read())!=-1 )循环来读取文件;也可以使用BufferedReader的readLine()方法一行一行的读取文本。 

    当我们读写文本文件的时候,采用Reader是非常方便的,比如FileReader, InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader,它是字节转换为字符的桥梁。 你可以在其构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。 


    节点流就直接从一个特定的数据源(节点)读写数据(如:文件,内存),相当于一个管道直接插到数据源,直接读写。

    父 类   InputStream OutputStream Reader Writer

    文 件   FileInputStream    FileOutputStrean    FileReader    FileWriter 文件进行处理的节点流

    数 组   ByteArrayInputStream    ByteArrayOutputStream    CharArrayReader     CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)

    字符串   无  无      StringReader      StringWriter 对字符串进行处理的节点流

    管 道   PipedInputStream   PipedOutputStream    PipedReader      PipedWriter 对管道进行处理的节点流,线程之间


    (七)处理流类型(注意构造方法)

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

    处理流就是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。(相当于包别的管道上的管道)。


    父 类 InputStream OutputStream Reader Writer

    缓冲流  BufferedImputStrean    BufferedOutputStream    BufferedReader         BufferedWriter  (常用)

    功能:需要父类作为参数构造,增加缓冲功能,避免频繁读写硬盘,可以初始化缓冲数据的大小,由于带了缓冲功能,所以就写数据的时候需要使用flush方法咯

    转换流  InputStreamReader     OutputStreamWriter-要inputStream或OutputStream作为参数,实现从字节流到字符流的转换

    数据流  DataInputStream         DataOutputStream -提供将基础数据类型写入到文件中,或者读取出来,

            为什么要有这个流呢?看这样的分析,如果没有这种流的话,有一个long,本身只占8个字节,如果我要写入到文件,需要转成字符串,然后在转成字符数组,那空间会占用很多,但是有了这种流之后就很方便了,直接将这8个字节写到文件就完了。。是不是既节约了内存空间有让程序写起来更加方便简单了呐。写倒是很简单,但是读取的时候就注意了,根据读取的数据类型,指针会往下移,所以你写的顺序必须要和读的顺序一致才能完成你正确的需求。

    对象流 用于直接将对象写入写出。

      流类有ObjectInputStream和ObjectOutputStream,本身这两个方法没什么,但是其要写出的对象有要求,该对象必须实现Serializable接口,来声明其是可以序列化的。否则,不能用对象流读写。

      还有一个关键字比较重要,transient,由于修饰实现了Serializable接口的类内的属性,被该修饰符修饰的属性,在以对象流的方式输出的时候,该字段会被忽略。


    1、缓冲流(重点:BufferedReader和BufferedWriter)

    构造方法:BufferedReader(Reader in)    BufferedReader(Reader in , int  size)    其中size定义缓存区的大小     

    BufferedWriter  BufferedInputStream   BufferedOutputStream  构造方法与之类似

    注意:BufferedReader提供了readLine()方法:用于读取一行字符串,通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。返回包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

    BufferedWriter提供了newLine()方法:写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 ('\n') 符。


    2、转换流:字节数据与字符数据之间的转换(重点)

    InputStreamReader 需要和 InputStream  套接

    OutputStreamWriter 需要和 OutputStream 套接

    注意:转换流在构造时,可以指定其编码集合

    InputStreamReader(InputStream in, String charsetName) 

    为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

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

    System类的静态属性in是InputStream类型。Java 的控制台输入由 System.in 完成。System.in具有阻塞方法,就是你不输入,程序不往下走。

    FileOutputStream(String name, boolean append):append为true表示从文件末尾处写入,而不是开始位置。 


    3、数据流

    作用:提供对java基础数据类型写入文件,或者是读出来。

    DataInputStream和DataOutputStream提供了可以存取与机器无关的java原始类型数据的方法。

    1、两个类的构造方法

    DataInputStream(InputStream  in )和DataOutputStream(OutputStream  out)

    注意:readUTF()方法:在网络传输数据常用,该方法读取使用 UTF-8 修改版格式编码的 Unicode 字符串的表示形式;然后以 String 的形式返回此字符串。

    UTF—8编码:比较省空间,多用在网络传输数据中。


    4、对象流(Object流):用于直接将对象写入和读取(重点)

         流类有ObjectInputStream和ObjectOutputStream,本身这两个方法没什么,但是其要写出的对象有要求,该对象必须实现Serializable接口,来声明其是可以序列化的。否则,不能用对象流读写。

      transient,由于修饰实现了Serializable接口的类内的属性,被该修饰符修饰的属性,在以对象流的方式输出的时候,该字段会被忽略。

    1、所保存的对象必须实现Serializable接口。

    2、 所保存的对象的属性也必须实现Serializable接口(该接口是标记接口,即没有任何方法的接口)

    3、 最好要给该对象提供一个版本号,private static final long serialVersionId。

    注意:实现Serializable接口,就是标记该对象可以序列化,即告诉编译器该对象可以序列化,对象的序列化有JVM控制。

    Externalizable接口:通过实现该接口可以实现自己来控制对象的序列化过程。 需要重写两个方法:writeExternal 和 readExternal 方法。

    java提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。即:该字节序列包含了对象的所有信息。
    对象的序列化的本质就是将对象转换成二进制数据流的一种实现方式。
    目的:就是方便对象的读取和存储。


    5、Print流:打印流

    PrintWriter和PrintStream都属于输出流,分别针对字符和字节。提供了重载的print()方法,println()方法用于多种数据类型的输出,有换行。

    注意:PrintWriter和PrintStream都有自动flush功能。同时二者的输出操作不会抛出异常,在内部就会被处理。


    public static void main(String[] args) throws IOException {        // 节点流FileOutputStream直接以A.txt作为数据源操作        FileOutputStream fileOutputStream = new FileOutputStream("A.txt");        // 过滤流BufferedOutputStream进一步装饰节点流,提供缓冲写        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(                fileOutputStream);        // 过滤流DataOutputStream进一步装饰过滤流,使其提供基本数据类型的写        DataOutputStream out = new DataOutputStream(bufferedOutputStream);        out.writeInt(3);        out.writeBoolean(true);        out.flush();        out.close();        // 此处输入节点流,过滤流正好跟上边输出对应,读者可举一反三        DataInputStream in = new DataInputStream(new BufferedInputStream(                new FileInputStream("A.txt")));        System.out.println(in.readInt());        System.out.println(in.readBoolean());        in.close();}

    原创粉丝点击