java输入输出处理(IO流)

IO流的概念和划分

理解数据流

数据流分为输入流和输出流,输入流只有读不能写,输出流只有写不能读。这里的输入与输出是相对程序而言的,数据流可以从磁盘文件、键盘和网络套接字等输入到程序,然后输出到磁盘文件、控制台和相连的网络。
处理数据流的类主要放在包java.io中,还有一个是java.nio,该包中的类主要解决输入输出过程中的一些复杂的问题。

java流的划分

字节流:处理字节的输入和输出,在顶层有两个抽象类InputStream和OutputStream。其中最重要的两个方法是read()和write(),它们分别用于读写字节。两种方法都在InputStream和OutputStream中被定义为抽象方法,它们被派生的流类重写。
字节流中还有一个流RandomAccessFile,支持随机的存取文件中的内容。
字符流:为处理字符的输入和输出提供了方便。不过在最底层,所有的输入输出都是字节形式的,一个字符一般等于多个字节。在顶层也有两个抽象类Reader和Writer。其中最重要的两个方法是read()和write(),它们分别用于读写字节。两种方法都在InputStream和OutputStream中被定义为抽象方法,它们被派生的流类重写。

文件的操作

File类

在进行文件操作时,需要知道一些关于文件的信息,File类提供了一些方法操纵文件和获取文件的信息。在java中,目录也当作一种文件,是特殊的文件,即文件名单列表。
File类有四个构造方法:
(1)File(String path)
(2)File(String dir,String filename)
(3)File(File dir,String filename)
(4)File(URI uri)
dir是文件所在的目录,filename是文件名,path是文件的路径名。
如:
File f1 = new File(“D:/java”);
File f2 = new File(“D:/java”,”test.txt”);
File f3 = new File(f1,”test.txt”);
File f4 = new File(“file://D:/java/test.txt”);
File类定义了很多获取File对象标准属性的方法。

目录

目录是一个包含其他文件和路径列表的File类。当创建一个File对象且它是目录时,isDirectory方法返回true。这种情况下,可以调用该对象的list方法提取该目录内部其他文件和目录的列表。该方法有两种形式:
(1)String[] list();//文件列表在一个String对象数组中返回
(2)File[] listFiles();//文件列表在一个File对象的数组中返回
有时需要列出目录下指定类型的文件,还可以在上面的方法中加上参数,就形成下面三种带参数的方法了:
(1)String[] list(FilenameFilter FnFobj)
(2)File[] listFiles(FilenameFilter FnFobj)
(3)File[] listFiles(FileFilter FFobj)
FnFobj是一个实现FilenameFilter 接口的类的对象,这个接口里仅有一个方法accept(),当调用list()方法列出文件时,将调用accept方法检查该文件名称是否符合accept方法指定的名字要求。
FFobj是一个实现FileFilter 接口的类的对象,这个接口里仅有一个方法accept()。

字节流处理

InputStream/OutputStream

InputStream定义了java字节流输入模式的抽象类,OutputStream定义了字节流输出模式的抽象类,这两个类中只要有方法出错了就会引发IOException异常。
InputStream类继承了Object类,实现了Closeable接口,该接口定义了一个close方法,可以释放流所占用的资源。
OutputStream类继承了Object类,实现了Closeable接口和Flushable接口,该类的所有方法都会返回一个void值。Flushable接口中定义了一个方法flush,该方法会输出缓冲区中的数据。

标准输入输出流

System.in作为字节输入流类InputStream的对象实现标准输入,通过read方法从键盘接受数据。如:

package chap09;
import java.io.IOException;

public class StdInput
{

    public static void main(String[] args) throws IOException
    {
        System.out.println("intput:");
        byte b[] = new byte[512];
        int count = System.in.read(b);
        System.out.println("Output");
        for (int i=0;i<count;i++)
        {
            System.out.print(b[i] + " ");
        }
        System.out.println();
        for (int i=0;i<count;i++)
        {
            System.out.print((byte)b[i] + " ");//此处应该输出abcd,为何这里的byte不起作用?
        }
        System.out.println("count=" + count);
    }

}

这里写图片描述

System.out作为打印流类PrintStream的对象实现标准输出。定义了print和println方法(会换行),支持java任意基本类型作为参数。后来又增加了支持数据的格式化输出的printf()方法,支持可变参数,即方法的参数个数是可变的。(此处涉及很多转换字符有点不好理解,以后再补充)如:

文件字节流

文件数据流类FileInputStream和FileOutputStream分别是 InputStream和OutputStream抽象类的子类,这些子类实现其父类方法的同时又定义了特有的功能,用于进行文件的输入输出处理,其数据源和接收器都是文件。
FileInputStream用于顺序访问本地文件,继承了read,close等方法,能引发FileNotFoundException异常。read()方法在读取数据时,输入流结束则返回-1。
FileOutputStream用于向一个文本文件写数据,继承了write,close等方法,能引发IOException或SecurityException异常。该类对象的创建不依赖于文件是否存在,如果不存在就在打开之前创建它,如果存在就直接打开,准备写。当试图打开一个只读文件时,会引发一个IOException异常。

过滤流

过滤流在读写数据的同时可以对数据进行处理,提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。这些过滤字节流是FilterInputStream和FilterOutputStream,分别是 InputStream和OutputStream抽象类的子类,过滤流拓展了输入输出流的功能,典型的扩展是缓冲、字符字节转换和数据转换。

BufferedInputStream/BufferedOutputStream

BufferedInputStream是FilterInputStream的子类,允许把任何InputStream类“包装”成缓冲流并使它的性能提高。
BufferedOutputStream是FilterOutputStream的子类,可以调用flush方法输出缓冲区中待定的数据。

DataInputStream/DataOutputStream

也是FilterInputStream和FilterOutputStream的子类,能够直接读写各种各样的java语言的基本数据类型。

随机存取文件

InputStream和OutputStream都是顺序访问流,从头至尾访问流,并且不能对一个文件不能同时进行读写。
RandomAccessFile类提供了一种称为“随机访问文件”方式,直接继承object类,可以
(1).对一个文件同时进行读写操作;
(2).在文件的任意位置进行读写操作。

其他字节流

可以自己查阅API文档。

字符流处理

尽管字节流提供了处理任何类型数据输入输出操作的足够的功能,但它们不能直接操作Unicode字符,提供直接的字符输入输出支持是必要的。

Reader/Writer

Reader和Writer类都是抽象类,而且其中方法出错都会引发IOException异常。其中Writer类的所有方法都返回一个void值。

文件字符流

文件数据流类FileReader和FileWriter分别是 reader和writer抽象类的子类,这些子类实现其父类方法的同时又定义了特有的功能。
FileReader以字符方式读取文件内容,能引发FileNotFoundException异常。
FileOutputStream以字符方式写入文件内容,能引发IOException或SecurityException异常。该类对象的创建不依赖于文件是否存在,如果不存在就在打开之前创建它,如果存在就直接打开,准备写。当试图打开一个只读文件时,会引发一个IOException异常。

字节流向字符流的转化

InputStreamReader和OutputStreamWriter用来在字节和字符之间作为中介,可以从一个字节流构造一个字符流对象,可以在构造这些流对象时指定字符编码规范,也可以用当前平台的默认编码规范。

这里写图片描述

如果使用了不支持的字符集,会引发UnsupportedEncodingException异常。在从字节流构造字符流时,要注意java程序文件用什么样的编码存储,构造函数中就应该指定为哪种编码,否则会乱码。

Scanner及其他字符流

一般地,以Reader结尾的类都是字符输入流,以Writer结尾的类都是字符输出流。
一般地,以Stream结尾的类都是字节流。
PrintWriter向字符(文本)输出流打印对象的格式化表示形式。
Scanner是一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。

串行化

把对象能记录自己的状态以便将来再生的能力,叫做对象的持续性。对象通过写出描述自己状态的数值记录自己的过程,叫做对象的串行化。在java.io包中,定义了一些接口和类作为对象串行化的工具。
串行化的注意事项:
(1)串行化只能保存对象的非静态成员变量,不保存变量的修饰符。
(2)transient关键字。
对于某些类型的变量,其状态是瞬时的,无法或无须保存其状态;对于这些变量,可以用transient关键字标明。
对于一些需要保密的变量,为了保证安全性,不应该串行化,可以在其前面加上transient关键字。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值