Java基础读书笔记(九)——输入流、输出流

1.流的概念

计算机中的流其实是一种信息转换。它是一种有序流,因此相对于某一对象,通常把对象接受外界的信息输入(input)称为输入流,相应地从对象向外输出(Output)的信息称为输出流,合称为输入/输出流(I/O Streams)。对象间进行信息或者数据的交换时,总是先将对象或数据转换为某种形式的流,再通过流的传输到达目的对象后将流转换为对象数据。所以,可以把流看做是一种数据的载体,通过它可以实现数据交换和传输。

在Java中,流仍是一个类的对象,很多文件的输入/输出操作都以此类的成员方法的方式来提供。

- Java的输入/输出流概述

Java流中分为两种,一种是字节流,另一种是字符流,每种流又分为输入和输出两种,并分别由四个抽象类来表示:InputStream、OutputStream、Reader、Writer。

(1)字节流:从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。

(2)字符流:从Reader和Write派生出的一系列类,这类流以16位Unicode码表示的字符为基本处理单位。

在这四个抽象类中,一些最基本的方法:

1)read()方法:当输入流被打开后,可以从里面读取信息。此方法可以从输入流中分离出一个或多个字节,如果字节没有准备好,则read命令将处于等待状态,直到字节流变为有效,即称为同步访问。在InputStream中的read()方法是个抽象方法,Java允许在InputStream流和Reader流的子类中重构read()方法。

2)write()方法:当输入流被打开后,可以使用write()方法向流中写入数据。Java允许在OutputStream流和Write流的子类中重构write()方法。

3)flush()方法:清空输入流。也就是强制把进程缓存中的数据提交给操作系统。并输出所有被缓存的字节。该方法将把缓存中所有内容强制输出到流中。

4)close()方法:对流操作完毕后,必须要将流对象关闭,此时流对象执行close()方法。close()方法不仅关闭输出流,而且释放与此流有关的所有系统资源。[关闭后的写操作会产生IOException异常。当停止I/O操作时,Java不会自动地清空(flush)和关闭数据流。因此,在I/O操作后,立即关不每一个数据流]

5)I/O中的异常:进行I/O操作时可能会产生I/O异常,这属于非运行时异常,应该在程序中处理。


2. 字节输入/输出流类

- Java的标准输入/输出流
  public static final InputStream in;
  public static final PrintStream out;

标准输入流System.in通常对应于键盘输入或者由主机环境(或用户)指定的另一个输入源;标准输出流System.out对应于显示器输出或由主机环境(或用户)指定的另一个输出目标。

实例:

public class Test1 {
    public static void main(String[] args) throws IOException {
        char a;
        System.out.println("Please input a char");
        a = (char)System.in.read();
        System.out.println("The char is:  " + a);
    }

}

运行结果:
这里写图片描述

- 文件输入/输出流类:
1. FileInputStream类

FileInputStream类创建一个能从文件读取字节的InputStream,常用的构造方法:

1)FileInputStream(File fileobj):
通过打开一个到实际文件的连接来创建一个FileInputStream,该文件为文件系统的File对象fileobj。
2)FileInputStream(String path):
通过打开一个到实际文件的连接来创建一个FileInputStream,该文件的完整路径名为path。
2. FileOutputStream类

FileOutputStream类创建一个可以向文件写入自己饿的类OutputStream,常用的构造方法:

1)FileOutputStream(File file):
创建一个向指定File对象表示的文件中写入数据的文件输出流。
2)FileOutputStream(String name):
创建一个像具有指定名称的文件中写入数据的输入文件流。
3)FileOutputStream(String name,boolean append):
创建一个像具有指定name的文件中写入数据的输出文件流。如果append为true,文件以设置搜索路径模式打开。

实例:创建一个文件,并输出文件内容

public class IOStreamTest {
    public static void main(String[] args) {
        File f = new File("G:/in.txt");
        FileInputStream fin = null;
        FileOutputStream fout = null;
        int a = 0;
        int i = 0;
        String s =" ";
        try {

        /*通过使用FileInputStream访问文件的一个或多个字
          节,或整个文件,为一个文件打开输入流FileInputStream,
          须将文件名或文件对象传送给构造方法*/

            fin = new FileInputStream(f);
            fout =new FileOutputStream("G:/out.txt");
            byte[]  bufferIn = new byte[1];
            /*int read(byte b[],int offset,int len):从offset开始做多可将len个字节的数据读入一个字节数组b中*/
            while((a= fin.read(bufferIn, 0, 1)) != -1){ // 文件内容以-1结束
                //判断输入字符是否为换行符
                if(!"\n".equals(String.valueOf((char)bufferIn[0]))){
                    s += String.valueOf((char)bufferIn[0]); 
                }else{
                    i++;   //记录行
                    //在一行末尾加入数字标识
                    s = i + s + String.valueOf((char)bufferIn[0]); 
                    //将处理后的字符串以字节形式写入out.txt
                    fout.write(s.getBytes());
                    System.out.println(s);
                    s = " ";
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fin.close();
                fout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:
这里写图片描述

示例中在G盘根目录下创建了文件in.txt,通过FileOutputStream类的fout对象将字符串内容写入文件中,然后通过FileInputStream类的fin对象从文件中读取内容并输出。

- 数据字节输入/输出流类

数据字节输入流(DataInputStream)和数据字节输出流(DataOutputStream)提供一些对Java基本数据类型写入的方法,像读写int、double、和boolean等方法。

一般来说对二进制文件使用DataInputStream流和DataOutputStream流。打开和关闭DataInputStream对象时,其方法与FileInputStream相同:

DataInputStream myData;
FileInputStream myFile;
myFile = new FileInputStream("G:/a.txt");
yData = new DataInputStream(myFile);

从DataInputStream流访问文件,可以是使用成员方法read()。也可以使用其他访问方法读取不同种类的数据,如char readChar()、int readInt()、String readLine()等。其中String readLine()成员方法可以用来一次读取一行字符。

- 对象字节输入/输出流类

ObjectInputStream对象输入流配合DataOutputStream对象输出流就可以实现对象的串行化(Serialization)。

对象的寿命通常随着声称该对象的程序终止而终止。对象通过写出描述自己状态的数值来记录自己,这个过程叫做对象的串行化。串行化的目的是为Java的运行环境提供一组特性,其主要任务是写出对象实例变量的数值。

构造对象的输入/输出流:要串行化一个对象,必须与一定的对象输入/输出流联系起来,通过对象的输出流将对象的状态保存下来,再通过输入流将对象状态恢复。在ObjectInputStream中用readObject()方法可以直接读取一个对象,ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。

- 缓冲字节流

缓冲流是一种字节流,通过把内存缓冲区练到输入/输出流而扩展一个过滤流。该缓冲区允许Java对多个字节同时进行输入/输出操作,因此可以减少访问硬盘次数,提高程序的性能和效率。

1. BufferedInputStream缓冲输入流

BufferedInputStream类允许把任何InputStream类封装成缓冲流。如下有两个构造方法:

1)BufferedInputStream(InputStream in): 
生成一种默认缓冲长度的缓冲流,一般缓冲大小为8192个字节。
2) BufferedInputStream(InputStream in,int size): 
创建具有指定缓冲区大小为size的BufferedInputStream。
2. BufferedOutputStream缓冲输出流

用flush()方法确保缓冲区内字节数据被写入实际的输出设备,还使所有缓冲的输出字节被写出到基础输出流中。如下有两个构造方法:

1)BufferedOutputStream(OutputStream out): 
创建一个新的缓冲输出流,已将数据写入指定的基础输出流。
2)BufferedOutputStream(OutputStream out,int size): 
创建一个新的缓冲输出流,已将具有指定缓冲区大小的数据写入指定的基础输出流。

实例:

public class BufferIOStreamEg {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("g:/a.txt");
        BufferedInputStream bin = new BufferedInputStream(in, 256);
        int len;
        byte Array[] = new byte[256];
        len = bin.read(Array);
        for(int i =0; i < len ;i++){
            System.out.print((char)Array[i]);
        }
    }
}

运行结果:
这里写图片描述


3. 字符流类

字符流是以字符为单位来操作的,一般用于处理文本数据

- 字符输入/输出流抽象类
1. Reader类

Reader类是处理所有字符流输入类的抽象父类,该类所有方法在异常情况下都会产生IOException异常。

1)读取字符:

①public void read() throws IOException;
②public void read(char cbuf[]) throws IOException;
③public abstract int read(char cbuf[],int off,int len) throws IOException;

2)标记流:

 ①public boolean markSupported();
 ②public void mark(int readAheadLimit) throws IOException;
 ③public void reset() throws IOException;

3)关闭流:

public abstract void close() throws IOException;

4)标记流中的当前位置:

void mark(int readAheadLimit);

5)跳过字符:

skip(long n)
2. Write类

Write类是处理所有字符流输出类的抽象父类,该类所有方法在异常情况下都会产生IOException异常。

1)向输出流写入字符:

①public void write(int c) throws IOException;
②public void write(char cbuf[]) throws IOException;
③public abstract int write(char cbuf[],int off,int len) throws IOException;
④public void write(String str) throws IOException;
⑤public void write(String str,int off,int len) throws IOException;

2)flush():清空输出流,并输出所有被缓存的字节。

3)关闭流:

 public abstract void close() throws IOException;
- 文件字符输入/输出流类
1. FileReader类

FileReader类创建了一个可以读取文件内容的Reader类

①FileReader(File file)
②FileReader(FileDescriptor fd):FileDescriptor是文件的完整路径
③FileReader(String fileName):fileName是描述该文件的File对象。
2. FileWrite类

FileWrite类创建了一个可以读取文件内容的Write类

①FileWrite(File file)
②FileWrite(String fileName)
③FileWrite(String fileName,boolean append): 
在给出文件名的情况下构造FileWrite对象,若append为true,则输出附加至文件尾。
- 字符输入/输出流类
1. InputStreamReader

InputStreamReader是字节流通向字符流的桥梁。

@Test
    public void test6() {
        FileInputStream in = null;    //文件输入流
        InputStreamReader ir = null; //字符输入流
        BufferedReader r = null;      //字符缓冲流
        try {
            in = new FileInputStream("g:/b.txt");
            ir = new InputStreamReader(in, "utf-8");
            r = new BufferedReader(ir);

            String str = r.readLine();
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
2. OutputStream

InputStreamReader是字符流通向字节流的桥梁。

@Test
    public void test7() {
        FileOutputStream fo = null;
        OutputStreamWriter ow = null;
        BufferedWriter bw = null;

        try {
            fo = new FileOutputStream("g:b.txt");
            ow = new OutputStreamWriter(fo, "utf-8");
            bw = new BufferedWriter(ow);
            bw.write("猎场!");
            bw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
- 字符缓冲流:

字符缓冲流BufferedReader和BufferedWrite可用来缓冲Reader和Write流中字符等数据,从而提供字符、数组和行的高效读取和写入。一般豆浆Reader和Write流打包成BufferedReader和BufferedWrite

public class BufferedReaderEg {

    public static void main(String[] args) throws IOException {
        String bufStr;
        int bufInt;
        //设置输入端为键盘
        BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输入一个整数:");
        bufStr = buf.readLine(); //从键盘上输入数据
        bufInt = Integer.parseInt(bufStr);
        buf.close();
        System.out.println("The Integer is=" + bufInt);
    }
}

运行结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/YOLO97/article/details/81712735