Java中IO(一、文件流)

文件流

FileInputStream从文件系统中的文件获取输入字节。哪些文件可用取决于主机环境。
FileInputStream用于读取原始字节流,如图像数据。要读取字符流,请考虑使用FileReader。



一、IO


/*
* 数据结构
*   数据结构是计算机存储和组织不同数据的方式,不同数据结构根据存储的方式、操作以及特性加以区分
*   当前SE基础中接触到有以下几类:
*       数组;有序可重复,查询更改快,添加删除满
*       链表;有序可重复,查询更改满,添加删除快
*       散列表;无序不可重复,存储键值对,key唯一,value不可重复
*       tree;无序不可重复,元素按照某种规则自动排序(Comparable、Comparator)
*   根据需求合理选择数据结构进行数据存储
*
* IO:流是一组有顺序,有起点终点的字节集合,是对数据传输的总称或抽象
*   就是数据之间的传递
*   本质:是数据的传输,根据 不同数据的传输特性,抽象为几类,方便操作数据
*   流中的操作对象是指内存中,当前操作的程序所涉及的数据
*       输入:往内存中导入数据
*       输出:从内存中写出数据
*   I:input O:output
*
* 分类:
*   按照处理数据类型不同:分为字节流和字符流
*   按数据流向不同:分为输入流和输出流(相对于内存而言)
*   按功能分:分为节点流和处理流
*       节点流:直接操作数据源
*       处理流:对其他流进行处理
*
* 四大抽象类
*   InputStream:
*   OutputStream:
*   Reader:
*   Writer:
*
* 文件流
*   原始文件流:用于打开链接,操作数据
*   1 FileInputStream 字节输入
*   2 FileOutputStream 字节输出
*   3 FileReader 字符输入
*   4 FileWriter 字符输出
* */

public class _01_IO_Summary {

    public static void main(String[] args) throws IOException {
        // System.in是标准输入(控制台)
        InputStream in = System.in;
        System.out.println("请输入:");
        int i = in.read();
        // System.out是标准输出(控制台)
        PrintStream out = System.out;
        out.println(i);
    }
}

二、FileInputStream


/*
* java.io.InputStream
*   java.io.FileInputStream; 在原始文件中读取数据
*   首先需要找到文件:1 绝对路径 2 相对路径
* */
public class _02_IO_FileInputStream {

    public static void main(String[] args){
        // 若要在finally中关闭文件流,则需要在try语句块外初始化文件流
        // 因为在try中初始化的话,如果try中出现异常,将不会在执行,那么
        // finally中就有可能找不到文件流对象
        FileInputStream inputStream = null;
        try {
            // 绝对路径
            // FileInputStream inputStream = new FileInputStream("D:\IDEA\JavaSE\SE\src\com\tianl\IO\com\_02_IO_FileInputStream.java");
            // FileInputStream inputStream = new FileInputStream("D:\\IDEA\\JavaSE\\SE\\src\\com\\tianl\\IO\\com\\_02_IO_FileInputStream.java");
            // 相对路径,idea中是相对于module而言,此处module为SE。 ./ 可以省略
            inputStream = new FileInputStream(
                    "./SE/src/com/tianl/IO/_01_FileInputStream/_02_IO_FileInputStream.java");

            // 读取数据
            // 读取一个字节,返回下一个字节的值,开始时光标在顶端如果到达文件末尾,就返回-1
            int i1 = inputStream.read();
            int i2 = inputStream.read();
            System.out.println((char) i1);
            System.out.println((char) i2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 此时还应判断文件流对象是否为空,如果为空,相当于使用null(不存在的对象)去调用close()方法
            // 会报空指针异常,且这里需要用try catch语句块来处理可能抛出的空指针异常
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

// 使用read循环读取
public class _03_IO_FileInputStream {

    public static void main(String[] args) {

        // 自动关闭资源写法
        try (FileInputStream inputStream = new FileInputStream(
                "./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");){

            int temp = 0; // 临时变量
            // 只要不读到文件末尾(inputStream.read()=-1),就输出
            while (((temp=inputStream.read())!=-1)){
                System.out.print((char) temp);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
* read 方法重载
*   可以无参,可以传入一个byte数组
*   read(byte[] b):使用字节数组来存储读取的数据,并一次返回
*       要么数组装满,要么达到文件末尾,可以提高读写速率
*   返回值是本次读取的字节个数,如果达到文件末尾,返回-1
* */
public class _04_IO_FileInputStream {

    public static void main(String[] args) {
        // 自动关闭资源写法
        try (FileInputStream inputStream = new FileInputStream(
                "./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");){

            // 准备数组
            byte[] bytes = new byte[5];
            // 返回本次读取的字节个数
            int i1 = inputStream.read(bytes);
            System.out.println(i1);
            // byte[]转换为String输出
            System.out.println(new String(bytes));

            // 在读取一次
            // 再次使用该数组读取的时候,数组内元素不会被清空,而是用新读取的数据替换原来的
            int i2 = inputStream.read(bytes);
            System.out.println(i2);
            // 转换为String
            // 如果直接把字节数组转换为String,有可能产生冗余数据(上次读取)
            // 为了保证数据不冗余,利用read的返回值(本次读取的字节数)
            // 只把本次读取的直接转换为String即可
            // String参数(字节数组,从哪里开始(包含关系),字节个数)
            System.out.println(new String(bytes,0,i2));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
* 循环读取
* */
public class _05_IO_FileInputStream {

    public static void main(String[] args) {
        // 自动关闭资源
        try (FileInputStream inputStream = new FileInputStream(
                "./SE/src/com/tianl/IO/_01_FileInputStream/_04_IO_FileInputStream.java"
        )){
            // 准备数组
            byte[] bytes = new byte[1024];
            int temp = 0;
            System.out.println(inputStream.available());
            // 按照字节数组大小循环读,每次读取一个字节数组长度
            while ((temp=inputStream.read(bytes))!=-1){
                System.out.println(temp);
                System.out.println(new String(bytes,0,temp));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
* 常用方法
* */
public class _06_IO_FileInputStream {

    public static void main(String[] args) throws IOException {
        // 1 创建流对象
        FileInputStream inputStream = new FileInputStream(
                "./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java");
        // 2 可获得字节数
        System.out.println(inputStream.available());;

        // 3 读取字节数组
        byte[] bytes = new byte[5];
        inputStream.read(bytes);
        System.out.println(new String(bytes));
        System.out.println(inputStream.available());

        // 4 跳过不读
        inputStream.skip(20);
        System.out.println(inputStream.available());
        // 5 读取一个
        System.out.println((char) inputStream.read());
        // 6 关闭资源
        inputStream.close();
    }
}

三、FileReader


/*
* FileRead: 一次读取一个字符(两个字节),而Unicode编码也是两个字节
*   字符串输入流一般用于读取存文本文件,压缩包、图片等还是使用字节流
* read一样有方法重载
*   read(): 读取一个字符,返回下一个字符数据,到达文件末尾返回-1
*   read(char[] c): 读取一个字符数组,到达文件末尾返回-1
* 常用方法和FileInputStream一致
* */
public class _01_FileReader {

    public static void main(String[] args) {
        try (FileReader fileReader = new FileReader(
                "./SE/src/com/tianl/IO/_01_FileInputStream/_03_IO_FileInputStream.java")){

            // 字符数组
            char[] chars = new char[512];
            int temp;
            // 循环读取
            while ((temp=fileReader.read(chars))!=-1){
                System.out.println(temp);
                System.out.println(new String(chars,0,temp));
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

四、FileOutputStream


/*
 * java.io.OutputStream
 *   java.io.FileOutputStream; 将文件中内容写出到硬盘中
 * 输入流,找不到文件会报错。但输出流不会报错,会自动创建该文件
 *   但不会创建文件夹(目录)
 *
 * 构造方法:
 *   FileOutputStream(String): 把内容输出到指定文件中,并覆盖原文件内容
 *   FileOutputStream(String, boolean): 如果第二个参数为true,把内容输出到指定文件中
 *      并在原文件中追加数据
 *
 * 常用成员方法:
 *   void close(): 关闭输出流并释放资源
 *   void flush(): 刷新此输出流并强制写出所有缓冲的输出字节,避免数据遗漏
 *   void write(byte[] b): 将b.length个字节从指定的字节数组写入此输出流
 *      想要输出字符串可以利用字符串的getByte()方法,把字符串转换为字节数组
 *   void write(byte[] b, int off, int len):
 *      将指定直接从偏移量off开始的len个字节写入此输出流
 *   abstract void write(int b): 将指定字节写入此输出流
 * */

public class _01_FileOutputStream {

    public static void main(String[] args) throws IOException {

        // 创建输出流对象,若没有传Boolean值,默认false,会覆盖原文件内容
//        FileOutputStream outputStream = new FileOutputStream(
//                "D:/111.txt"
//        );

        // 追加式写入
        FileOutputStream outputStream = new FileOutputStream(
                "D:/111.txt",true
        );

        for (int i = 0; i < 26; i++) {
            outputStream.write(97+i);
        }

        String str = "Hello World\n";
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        outputStream.write(bytes);

        // 刷缓存
        outputStream.flush();
        // 关闭流
        outputStream.close();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值