栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的I/O流详解+总结(同时适合初学者自学和有一定基础的同学复习)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的I/O流详解+总结(同时适合初学者自学和有一定基础的同学复习)

字节输入输出流

File

  • 用file类对象可以获得文件的地址,目录,文件的长度,读写权限等,但是不能直接对文件进行读写.
  • 使用File类并不会创建文件,可以将File类对象理解为文件的一个小名,总不能在程序中每次用到这个文件的时候都把绝对地址输入进去吧.
  • 初始化:

        三种初始化方式:

        File file = new File("writed.txt");//文件与当前程序在同一目录中
        File f = new File("D:\java的练习\IO流","file2.txt");
        File file1 = new File(file,"writed.txt");


FileInputStream

FileInputStream可以用来读取文件,如果只是简单读取文件,可以使用FileInputStream类,这里说的简单指的是:首先,文件大小应该尽量小些,因为FileInputstream读取文件是比较慢的,所以,如果文件很大的话读取文件要耗费很长时间.其次,读出的内容尽量不含中文,或者读取的内容不需要直接输出显示.因为Unicode对中文的编码是三个字节,所以如果是中文的话,直接输出会一个字节一个字节输出,就可能会乱码.但是将文件里的内容写入另一个文件的话,底层操作会自动将这三个字节组成一个汉字(因为汉字在存储的时候,无论选择哪种编码存储,每一个字节都是负数),这样写入文件中的内容就不会是乱码.

  • FileInputStream类是InputStream类的子类,实例方法都是从InputStream类继承来的.InputStream类是虚类不能直接使用.
  • FileInputStream类用来读取文件,且是以字节为单位读取文件
  • FileInputStream类的两个构造方法:

       FileInputStream(String name)//参数是文件名eg:"a.txt"

       FileInputStream(File file)//参数是文件类的对象,就是上面讲File初始化时构造的file,f,file2.

        (下面这两种初始化方法也可以)

FileInputStream fileInputStream = new FileInputStream(new File("new.txt"));
        FileInputStream fis = new FileInputStream("file2.txt");
  • FileInputStream会顺序的读取文件,每次调用read方法都会顺序地读取剩下的内容,直至文件末尾,或者流关闭

使用FileInputStream读取文件的方法

这是API里规定的read方法:

read()方法返回的是读取到的字节内容,read(byte[]b)是将读取到的内容存储到b数组里.i它返回的实际上是读取到的字节数,而不是读取到的内容.

下面这段代码演示了如何用File和FileInputStream读取文件

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

public class InputStream_ {
    public static void main(String[] args) {
        int n = -1;//默认n是文件结尾,这样读出来的任何字节都可以保证是从文件里读取出来的
        byte []a = new byte[50];//将从文件中读取的一百个字节放入a数组中
        File file = new File("new.txt");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);//创建文件fIle的输入流
            if((n=fileInputStream.read(a,0,50))!=-1){
                String s = new String(a,0,n);//将读取到的字符数组转换成字符串
                //String(byte[] bytes, int offset, int length)
                //通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。
                System.out.println(s);
            }
        } catch (IOException e) {
            System.out.println("出错");
        }
    }
}

总结下来,如果想要用字节流读取一个文件,首先要实例化一个FileInputStream类对象,和一个用来存储读取出的内容的字节数组.读取后将该字节数组中的内容转化成字符串.


FileOutputStream

如果只是简单的向文件中写入内容,可以用FileOutputStream.

  • FileOutputStream类是OutputStream类的子类,实例方法都是从OutputStream类继承来的
  • FileOutputStream类用来向文件里写内容,以字节为单位
  • FileOutputStream类的两个构造方法:

       FileOutputStream(String name)//参数是文件名eg:"a.txt"

       FileOutputStream(File file)//参数是文件类的对象


(看到这儿是不是感觉和FileInputStream大差不差?那么下面就是和FileInputStream不一样的地方了)


  • 在使用FileOutputStream的上述两个构造方法时,如果输出流指向的文件不存在,Java就会自动创建该文件,如果指向的是已存在的文件,输出流就会将文件清空,也就是说文件的长度会变为零.(是不是听起来很离谱?难道就不能将一个文件不清空,同时还能向文件里写东西吗?当然可以!因为还有两种构造方法)
  • FileOutputStream的另外两个构造方法

                FileOutputStream(String name,Boolean append);

                FileOutputStream(File file,Boolean append);

     如果append取值为true,输出流不会刷新所指向的文件,将从文件结尾接着写入.FileInputStream会顺序的向文件中写入内容,每次调用write方法都会顺序地在文件尾写入内容,直至流关闭

        如果append取值为false,输出流会刷新所指向的文件.

下面这个例子演示了如何用FileOutputStream基本的向一个文件写入内容

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

public class OutputStream {
    public static void main(String[] args) {
        File file = new File("new.txt");
        byte []a = "helloworld".getBytes();//将字符串转换成字节数组
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);//创建file的输出流
            System.out.println(file.getName()+"的大小: "+file.length());
            fileOutputStream.write(a);//将a写入文件,且无论之前的文件中有什么内容都将被刷新
            fileOutputStream.close();//关闭输出流,主动使用close方法可以保证操作系统把缓冲区的内容放到磁盘上
            System.out.println(file.getName()+"的大小: "+file.length());
            fileOutputStream = new FileOutputStream(file,true);//向文件尾添加内容
            fileOutputStream.write(a);//将a写入到文件尾
            fileOutputStream.close();
            System.out.println(file.getName()+"的大小: "+file.length());//查看是否写入成功
        } catch (IOException e) {
            System.out.println("错误");
        }
    }
}

附上运行结果


FileInputStream+FileOutputStream

用FileInputStream+FileOutputStream将一个文件中的内容写入到另一个文件中

可以当作练习,看看自己有没有掌握FileInputStreamh和FileOutputStream

import java.io.*;

public class Test {
    public static void main(String[] args) {
        File in = new File("new.txt");
        File out = new File("writed.txt");
        byte [] a = new byte[20];
        int n = -1;
        try {
            FileInputStream fileInputStream = new FileInputStream(in);
            FileOutputStream fileOutputStream = new FileOutputStream(out,true);
            System.out.println(in.getName()+in.length());//查看原始in所指文件长度
            System.out.println(out.getName()+out.length());//查看原始out所指文件长度
            if((n = fileInputStream.read())!=-1){
                fileInputStream.read(a,0,20);
            }
            fileOutputStream.write(a);
            System.out.println(out.getName()+out.length());//查看写入内容后的out所指文件长度

        } catch (IOException e) {
            System.out.println("错误");
        }
    }
}

附上运行结果,从运行结果上可以看出,代码是对的

           

(学不会揍你是我之前的CSDN名)


字节流注意事项:

        (1)字节流在读取内容的时候会读入每行最后的换行符"rn"(以windows系统举例),比如说,如果想要读取的文件的内容是12345,然后用一个七个字节的数组取读取的话,读取到的内容就是"12345rn"

        (2)使用字节流写入内容时,如果需要换行,要自行添加.不同系统中的换行方式不同:

        windows:"rn"        mac:"r"        Linux:"n"

        (3)就着(1)来看,因为我的系统是windows的,所以换行符是"rn",有没有注意到有一行只输出了8,而不是8or?这是因为在读取完第一行末尾的low后,下一次读取的内容正好是"rn8",又因为用的是println输出,所以在输出完8之后就自动换行了.由这个例子可以看出,在用字节流读取文件的时候会将换行符读入,所以如果想要输出的话,println会破坏原有的文档格式,那么如果我们输出时想要保留文档的格式的话,就用print输出就行.

 下面这个运行结果就是用print输出的,保留了原来文档的格式


字节缓冲流

先提出两个我之前在学习缓冲流的时候不理解的两个问题

(1)为什么要使用字节缓冲流?

使用字节缓冲流可以提高程序运行效率.因为字节缓冲流的源是字节流,而频繁调用字节流会导致程序运行起来很慢,所以可以使用缓冲区,将读取的数据暂时放进缓冲区,然后再从缓冲区将数据读取出来.

(2)为什么字节缓冲流的源是字节流?/为什么构造方法需要的是字节流而不是具体的文件?

因为字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作.

字节缓冲流:

  • BufferOutputStream:该类实现缓冲输出流,通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为每次写入的每个字节导致底层系统的调用
  • BufferInputStream:创建BufferInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

构造方法:

  • BufferOutputStream(OutputStream out);
  • BufferInputStream(InputStream in);

码字不易,看到这儿不点个赞不合适吧?(给可怜还容易emo的我一点鼓励和支持吧~)


字符输入输出流

        正如前面字节流里提到的,在含有中文的文件中,使用字节流读取不是很方便,所以我们需要学习如何使用字符流.字符流=字节流+编码表(ps:字符流也是有限制的,它只能赋值文本数据)

文件字符输入输出流

  • FileReader(String filename);        FileReader(File file);
  • FileWriter(String filename);          FileWriter(File file);

        FileWriter(String filename,boolean append);        

        FileWriter(File file,boolean append);

字符缓冲流

BufferedReader(Reader in);

BufferedWriter(Writer out);

字符缓冲流的特有功能

BufferedWriter:

        void newline():写一行行分隔符,行分隔符字符串由系统属性定义

BufferedReader:

        public String readLine():读一行文字,结果包含行的内容的字符串,不包括任何终止字符,如果到达了流的结尾,会返回null.

下面这个例子是用字符缓冲流将new.txt里的内容读取到file2.txt中

import java.io.*;

public class Test {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("new.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("file2.txt"));
        int ch;
        while ((ch = br.read())!=-1){
            bw.write(ch);
        }
        bw.close();
        br.close();
    }
}


总结(学习心得体会)

字节流和字符流都有各自的优缺点

字节流:优点是可以读取文档,图片,视频,音频.缺点是读取速度较慢,而且对于要读取之后立即输出的中文来说不太友好.

字符流:优点是读取速度快,缺点是只能读取文档文件,甚至word都不可以读取.

体会抽象类的好处:读取都是read(),写入都是write().

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/571833.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号