Java中的流

***字节流

一、I/O流

1.概述:输入/输出流(Input/Output)
2.流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输成为流
流的本质是数据传输。
3.IO流是用来处理设备之间的数据传输问题的
常见应用:文件复制、文件上传、文件下载。
4.IO流分类:
①数据流向分类:
输入流:读数据
输出流:写数据
②按照数据类型分类:
字节流:字节输入流、字节输出流
字符流:字节输入流、字节输出流
一般情况下IO流的分类是按照数据类型来分的。
读的懂的:用字符流
读不懂的:用字节流
如果不知道使用哪种类型的流,就使用字节流。

**二、字节流写数据

1.InputStream:抽象类,表示字节输入流的所有类的超类。
OutputStream:抽象类,表示字节出流的所有类的超类。
子类名特点:父类名作为后缀
2.需要以上父类的子类来实例化,并使用
选择一个:FileInputStream\FileOutputStream
3.使用字节输出流写数据步骤
①创建字节流对象(其实这个过程做了三件事:一是创建了字节输出流对象;二是调用系统方法创建了文件;三是让创建的字节输出流对象指向了创建的文件。
②调用字节输出流的写数据方法
③释放资源(关闭此文件输出流并且释放与此流相关的任何系统资源)
4.创建字节输出流对象的构造方法:
* FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(FileDescriptor fdObj) 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
* FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。
* FileOutputStream(String name, boolean append)创建文件输出流以指定的名称写入文件。

package com.zx.ZiJieLiu;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 创建字节输出流对象的构造方法:
 *      FileOutputStream(File file)
     * 创建文件输出流以写入由指定的 File对象表示的文件。
     * FileOutputStream(File file, boolean append)
     * 创建文件输出流以写入由指定的 File对象表示的文件。
     * FileOutputStream(FileDescriptor fdObj)
     * 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
     * FileOutputStream(String name)
     * 创建文件输出流以指定的名称写入文件。
     * FileOutputStream(String name, boolean append)
     * 创建文件输出流以指定的名称写入文件。
 *
 * FileOutputStream:文件输出流用于将数据写入File
 *      FileOutPutStream(String name):创建文件输出流以指定的名称写入文件
 */
public class FileOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //创建字节输出流(直接执行这句话,在本模块路径下就会创建fos.txt文件)
        FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
        /**
        *创建字节输出流做了三件事情:
        *    1.调用系统功能,创建文件
        *    2.创建了字节输出流对象
        *    3.让字节输出流对象指向了创建好的文件
         *    */
        //写数据方法
        /**
         * void write( int b)将指定的字节写入此文件输出流。
         */
        fos.write(89);//会进行转换成字符Y
        fos.write(57);//字符9
        fos.write(55);//字符7

        //所有和IO相关的操作都要释放资源
        //close()关闭此文件输出流并释放与此流相关联的任何系统资源。
        fos.close();
    }
}

5.字节输出流写数据的三个方法:
①void write(byte[] b)将 b.length个字节从指定的字节数组写入此文件输出流。
②void write(byte[] b, int off, int len)将 len字节从位于偏移量(索引)off的指定字节数组写入此文件输出流。
③void write(int b) 将指定的字节写入此文件输出流。

package com.zx.ZiJieLiu;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 创建字节输出流对象的构造方法:
     * FileOutputStream(File file)
     * 创建文件输出流以写入由指定的 File对象表示的文件。
     * FileOutputStream(File file, boolean append)
     * 创建文件输出流以写入由指定的 File对象表示的文件。
     * FileOutputStream(FileDescriptor fdObj)
     * 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
     * FileOutputStream(String name)
     * 创建文件输出流以指定的名称写入文件。
     * FileOutputStream(String name, boolean append)
     * 创建文件输出流以指定的名称写入文件。
 * 字节输出流写入数据的三种方法:
     * void write(int b):将指定字节写入字节输出流
     * void write(byte[] b):将制定字节数组写入字节输出流
     * void write(byte[] b,int offer,int len):将指定字节数组b从位于偏移量off开始len长度的字节写入输出流。
 */
public class FileOutPUtStreamDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建字节输出流对象(①调用系统方法创建文件②创建字节输出流对象③将创建的字节输出流对象指向了创建的文件)
        //对比构造方法FileOutputStream(File file)和FileOutputStream(String name)
        //FileOutputStream(File file)
//        File f = new File("MyFile\\fos.txt");
//        FileOutputStream fos = new FileOutputStream(f);
        FileOutputStream fos = new FileOutputStream(new File("MyFile\\fos.txt"));
        //FileOutputStream(String name),点击查看源码,其实这个方法做的事情和上面传File的构造方法一样
//        FileOutputStream fos1 = new FileOutputStream("MyFile\\fos.txt");

        //2.写数据
        //①void write(int b)
        fos.write(89);
        //②void write(byte[] b)
        byte[] b = {97,98,99,100};//对应字符abcde
            //补充:String中的getBytes()方法可以简单生成
        byte[] bytes = "asadsd".getBytes();
        fos.write(b);
        fos.write(bytes);
        //③void write(byte[] b,int off,int len)
        byte[] bytes1 = "fhdjshfksd".getBytes();
        fos.write(bytes1,0,bytes1.length);
        fos.write(bytes1,0,4);

        //3.关闭流
        fos.close();

    }
}

6.每次用3中步骤写数据,每次执行,都会重新写入数据,写入数据时是连续的,而且前一次执行写入的数据自动消失了
①那么,如何实现字节流写数据的换行?
②如何实现字节流写数据的追加写入?
③请看FileOutputStreamDemo03------

package com.zx.ZiJieLiu;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 两个问题:
 *      1.如何实现写入字节流写入数据换行?
 *        换行符号在不同操作系统下不一样:
 *          基于 Unix 的系统使用 \n作为行结束字符,
 *          基于 Windows 的系统使用 \r\n作为行结束字符,
 *          基于 Mac 的系统使用\r作为行结束字符。
 *      2.字节流写入数据如何实现追加写入?
 *          在创建对象的时候告诉计算机要追加写入
 *          构造方法:FileOutputStream(String name, boolean append)
 *          创建文件输出流以指定的名称写入文件。
 *
 */
public class FileOutPutStreamDemo03 {
    public static void main(String[] args) throws IOException {
        //1.创建字节输出流对象
//        FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
        FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt",true);
        //2.写数据(实现换行)
        for (int i = 0;i<5;i++){
            fos.write("zx".getBytes());
            fos.write("\r".getBytes());
        }
        //3.释放资源
        fos.close();
    }
}

①实现字节流写数据的换行:添加一个字节,就添加一个换行符
fos.write("fdsfs".getBytes());
fos.write("\n".getBytes());
注意:不同操作系统识别换行字符不一样
②实现字节流写数据的追加写入
在创建字节输出流对象的时告诉计算机我要追加写入,用构造方法FileOutputStream(String name,boolean append);

7.字节流写数据加异常处理,finally语句块,保证close语句一定执行。

package com.zx.ZiJieLiu;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 字节输出流加异常处理
 */
public class FileOutputStreamDemo04 {
    public static void main(String[] args) {
        //创建一个字节输出流对象

        //如果加try_catch语句块捕获异常,那么不能保证fos.close()方法一定会执行,所以引进一个finally
//        try {
//            FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
//            fos.write("qzz".getBytes());
//            fos.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        FileOutputStream fos = null;
        try {
//            fos = new FileOutputStream("fos.txt");//模块同级目录下创建
            //②
            fos = new FileOutputStream("z:\\fos.txt");
            fos.write("qzz".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //如②我的文件根本找不到路径,会报两个错
            // java.io.FileNotFoundException: z:\fos.txt (系统找不到指定的路径。)
            // java.lang.NullPointerException
            //所以为了增强程序的健壮性,在这里进行一个判断,如果fos是空对象,不必关闭
            if (fos != null) {
                try {
                    fos.close();

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

    }
}

三、字节流输入流读数据

1.字节输入流:将硬盘文件中的数据,读取到内存中使用。
FileInputStream继承自InputStream
2.读数据步骤:
①创建FileInputStream对象:利用FileInputStream的构造方法创建字节输入流对象。
(构造方法会做两件事情:①创建字节输入流对象②将字节输入流对象指向要读取的文件)
(注意:构造方法中传入的文件需要时已经存在的文件,否则会报FileNoFoundException错误)
②读数据:调用FileInputStream对象的读取数据的方法。
③释放资源。
3.创建FileInputStream对象的构造方法(主要学会第一个和第三个):
* FileInputStream(File file)
* 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
* FileInputStream(FileDescriptor fdObj)
* 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
* FileInputStream(String name)
* 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

4.读数据:
* int read()
* 从该输入流读取一个字节的数据。
* int read(byte[] b)
* 从该输入流读取最多 b.length个字节的数据为字节数组。(注意是最多,所以返回值是读取的数据长度,而不是数组定义的长度)
* int read(byte[] b, int off, int len)
* 从该输入流读取最多 len字节的数据为字节数组。

package com.zx.ZiJieLiu;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * 将fos文件中的内容读取出来并在控制台输出
 *
 * 使用字节输入流写数据的步骤:
 *      1.创建字节输入流对象
 *      2.使用字节输入流读数据的方法
 *      3.释放资源
 *
 * 创建字节输入流对象的构造方法:
     * FileInputStream(File file)
     * 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
     * FileInputStream(FileDescriptor fdObj)
     * 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
     * FileInputStream(String name)
     * 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
 * 字节输入流读数据的方法:
     * int read()
     * 从该输入流读取一个字节的数据。
     * int read(byte[] b)
     * 从该输入流读取最多 b.length个字节的数据为字节数组。(注意是最多,所以返回值是读取的数据长度,而不是数组定义的长度)
     * int read(byte[] b, int off, int len)
     * 从该输入流读取最多 len字节的数据为字节数组。
 * */
public class FileInputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //1.创建字节输入流的对象
        /**
         *会做两件事情:
         *    ①创建一个FileInputStream对象
         *    ②会将一个FileInputStream对象指向构造方法中要指向的文件
         *注意:构造方法中的文件是已经存在的,否则会报java.io.FileNotFoundException异常
         */
        FileInputStream fis = new FileInputStream("MyFile\\fos.txt");
        //fos.txt文件中内容是abcd (最后还有一个空格)
        /**
         * 2-1读取数据_read()方法
         *   使用FileInputStream对象中的int read()方法
         *   一次读取一个字节,读取文件中的一个字节并返回,读取到文件末尾返回-1
         */
        /*//第一次读取
        int read = fis.read();
        System.out.println(read);//输出97 对应的读取到的字符是a
        //第二次读取
        read = fis.read();
        System.out.println(read);//输出98,对应读取到的数据是b
        //第三次读取
        read = fis.read();
        System.out.println(read);//输出99,对应读取到的数据是c
        //第四次读取
        read = fis.read();
        System.out.println(read);//输出100,对应读取到的数据是d
        //第五次读取
        read = fis.read();
        System.out.println(read);//输出13,对应读取到的是空格
        //第六次读取
        read = fis.read();
        System.out.println(read);//输出-1,已经读取到末尾*/

        /**
         * 2-1-优 read(),一个字节一个字节读取数据的优化
         *  循环读取
         *  由2-1得到思路:
         *      只要(read=fis.read())!=-1,那么可以一直读取
         */
        int len = 0;//记录读取到的字节,上上面read代表的含义一样
        while ((len = fis.read())!=-1){
            System.out.println(len);
        }
        fis.close();

    }
}

5.读数据原理:Java程序—jvm—OS—OS读取数据的方法—读取文件

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值