Java拾贝第十一天——IO流之字节流

Java拾贝不建议作为0基础学习,都是本人想到什么写什么

在JavaIO中,流的操作主要有字节流和字符流两大类。

两类都有输入和输出操作。

字节流

字节流主要操作Byte(字节)数据类型。在字节流中:

输出流主要使用OutputStream类,输入流主要使用InputStream类。

OutputStream类定义如下:

public abstract class OutputStream implements Closeable, Flushable

可以发现OutputStream类是一个抽象类。如果想要操作文件,那么需要使用其子类FileOutputStream或FileInputStream。

字节输出流

通过向上转型的方式实例化OutputStream或实例化FileOutputStream自身。

FileOutputStream构造方法如下:

public FileOutputStream(File file) throws FileNotFoundException

传参为File对象,File有参构造方法需指明文件路径。

FileOutputStream类常用方法如下:

方法 类型 描述
public void write(int b) throws IOException 普通方法 将一个字节输出
public void write(byte b[]) throws IOException 普通方法 将一个字节数组输出
public void write(byte b[], int off, int len) throws IOException 普通方法 将一个指定范围的字节数组输出
public void close() throws IOException 普通方法 关闭流

write(int b)

输出一个字节。
栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileOutputStream stream = new FileOutputStream(file);
            stream.write(65);
        } catch (Exception e) {//直接提高异常优先级,因为有多个异常
            e.printStackTrace();
        }
    }

D:\IOtest\text.txt内:

A
//根据ASCII表得到的结果,在表中十进制的65代表A

write(byte b[])

输出一个字节数组。
栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        byte[] bytes = "Hello World!".getBytes();//字符串转为字节数组
        try {
            FileOutputStream stream = new FileOutputStream(file);
            stream.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

D:\IOtest\text.txt内:

Hello World!

write(byte b[], int off, int len)

输出一个指定范围的字节数组。
栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        byte[] bytes = "Hello World!".getBytes();
        try {
            FileOutputStream stream = new FileOutputStream(file);
            stream.write(bytes,0,7);下标 从0开始到7结束(不包含7)
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

D:\IOtest\text.txt内:

Hello W

image

close()和末尾追加

关闭流,上述栗子都没有关闭流。

因为程序在main内就结束了,JVM会自动关闭流,但建议在合适的地方手动关闭流。

输出流默认是覆盖输出的,末尾追加内容需要使用被

FileOutputStream重载的有参构造,传参新增一个布尔值:

public FileOutputStream(String name, boolean append)throws FileNotFoundException

栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        byte[] bytes = "Hello World!".getBytes();
        try {
            FileOutputStream stream = new FileOutputStream(file,true);
            stream.write(bytes);
            stream.write(bytes);//执行两次

            stream.close();//手动关闭流
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

D:\IOtest\text.txt内:

Hello WHello World!Hello World!

换行需要使用转义符

如果我们需要换行进行追加内容的化需要使用转义符\r\n

\r:回车,光标回到本行首位
\n:换行

为什么要两个?
	:在某些系统中两个才能进行换行

至此,修改栗子如下:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        byte[] bytes = "\r\nHello World!".getBytes();//换行符
        try {
            FileOutputStream stream = new FileOutputStream(file,true);
            stream.write(bytes);
            stream.write(bytes);//执行两次

            stream.close();//手动关闭流
        } catch (Exception e) {
            e.printStackTrace();
        }

D:\IOtest\text.txt内:

Hello WHello World!Hello World!
Hello World!
Hello World!

循环输出

栗子:

public class Test11 {
    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        byte[] bytes = "\r\nHello World!".getBytes();
        try {
            FileOutputStream stream = new FileOutputStream(file,true);//追加的形式
            for (int i = 0; i < bytes.length; i++) {
                stream.write(bytes[i]);//调用的方法是write(int b)
            }
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

通过IDEA-Debug的形式运行上述栗子。
image
在字符串转为字节数组时,其实数组内部已经存放与字符串对应的字节数值了。

所以循环内调用的都是write(int b)方法。

以前刚开始接触IO的时候我真的怎么看都看不懂只能死记硬背= =,不建议这种行为真的头大

字节输入流

相应的,有输出肯定有输出。

InputStream类定义如下:

public abstract class InputStream implements Closeable

它也是抽象类,想要操作文件需要使用其子类,FileInputStream构造方法如下:

public FileInputStream(File file) throws FileNotFoundException

FileInputStream常用方法如下:

方法 类型 描述
public int read() throws IOException 普通方法 返回读取的一个字节
public int read(byte b[]) throws IOException 普通方法 将内容读取到字节数组,并返回读入的个数。
public int available() throws IOException 普通方法 返回输入文件的大小
public void close() throws IOException 普通方法 关闭流

read()

返回读取的一个字节。

D:\IOtest\text.txt内:

asdjhjfsdhiasdas123

栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
            int read = stream.read();
            System.out.println(read);
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

97
//查询ASCII表,97对应的a

如果D:\IOtest\text.txt内为空:

-1

读取内容为空返回-1。

read(byte b[])

将内容读取到字节数组,并返回读入的个数。

D:\IOtest\text.txt内:

asdjhjfsdh iasdas123 12312aa$!@#@

栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            int read = stream.read(bytes);
            System.out.println("内容个数"+read);

            String s = new String(bytes);
            System.out.println(s);

            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

内容个数33
asdjhjfsdh iasdas123 12312aa$!@#@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

内容被正确读进字节数组了,但是发现后面好多空格哇!这是因为数组开辟了1024个空间,实际只有33个空间有效,多余了很多空白的空间,该如何避免呢。

available()

返回文件的大小,以字节为单位

至此,修改栗子如下:

      public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
            byte[] bytes = new byte[stream.available()];

            int read = stream.read(bytes);
            System.out.println("内容个数"+read);

            String s = new String(bytes);
            System.out.println(s);

            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

内容个数33
asdjhjfsdh iasdas123 12312aa$!@#@

成功啦!我们避免了空间的浪费!

循环读取

D:\IOtest\text.txt内:

我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?

一次读取一个字节
利用read()读取一个字节为空会返回-1进行循环。
栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
            byte[] bytes = new byte[stream.available()];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = ((byte) stream.read());
            }
            System.out.println(new String(bytes));
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?

一次读取多个字节
利用read(byte b[]),相同的它读取为空也会返回-1。

栗子:

    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            int temp;
            while ( (temp=stream.read(bytes))!=-1 ){
                System.out.println(new String(bytes,0,temp));
            }
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

程序运行结果:

我kjas lkjdlksajask大按实际哦段搜23sjafiijfisahdfo1231 !@#!%TFSDAS
阿斯顿发射点 给!@34125
暗收分撒到 6465465465465?

一次读取1024字节的内容,如果没读取完成继续读取。直至temp=-1。

如果text.txt内容很多就可以体现出这一点。

posted @ 2023-10-25 16:52  rowbed  阅读(2)  评论(0编辑  收藏  举报