zoukankan      html  css  js  c++  java
  • JAVA I/O系统

    概述

    对于使用过java提供了I/O来说的程序员来说,可能对其提供的api又爱又恨,爱的是java本身封装了很多功能强大的输入输出流给开发者使用,恨的是一开始开发者可能会对Java I/O系统提供了如此多的类而不知所措。本文就简要的介绍一下java的i/o,以供自己复习使用。

    特殊的File 类

    File类是在java I/O中常用的一个工具类,它可以帮助我们处理文件和文件目录的问题。其实File这个名字有一定的误导性,它既可以表示文件,又可以表示目录。如果其表示的是一个目录,我们就可以调用list()方法来返回文件集合的名称数组或者调用listFile()方法来返回所有的文件。File类还提供了一些常用的属性,比如File.separator表示获取所在系统的路径分隔符、File.pathSeparator表示路径之间的分隔符。但是需要注意的是:File类是针对文件或者目录的相关操作,例如删除、创建、判断文件或者目录是否存在等,但是只通过File类无法访问文件的具体内容,既只通过File既不能从文件中读取数据,也不能写入数据。这里只列出一个使用File类的demo,是有一次面试的面试题,列出指定目录下所有的内容。代码如下:

    package com.vino.nio;
    
    import java.io.File;
    
    public class FileDemo {
    
        public static void main(String[] args) {
            String fileName = "D:" + File.separator;
            File file = new File(fileName);
            printAllFile(file);
        }
    
        // 打印一个文件下所有的文件,包括目录下的文件
        public static void printAllFile(File file) {
            if (file != null) {
                if (file.isDirectory()) {
                    File[] fileArray = file.listFiles();
                    if (fileArray != null) {
                        for (int i = 0; i < fileArray.length; i++) {
                            printAllFile(fileArray[i]);
                        }
                    }
                } else {
                    System.out.println(file);
                }
            }
        }
    }

    正菜开始

    Java类库的I/O类分为输入和输出两部分。通过继承,任何自InputStream或Reader派生而来的类都含有read()这个基本方法,用于读取单个字节或者字节数组。同样,任何自OutputStream或Writer派生儿来的类都含有名为write()的基本方法,用于写单个字节或者字节数组。通常,我们很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所提供的功能。

    四种抽象类见下图所示:

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

    这里先介绍常用的文件流:

    文件流是指那些主要用于从文件操作数据源中的流,主要有4种,分别如下所示:

    FileInputStream vs FileOutputStream vs FileReader vs FileWriter

    FileInputStream:

    • fis.read() 从此输入流中读取一个数据字节。返回:下一个数据字节;如果已到达文件末尾,则返回 -1。 ;
    • fis.read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。返回读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。 

    Tips:在Unicode编码中,一个英文字符是用一个字节编码的,一个中文字符是2个字节编码的。所以用字节流读取中文时,肯定会出问题。
    FileOutputStream:

    常用的初始化该类的方式如下:

    • OutputStream ops = new FileOutputStream(File f);
    • OutputStream ops = new FileOutputStream(File f, boolean append);

    第二种表示是否是追加写。默认情况下,是不追加写的。

    byte[] b = str.getBytes();

    • fos.write(b)  向此输出流中写入b.lenth个字节。
    • fos.write(b[i]) 向此输出流中写入b[i],两者都返回void。

    用字节文件输出流往文件中写入的中文字符没有乱码,因为程序先把中文字符转成了字节数组然后再往文件里面写。 另外,向输出流写入数据,还需要在写入操作完成后,调用flush()方法来强制写出所有缓冲的数据。调用close()的时候会调用flush()方法,所以调用close()的时候就相当于调用了flush()方法。

    FileReader:

    • fr.read(); // 读取单个字符。返回作为整数读取的字符,如果已达到流末尾,则返回 -1。
    • fr.read(char[] c);//将字符读入数组。返回读取的字符数。如果已经到达尾部,则返回-1。

    FileWriter:

    同理与FileOutputStream,只是处理的对象是字符流。这里可以直接输入字符串,而不需要你将字符串转化为字节数组。

    Writer out =new FileWriter(f);
    String str="hello";
    out.write(str);
    out.close();

    Tips:一般来说:FileInputStream vs FileOutputStream类用来操作二进制文件比较合适,如图片,声音,视频等。而FileReader vs FileWriter类用来操作文本比较合适。

    转换流:

    整个IO类中除了字节流和字符流还包括字节和字符转换流。
    OutputStreramWriter将输出的字符流转化为字节流
    InputStreamReader将输入的字节流转换为字符流
    但是不管如何操作,最后都是以字节的形式保存在文件中的。

    缓存流:

    缓冲流都是过滤流,就是说缓冲流并不直接操作数据源,而是对直接操作数据源的节点流的一个包装。当使用过滤流的过程中,当关闭过滤流,它会自动关闭它所包装的节点流。常见的缓存流有BufferedReader。

    BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流。常见的用法如下:

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

    Scanner:

    还有一个不得不提到的类是:Scanner。

    其实在Java里头,我们比较常用的是采用Scanner类来进行数据的输入。具体的用法见下:

    package com.vino.nio;
    
    import java.util.Scanner;
    
    public class ScannerDemo {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            // 读一个整数
            int temp = sc.nextInt();
            System.out.println(temp);
            // 读取浮点数
            float flo = sc.nextFloat();
            System.out.println(flo);
            // 读取字符
            // ...等等的,都是一些太基础的,就不师范了。
        }
    }

     总结:

    本文只是对java i/o的一个简单的总结,涉及到的主要是4中常用的文件流、转换流、缓存流的用法,对于流的高级的用法没有涉及到,博主在日常的开发过程中也没有使用到。另外还要指出的是,本文没有涉及到java的nio,在以后会补充上来。

    参考:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 

  • 相关阅读:
    数组
    js--函数
    for循环
    运算符
    js 正则表达式
    js DOM节点
    js 字符串
    js 函数
    2018-12-26 课堂笔记 for循环
    2018-12-25 课堂笔记 js
  • 原文地址:https://www.cnblogs.com/babybluevino/p/3766302.html
Copyright © 2011-2022 走看看