Java IO总结

一、java io 概述

1.1 相关概念

Java IO

Java IO即Java 输入输出系统。不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO(文件、控制台、网络),我们还要考虑具体和它们的通信方式(顺序、随机、二进制、按字符、按字、按行等等)。Java类库的设计者通过设计大量的类来攻克这些难题,这些类就位于java.io包中。

在JDK1.4之后,为了提高Java IO的效率,Java又提供了一套新的IO,Java New IO简称Java NIO。它在标准java代码中提供了高速的面向块的IO操作。

在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。

IO相关的媒介

Java的IO包主要关注的是从原始数据源的读取以及输出原始数据到目标媒介。以下是最典型的数据源和目标媒介:

文件

管道

网络连接

内存缓存

System.in, System.out, System.error(注:Java标准输入、输出、错误输出)

二、Java IO类库的框架

2.1 Java IO的类型

虽然java IO类库庞大,但总体来说其框架还是很清楚的。从是读媒介还是写媒介的维度看,Java IO可以分为:

输入流:InputStream和Reader

输出流:OutputStream和Writer

而从其处理流的类型的维度上看,Java IO又可以分为:

字节流:InputStream和OutputStream

字符流:Reader和Writer

下面这幅图就清晰的描述了JavaIO的分类:

-字节流字符流输入流InputStreamReader输出流OutputStreamWriter

我们的程序需要通过InputStream或Reader从数据源读取数据,然后用OutputStream或者Writer将数据写入到目标媒介中。其中,InputStream和Reader与数据源相关联,OutputStream和writer与目标媒介相关联。 以下的图说明了这一点:

2.2 IO 类库

上面我们介绍了Java IO中的四各类:InputStream、OutputStream、Reader、Writer,其实在我们的实际应用中,我们用到的一般是它们的子类,之所以设计这么多子类,目的就是让每一个类都负责不同的功能,以方便我们开发各种应用。各类用途汇总如下:

文件访问

  1. 网络访问

    内存缓存访问

    线程内部通信(管道)

    缓冲

    过滤

    解析

    读写文本 (Readers / Writers)

    读写基本类型数据 (long, int etc.)

    读写对象

三、Java IO的基本用法

基本方法:(注意:throws IOEception : 指的是会抛出 IOEception 。要去try–catch)

 int read() throws IOException      //读取一个字符并以整数的形式返回(0~255, 返回-1意味着已经到输入流的末尾。
 int read(byte[] buffer) throws IOException  //读取一系列字节存储到一个数组buffer,返回实际读取的字节数,返回-1意味着已经到输入流的末尾。
 int read(byte[] buffer,int offset, int length) throws IOEception           //读取length个字节,并字节数组buffer[offset]开始存,返回实际读取的字节数,返回-1意味着已经到输入流的末尾。
void close() throws IOExcption                                                   //关闭流释放内存资源
void skip(long n) throws IOExcption                                         //跳过n个字节不读,返回实际跳过的字节数
 

 

//读取本身这个java文件,并且打印出代码



import java.io.*;

public class TestFileInputStream{

    public static void main(String[] args){

        FileInputStream in = null;

        try{

            in = new FileInputStream("F:\\javajava\\TestFileInputStream.java");   //注意:try--catch里面的东西,就像方法里面的局部变量!!

        }catch(FileNotFoundException ex){                          //所以没有在try里面写FileInputStream in =new FileInputStream("F:\\javajava\\TestFileInputStream.java"); 

            System.out.println("没有找到文件");                      //要是写了。在之后的in.close()就无法通过编译。找不到这个方法,程序认为没有in这个文件

            System.exit(-1);

        }                     

      int count=0;

      int b =0;

        try{

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

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

                count++;

            }

            in.close();

        }catch(IOException s){

            System.out.println("文件出现问题");           //这里程序运行后会打印出“???”,因为Input/OutputStream是字节流,单个字节操作,中文是两个字节

            System.exit(0);

        }

        System.out.println(count+"字符被打印");

    }

}

 

字节流OutputStream(可以写入数据)

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



基本方法:

void write(int b) throws IOEception               //向输出流写入一个字节数据,该字节数据为参数b的低8位
void write(byte[] b) throws IOEception         //将一个字节类型的数组中的数据写入输出流
void write(byte[] b,int off,int len) throws IOEception      //将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void close() throws IOEception                                     //关闭流释放内存资源
void flush() throws IOEception                                     //将输出流中缓冲的数据全部写出到目的地
 

 

//复制我的F盘\\javajava\\HelloWorld.java文件内容到F:\\javajava\\game1\\HW.java

 

import java.io.*;

public class TestFileOutputStream{

    public static void main(String[] args){

        FileInputStream in = null;

        FileOutputStream out = null;

        int b = 0;

        try{

            in = new FileInputStream("F:\\javajava\\HelloWorld.java");

            out = new FileOutputStream("F:\\javajava\\game1\\HW.java");           //如果没有这个文件,则程序会帮你创建这个文件

        }catch(FileNotFoundException ex){

            System.out.println("文件没有找到");

            System.exit(-1);

        }

        try{

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

                out.write((char)b);

            }

            System.out.println("文件复制成功");

        }catch(IOException x){

            System.out.println("文件出错");

            System.exit(-1);

        }

    }

}

字符流Reader:

继承自Reader 的流都是用于向程序中输入数据(读取该文件的数据),且数据的单位为字符(16 bit)

基本方法:

int read() throws IOException //读取一个字符并以整数的形式返回(0~255, 返回-1意味着已经到输入流的末尾。
int read(char[] cbuf) throws IOException //读取一系列字节存储到一个数组cbuf,返回实际读取的字节数,返回-1意味着已经到输入流的末尾。
int read(char[] cbuf,int offset, int length) throws IOEception //读取length个字节,并字节数组cbufr[offset]开始存,返回实际读取的字节数,返回-1意味着已经到输入流的末尾。
void close() throws IOExcption //关闭流释放内存资源
void skip(long n) throws IOExcption //跳过n个字节不读,返回实际跳过的字节数

//打印当前文件的代码

import java.io.*;

public class TestFileReader{
public static void main(String[] args){

    FileReader fr = null;

    int c =0;

    try{

        fr =new FileReader("F:\\javajava\\TestFileReader.java");

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

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

        }

        fr.close();

    }catch(FileNotFoundException ex){

        System.out.println("文件没有找到");           //这里程序运行后就会打印完整 的中文,英文Reader,Writer都是字符流,可以两个字节操作

        System.exit(-1);

    }catch(IOException e){

        System.out.println("文件出错");

        System.exit(-1);

    }

}

}

Writer:

继承自Writer的流都是用于程序中输入数据,且数据的单位为字符(16 bit):

基本方法:

void write(int c) throws IOEception                                      //向输出流写入一个字符数据,该字节数据为参数c的低8位
void write(char[] cbuf) throws IOEception                            //将一个字符类型的数组中的数据写入输出流
void write(char[] cbuf,int off,int len) throws IOEception      //将一个字符类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(String string) throws IOEception                         //将一个字符串中的字符写入到输出流
void write(String string,int offset,int length) throws IOEception    //将一个字符串从offset开始的length个字符写入到输出流
void close() throws IOEception                                    //关闭流释放内存资源
void flush() throws IOEception                                    //将输出流中缓冲的数据全部写出到目的地
 

//写入文件 50000以内的符号(包含中文,字母等等)

 

import java.io.*;

public class TestFileWriter{

    public static void main(String[] args){

        FileWriter fw = null;

        try{

            fw = new FileWriter("F:\\javajava\\game1\\unicode.dat");

            for(int c=0;c<=50000;c++){   //char两个字节,最大到65535,所以没有越界

                fw.write(c);

            }

            fw.close();

        }catch(IOException el){

            el.printStackTrace();

            System.out.println("文件写入错误");

            System.exit(-1);

        }

    }

}

处理流:

处理类型 字符流 字节流

  • Buffering BufferedReader

    BufferedWriter

    BufferedInputStream

    BufferedOutputStream

    Filtering FilterReader

    FilterWriter

    FilterInputStream

    FilterOutputStream

    Converting between byte and character InputStreamReader

    OutputStreamWriter

    Object Serialization — ObjectInputStream

    ObjectOutputStream

    Data conversion — DataInputStream

    DataOutputStream

    Counting LineNumberReader LineNumberInputStream Peeking
    ahead PushbackReader PushbackInputStream
    Printing PrintWriter PrintStream

缓冲流(Buffered):

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

BufferedReader(Reader in)
BufferedReader(Reader in ,int sz) //sz为自定义缓存区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out,int size)
缓冲输入流支持其父类的mark和reset方法
BufferedReader提供了readLine方法用于读取一行字符串
BufferedReader提供了newLine方法用于读取一行字符串
对于输出的缓冲流,写入的数据会在内存中缓存,使用flush方法将会使内存中的数据理科写出

一些例子:

import java.io.*;

public class TestBufferStream1{
public static void main(String[] args){

    try{

        FileInputStream fis = new FileInputStream("F:\\javajava\\HelloWorld.java");

        BufferedInputStream dis = new BufferedInputStream(fis);

        int c = 0;

        System.out.println(dis.read());

        System.out.println(dis.read());

        dis.mark(100);  //将标记直接标到100,从第100个字符开始读取

        for(int i=0;i<=10&&(c=dis.read())!=-1;i++){

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

        }

        System.out.println();

        dis.reset();    //重新回到刚才标记的那个点

        for(int i=0;i<=10&&(c=dis.read())!=-1;i++){

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

        }

        dis.close();

        

    }catch(IOException ex){

        System.out.println("文件没有找到");

        System.exit(-1);

    }

}

}

正是有这些处理流,使得这些高亮的方法得以使用。

import java.io.*;

public class TestBufferStream2{
public static void main(String[] args){

    try{

    BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\javajava\\game1\\write1.java"));

    BufferedReader br = new BufferedReader(new FileReader("F:\\javajava\\superself.java"));

    String s = null;

    for(int i=0;i<=100;i++){

        s=String.valueOf(Math.random()); //将随机数转换为字符串

        bw.write(s);

        bw.newLine();        //缓冲流提供的方法,添加一行

    }

    //bw.flush();      //刷新流,将东西倒光

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

        System.out.println(s);

    }

    bw.close();

    br.close();

}catch(IOException ex){

    ex.printStackTrace();

}

}

}

转换流

InputStreamReader 和 OutputStreamWriter用与字节数到字符数据之间的转换
InputStreamReader 需要和 InputStream “套接”。
OutputStreamWriter 需要和 OutputStream “套接”。
转换流在构造时可以指定其编码集合,例如:InputStream isr = new InputStreamReader(System.in,“ISO8859_1”);

import java.io.*;

public class TestTransForm1{
public static void main(String[] args){

    try{

        OutputStreamWriter osw = new OutputStreamWriter(                          //这就是转换流

                new FileOutputStream("F:\\javajava\\game1\\transwriter.txt"));

        System.out.println(osw.getEncoding());

        osw.close();

        osw  = new OutputStreamWriter(

                new FileOutputStream("F:\\javajava\\game1\\transwriter.txt",true),

                "ISO8859_1");         //这个地方的"true",使得在文件末端写入数据,而不会覆盖!!

                                     //ISO8859_1的意思是国际编码

        osw.write("sdasasdasdadas");

        System.out.println(osw.getEncoding());

        osw.close();

    }catch(IOException e){

        e.printStackTrace();

    }

}

}



import java.io.*;

public class TestTransForm2{
public static void main(String [] args){

    InputStreamReader isr = new InputStreamReader(System.in);       //得到键盘的输入

    BufferedReader br = new BufferedReader(isr);              //处理流使得可以用下面 直接读取一行的方法

    String s =null;

    try{

        s = br.readLine();

        while(s!=null){

            if(s.equalsIgnoreCase("exit")) break;                          //忽略大小写

            System.out.println(s.toUpperCase());

            s=br.readLine();

        }

        br.close();

    }catch(IOException e){

        e.printStackTrace();

    }

}

}

数据流

DataInputStream 和 DataOutputStream分别继承自InputStream 和 OutputStream ,它属于流,需要分别“套接”在InputStream和OutputStream类型的节点流上
DataInputStream 和 OutputStream提供了可以存取与机器无关的java原始类型数据(如:int,double等)的方法。

//高亮的都是Data…Stream带来的方法

//此程序先在节点流ByreArray…Stream套上DataOutputStream数据流,后写进去东西,再套用DataInputStream读出来

i

mport java.io.*;

public  class TestDataStream{
public static void main(String[] args){

    ByteArrayOutputStream baos =

                                            new ByteArrayOutputStream();

    DataOutputStream dos =

                                            new DataOutputStream(baos);

    try{

        dos.writeDouble(Math.random());

        dos.writeBoolean(true);

        ByteArrayInputStream bais =

                new ByteArrayInputStream(baos.toByteArray());

        System.out.println(bais.available());

        DataInputStream dis = new DataInputStream(bais);

        System.out.println(dis.readDouble());

        System.out.println(dis.readBoolean());

        dos.close(); dis.close();

    }catch(IOException e){

        e.printStackTrace();

    }

}

}

Print 流:

你看就叫Print,所以这里就只有输出流,没有输入流了。(用于输出很舒服)

PrintWriter和PrintStream都属于输出流,分别针对字符和字节。
PrintWriter和PrintStream提供了重载的print
Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息。
PrintWriter和PrintStream有自动flush功能。

一些方法:

PrintWriter(Writer out)
PrintWriter(Writer out,boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFulsh)
PrintStream(OutputStream out)
PrintStream(OutputStream out,boolean autoFlush)

import java.io.*;

public class TestPrintStream1{
public static void main(String[] args){

    PrintStream ps =null;

    try{

        FileOutputStream fos =

                        new FileOutputStream("F:\\javajava\\game1\\log.dat");

        ps = new PrintStream(fos);

    }catch(IOException e){

        e.printStackTrace();

    }

    if(ps !=null){

        System.setOut(ps);      //把输出的地方从命令行变到了这个ps文件里面

    }

    int ln = 0;

    for(char c =0;c<=60000;c++){

        System.out.print(c+" ");

        if(ln++ >=100){

            System.out.println();

            ln=0;

        }

    }

}

}

//读取文件并且打印出来

import java.io.*;

public class TestPrintStream2{
public static void main(String[]args){

    String filename = args[0];

    if(filename!=null){

        printList(filename,System.out);

    }

}

public static void printList(String f,PrintStream fs){   //这是一个方法

    try{

        BufferedReader br =

                                new BufferedReader(new FileReader(f));

        String s =null;

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

            fs.println(s);

        }

        br.close();

    }catch(IOException e){

        fs.println("无法读取文件");

    }

}

}

//log记录修改程序的日志

    import java.util.*;
    
    import java.io.*;    

public class TestPrintStream3{
public static void main(String[] args){

    String s =null;

    BufferedReader br = new BufferedReader(

                                            new InputStreamReader(System.in));

    try{

        FileWriter fw = new FileWriter("F:\\javajava\\game1\\logdfile.log",true);

        PrintWriter log = new PrintWriter(fw);

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

            if(s.equalsIgnoreCase("exit")) break;

            System.out.println(s.toUpperCase());

            log.println("----");

            log.println(s.toUpperCase());

            log.flush();

        }

        log.println("==="+new Date()+"===");

        log.flush();

        log.close();

    }catch(IOException e){

        e.printStackTrace();

    }

}

}

Object 流:

直接将Object写入或读出

import java.io.*;

public class TestObjectIO{
public static void main(String[] args){

    T t =new T();

    t.k = 8;

    FileOutputStream fos = new FileOutputStream("F:\\javajava\\game1\\testobject.dat");

    ObjectOutputStream oos = new ObjectOutputStream(fos);

    oos.writeObject(t);

    oos.flush();

    oos.close();

    

    FileInputStream fis  = new FileInputStream("F:\\javajava\\game1\\testobject.dat");

    ObjectInputStream ois = new ObjectInputStream(fis);

    T tReaded =(T)ois.readObject();

    System.out.println(tReaded.i+" "+tReaded.j+" "+tReaded.d+" "+tReaded.k);

}

}

class T implements Serializable{ //要想把一个类的对象化实现序列化一个字节流(写到硬盘或者网络上)必须实现这个接口

int i=0;                                                //Serializable:可以被序列化的

int j =9;

double d =2.3;

int k =0;                                           //如果是这样写的 transient(透明的意思) int k =15; 那么主函数将会打印出k为0

                                                         //也就是说transient 在序列化是不予考虑, 不会写入硬盘

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值