java基础-I/O流

知识点

  1. I/O流的基本知识
  2. I/O流中常用流的关系
  3. I/O流之FileInputSrteam,FileOutputStream
  4. I/O流之FileReader,FileWriter
  5. I/O流之InputStreamReader,OutputStreamWriter
  6. I/O流之BufferedReader,BufferedWriter
  7. I/O流之DataOutputStream,DataInputStream
  8. I/O流之ObjectOutputStream,ObjectInputStream

一、I/O流的基本知识

1.1 java中的流是对于内存而言的,分为: 输入流,输出流

  • 输入流:将数据从磁盘读取到内存中的为输入流
  • 输出流:将数据从内存中写入到磁盘中的位输出流

1.2 而根据流的读取方式又可以分为:字节流,字符流

  • 字节流
    定义:字节流是按照字节的方式读取数据
    作用:字节流适合读取视频,音乐,图片等二进制文件
    特点:java语言中所有的字节流都以stream结尾

  • 字符流
    定义:字符流是按照字符的方式读取数据,也就是一次读取2个字节,java中一个字符占2个字节
    作用:字符流适合读纯文本文件(不包括文件格式)
    特点:java语言中所有的字符流都以Reader/Writer结尾

二、I/O流中常用流的关系

2.1 常用流主要由如下类:

FileInputStream
FileOutInputStream

FileReade
FileWriter

BufferedInputStream
BufferedOutStream

BufferedReader
BufferedWriter

DateInputStream
DateOutputStream

ObjectInputStream
ObjectOutputStream

InputStreamReader
OutStreamWriter

PrintWriter
PrintStream

2.2常用类的继承关系:
字节流:

字节流.png

字符流:


字符流.png

三、I/O流之FileInputSrteam,FileOutputStream

3.1 FileInputSrteam

FileInputSrteam的构造方法:

//参数为 文件地址
FileInputStream(String name)

FileInputSrteam的常用方法:

//从输入流中读取一个字节,范围数据为读取到的字节数,若读取不到数据返回-1(该方式不适合用于读取长文本)
int read();
//从次此输入流中读取b.length个字节,范围类型为读取的字节个数,若读取不到数据返回-1
int read(byte[] b);
//从此输入流中将最多len个字节的数据读入到一个byte数组中
int read(byte[] b,int off,int len);
//返回下一次对此输入流可以读取到的估计剩余字节数
int available();
//从输入流中跳过并丢弃n个字节数据
long skip(long n);

使用栗子
有一个abcdefg文件,里面记录有abcdefg几个字母

 public static void main(String[] args){

        FileInputStream fileInputStream=null;
        try {
            fileInputStream=new FileInputStream("abcdefg.txt");

            System.out.println("available="+fileInputStream.available());

            System.out.println("read()="+fileInputStream.read());

            byte[] bytes=new byte[2];
            int temp=fileInputStream.read(bytes);
            System.out.println("read(byte[] b)="+new String(bytes,0,temp));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fileInputStream!=null){
                fileInputStream.close();
             }
        }
    }

//输出结果
available=7
read()=97
read(byte[] b)=bc

3.1 FileOutputSrteam

FileOutputSrteam和FileInputStream是相对的,所以使用方式也是类似
FileOutputSrteam的构造方法

//文件路径
**FileOutputSrteam(String name)**
/*
*@parem name 文件路径
*@parem append 是否追加内容
*/
FileOutputStream(String name,boolean append)

第一个方法创建的输出流每次写入到磁盘文件都会进行内容覆盖,而第二创建的输出流则根据传入的参数判断是否是追加写入

FileOutputStream的常用方法:

//将b.length个字节从指定的byte数组写入到此文件输出流中
void write(byte[] b)
//将指定的byte[]数组中从偏移量off开始的len个字节写入到此文件输出流中
void write(byte[] b ,int off ,int len)
//将指定的字节写入此文件输出流中
void write(int b )

使用例子:

 public static void main(String[] args){

        FileOutputStream fos=null;
        try {
           fos=new FileOutputStream("abcdefg.txt");
   
           String msg="Hellworld";
           byte[]  b=msg.getBytes();

            fos.write(b);
            //强制写入
            fos.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if( fos!=null){
                 fos.close();
             }
        }

四、I/O流之FileReader,FileWriter

其实FileReader和FileWriter,和上面FileInputStream,FileOutputStream的用法基本一致的,只是从字节流变换成了字符流,而使用字符流的好处就是在读取文字的时候可以确保读取到完整的一个汉字(java中一个汉字占2个字节=一个字符),就避免了出现乱码的情况
由于用法差不多,这里就不在做细说,直接上个栗子吧

4.1 文件复制栗子

 public static void main(String[] args){

        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader("E:myClass.java");

            fw = new FileWriter("C:\\test\\myClass1.java", true);

            char[] chars = new char[512]; //1kb
            int temp;
            while ((temp = fr.read(chars)) != -1) {
                fw.write(chars, 0, temp);
            }

            //强制写入
            fw.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }

                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

熟悉了第三部分的字节流,那么这里的字符流也同样熟悉了

五、I/O流之InputStreamReader,OutputStreamWriter

InputStreamReader,OutputStreamWriter是比较有用的,因为他们是负责转换的,也叫转换流,这两个类可以将字节流转换成字符流

5.1 InputStreamReader

构造方法:

//构造方法返回一个InputStreamReade继承至Reader,字符输入流的用法前面FileReader已经讲解,这里用法是类似的
InputStreamReader(InputStream var1);
InputStreamReader(InputStream var1, String var2)

5.2 OutputStreamWriter

构造方法:

//构造方法返回一个OutputStreamWriter继承至Writer,字符输出流的用法前面FileWriter已经讲解,这里用法是类似的
OutputStreamWriter(OutputStream var1);
OutputStreamWriter(OutputStream var1, String var2);

六、I/O流之BufferedReader,BufferedWriter

buffered类型的流是指带有缓冲区的流类型,其有个很方便的方法就是可以直接读写一行数据

6.1 BufferedReader

构造方法:

BufferedReader(Reader reader);
BufferedReader(Reader reader,int size);

常用方法:

//readLine读取的数据是不会带末尾的换行符
String BufferedReader.readLine();

6.2 BufferedWriter

构造方法:

BufferedWriter(Writer writer);
BufferedWriter(Writer writer,int size);

常用方法:

void writer(char [],int off,int len);
void writer(int c);
void writer(String s,int off,int len);
void newLine();

七、I/O流之DataOutputStream,DataInputStream

data类型的字节流,可以将内存中的数据包括该数据的类型一起写入到文件中,在读取的时候也可以直接读取某个类型的数据,比如 int a=10; 它就会把int的类型的10写入到文件中,而不是单纯的写个10字符进去

7.1 DataOutputStream

构造方法:

DataoutputSteam (OutputSteam out);

常用方法:

void writeByte(byte b);
void writeShort(short s);
void writeInt(int t);
void writeLong(long l);
void writeFloat(float f);
void writeDouble(double b);
void writeBoolean(boolean b);
void writeChar(char c);

注意:由于dataoutputstream在写入数据的时候带上了数据类型,所以对于写入的文件是写入了二进制类型的数据,直接打开文件是看不懂的,必须使用对应的dataintputstream来读取文件数据

7.2 DataIntpuStream

构造方法:

DataInputSteam(InputStream is);

常用方法:

byte readByte(byte b);
short readShort(short s);
int readInt(int t);
long readLong(long l);
float readFloat(float f);
double readDouble(double b);
boolean readBoolean(boolean b);
char readChar(char c);

注意:在读取数据的时候,必须提前知道文件存储的格式,顺序,读取的顺序必须和写入的数据一致,不然无法读取数据

八、I/O流之ObjectOutputStream,ObjectInputStream

Objec的字节流类型其实相当于我们常说的,类的序列化和反序列化,其作用就是把java类对象写入到文件中,或者从文件中读取一个类对象的信息

8.1 ObjectOutputStream

相当于对对象实现序列化写入文件中,但前提该类对象实现了Serializable接口
构造方法:

ObjectOutputStream();
ObjectOutputStream(OutputStream out);

常用方法:

void writeObject(object obj);

8.2 ObjectInputStream

读取文件中的类信息,就是常说的反序列化
构造方法:

ObjectInputStream();
ObjectInputStream(InputStream in);

常用方法:

Object readObject();

注意:在反序列的时候,jvm会识别一个序列化ID,该ID的在我们做序列化的时候因为实现了serializable接口,所以jvm会自动帮我们的类对象加上一个static final long serialVersionUID;的属性,而该属性的作用是在反序列的时候,jvm会对比当前反序列化文件中的UID和当前序列化对象的class中的UID是否一致,如果不一致则会报异常

通常可以直接在实现序列化接口的时候自行定义一个serialVersionUID的成员变量,这样jvm就不会再覆写一个UID,保证了在序列化和反序列的时候使用了同一个UID


总结

I/O流在日常开发逻辑中可能用得不是很多,但是I/O流在做数据持久化中是必不可少的知识,理解清楚常用流的作用以及它们之间的关系,可以在做数据写入和读取的时候更加得心应手。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 导语: 记得刚刚学习Java I/O的时候,被输入输出流的层次结构吓得不轻,一整个流家族里面,包含了各种流类型,其...
    wuqke阅读 800评论 1 1
  • 前言:在之前的面试中,每每问到关于Java I/O 方面的东西都感觉自己吃了大亏..所以这里抢救一下..来深入的了...
    我没有三颗心脏阅读 2,483评论 0 21
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,365评论 0 4
  • 昨天,我摊上大事儿了。 最初,我并没有意识到问题的严重性。工作出现失误,这谁都有过。无论是谁出了问题,碰到我值班,...
    绽蕊向阳阅读 138评论 2 1
  • 摄影日更Day7 小肉肉
    舞步指尖阅读 245评论 0 0