欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中的I/O(输入输出流)

程序员文章站 2024-03-23 22:01:46
...

  在变量、数组和对象中存储的数据是暂时存在的,程序结束后他们就会丢失。为了能够永久地保存程序创建的数据,可以将其保存在磁盘文件中,这样就可以再其他程序中使用他们。Java的I/O技术可以将数据保存到文本文件、二进制文件甚至是ZIP压缩文件中,以达到永久性保存数据的要求。

1.流

  流是一组有主的数据序列,根据操作的类型,可分为输入流和输出流两种。I/O(Input/Output,输入/输出)流提供了一条通道程序,可以使用这条通道把源中的字节序列送到目的地。虽然I/O流通常与磁盘文件存取有关,但是程序的源和目的地也可以使键盘、鼠标、内存或显示器窗口等。
  Java由数据流处理输入/输出模式,程序从指向源的输入流中读取源中的数据,源可以使文件、网络、压缩包或其他数据源。
  输出流的志向是数据要到达的目的地,程序通过向输出流中写入数据把信息传递到目的地。输出流的目标可以是文件、网络、压缩包、控制台和其他数据输出目标。

2.输入/输出流

  Java语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在java.io包中。其中,所有输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类;而所有输出流都是抽象类OutputStream(字节输出流)或抽象类Writer(字符输出流)的子类。

2.1 输入流

  InputStream类是字节输入流的抽象类,是所有字节输入流的父类。
  该类中所有方法遇到错误时都会引发IOException异常。其方法有:

方法 功能描述
read() 从输入流中读取数据的下一个字节。返回0~255范围内的int字节值。如果因为已经到达流尾而没有可用的字节,则返回值为-1。
read(byte[] b) 从输入流中读入一定长度的字节,并以整数的形式返回字节数。
mark(int readlimit) 在输入流的大年位置放置一个标记,readlimit参数告知此输入流在标记位置失效前允许读取的字节数。
reset() 将输入指针返回到当前所做的标记处。
skip(long n) 跳过输入流上的n个字节并返回实际跳过的字节数。
markSupported() 如果当前流支持mark()/reset()操作就返回true。
close() 关闭此输入流并释放与该流关联的所有系统资源。

  注意:并不是所有的InputStream类的子类都支持InputStream中定义的所有方法,如skip()、mark()、reset()等方法只对某些子类有用。

  Java中的字符是Unicode编码,是双字节的。InputStream是用来处理字节的,并不适合处理字符文本。Java为自富文本的输入串门提供了一套单独的类Reader,但Reader类并不是InputStream类的替换者,只是在处理字符串时简化了编程。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。Reader类的具体层次结构如图所示:

Java中的I/O(输入输出流)
Reader类的层次结构

  Reader类中的方法与InputStream类中的方法类似。

2.2 输出流

  OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。
  OutputStream类中所有的方法均返回void,在遇到错误时会引发IOException异常。其方法有:

方法 功能描述
write(int b) 将指定的字节写入此输出流
write(byte[] b) 将b个字节从指定的byte数组写入此输出流
write(byte[] b,int off,int len) 将制定byte数组中从偏移量off开始的len个字节写入此输出流
flush() 彻底完成输出并清空缓存区
close 关闭输出流

  Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。Writer类的层次结构如图所示:

Java中的I/O(输入输出流)
Writer类的层次结构

3.文件的输入与输出

  程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭是,这些数据将消失。如果需要将数据永久保存,可使用文件输入输出流与指定的文件建立连接,将需要的数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到文件中。

3.1 File类、

  File类是java.io包中唯一代表磁盘文件本身的对象。File类定义了一些与平台无关的方法来操作文件,可以通过调用File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据类可以将数据写入到文件中,文件也是数据流最常用的数据媒体。

方法 返回值 说明
getName() String 获取文件的名称
canRead() boolean 判断文件是否为可读的
canWrite() boolean 判断文件是否可被写入
exits() boolean 判断文件是否存在
length() long 获取文件的长度(以字节为单位)
getAbsolutePath() String 获取文件的绝对路径
getParent() String 获取问价你的父路径
isFile() boolean 判断文件是否存在
isDirectory() boolean 判断文件是否为一个目录
isHidden() boolean 判断文件是否为隐藏文件
lastModified() long 获取文件最后修改时间
3.2 文件的输入输出流
FileInputStream与FileOutputStream类

  FileInputStream与FileOutputStream类都用来操作磁盘文件。如过读取需求比较简单,则可以使用FileInputStream类,该类继承自InputStream类。FileOutputStream类与之对应。

FileReader与FileWriter类

  使用FileOutputStream类想文件中写入数据与使用FileInputStream类从文件中将内容读取出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉子在文件中占用两个字节,如果使用字节流,读取不好可能会出现乱码现象,此时采用字符流Reader或Writer类就可以避免。
  FileReader和FileWriter字符流对应了FileInputStream和FileOutputStream类。FileReader流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取源中其余的内容,直到源的末位或流被关闭。
  FileReader和FileWriter字符流的应用实例:

public class FileDemo {
    public void FileReader(){
        File file = new File("F:\\io\\io.txt");
        //字符流读取文件信息
        try {
            char[] charArray = new char[1024];
            //创建一个char数组,用于读取打印文本信息

            FileReader fr = new FileReader(file);
            int length = fr.read(charArray);

            for(int i = 0 ; i < length ; i++){
                System.out.print(charArray[i]);
            }
            fr.close();//关闭流

        } catch (FileNotFoundException e) {
            System.out.println("文件没有找到" + e);
        } catch (IOException e) {
            System.out.println("文件读取失败" + e);
        }
    }

    public void FileWriter(){
        File file = new File("F:\\io\\io_1.txt");

        try {
            FileWriter fw = new FileWriter(file,true);
            String s = "生产快乐的地方!";

            fw.write(s, 0, s.length());//将字符串写入文件
            fw.close();

        } catch (IOException e) {
            System.out.println("文件写入异常" + e);
        }
    }

    public static void main(String[] args) {
        FileDemo fd = new FileDemo();
        fd.FileReader();
        fd.FileWriter();
    }
}
BufferedInputStream与BufferedOutputStream类

  缓存是I/O的一种性能优化。缓存流尾I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()、mark()、reset()方法都成为可能。
  BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。

BufferedReader与BufferedWriter类

  BufferedReader与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。

public class FileDemo {
    /**
     *带缓存的输入/输出流
     */
    public void BufferedRW(){
        File file = new File("F:io\\io.txt");
        File fileW = new File("F:\\io\\io_2.txt");
        try {
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            //读取文件并使其存入缓存区

            FileWriter fw = new FileWriter(fileW);
            BufferedWriter bw = new BufferedWriter(fw); 
            //缓冲流

            String info = br.readLine();
            //用来接收缓冲流读取的字符串
            while(info != null){

                bw.write(info);
                //写入信息
                bw.newLine();
                info = br.readLine();
                //换行继续读取信息
            }
            br.close();
            bw.close();
            //输入/输出流关闭

        } catch (FileNotFoundException e) {
            System.out.println("文件没有找到" + e);
        } catch (IOException e) {
            System.out.println("文件读写失败" + e);
        }
    }

    /**
     *有2个文本文件x和y,
     *将x文件中的信息和y中的信息全部写入z文件中,
     *并且y中的信息在x的后面
     */
    public void fileXYZ(){
        File fileX = new File("F:\\io\\io.txt");
        File fileY = new File("F:\\io\\io_1.txt");
        File fileZ = new File("F:\\io\\io_Z.txt");
        try {
            FileReader frX = new FileReader(fileX);
            BufferedReader brX = new BufferedReader(frX);
            //读取x文件中的信息

            FileReader frY = new FileReader(fileY);
            BufferedReader brY = new BufferedReader(frY);
            //读取y文件中的信息

            FileWriter fw = new FileWriter(fileZ);
            BufferedWriter bw = new BufferedWriter(fw); 
            //创建z文件的缓冲流

            String infoX = brX.readLine();
            String infoY = brY.readLine();
            while(infoX != null){
                bw.write(infoX);
                bw.newLine();
                infoX = brX.readLine();
            }//读取并写入x文件中信息

            while(infoY != null){
                bw.write(infoY);
                bw.newLine();
                infoY = brY.readLine();
            }//读取并写入y文件中信息

            brX.close();
            brY.close();
            bw.close();
            //关闭流

        } catch (FileNotFoundException e) {
            System.out.println("文件没有找到" + e);
        } catch (IOException e) {
            System.out.println("文件读写失败" + e);
        }
    }

    public static void main(String[] args) {
        FileDemo fd = new FileDemo();
        fd.BufferedRW();
        fd.fileXYZ();
    }
}