java中的I/O

核心类,接口

File---------------------------------文件流

InputStream-----------------------字节输入流----字节流可以处理一切,比如文本,音像,图片等

OutputStream---------------------字节输出流

Reader-----------------------------字符输入流----字符流只能处理纯文本,可以转换成字节流,但字节流不一定能转化成字符流,比如音像,图片等

Writer------------------------------字符输出流

Closeable--------------------------关闭流接口----java通知操作系统可以释放资源了

Flushable--------------------------刷新流接口----避免数据驻留在内存中

Serializable------------------------序列化接口

 

用户的当前目录

System.out.println(System.getProperty("user.dir'));

 

I/O----java.io

流:是一个抽象,动态的概念,是一连串连续动态的数据集合。

数据源;提供原始数据的原始媒介,常见的:数据库,文件,其他程序,内存,网络链接,I/O设备。

(1).如果对于File对象来说,输入和输出操作只能针对文件,不能针对目录

(2).IO操作不仅仅使针对文件,它可以从网路中输入和输出。。。。

(3).输入:

        输出:----参照物使当前程序

例如:

把数据写到文件中:输出操作,把数据从程序中输出到文件

从文件读取数据:输入操作

例如:

    服务器发送数据到客户段:

        对于服务器来说是输出

        对于客户段来说是输入

 

2.IO分类

(1).方向

    输入流和输出流

(2).操作数据单位

    字节流和字符流

    字节流:以字节为单位byte

    字符流:以字符为单位char

字符流:只能用于读/写纯文本数据

纯文本数据:内容全是字符

                    .txt,.html,.properties等是纯文本文件

                    .doc,.xls,.ppt都不是

字节流:适应于任何类型文本

如果全是纯文本用字符流快

 

(3).功能角色不同

节点流和处理流

节点流:和每个节点关联,例如:文件流。。

处理流:在节点流的基础上,加其他的处理功能,加装饰功能的,例如:缓冲流,序列化与反序列化

 

3.IO流有四大抽象基类/超类/父类

    (1).InputStream:字节输入流

    (2).OutputStream;字节输出流

    (3).Reader:字符输入流

    (4).Writer:字符输出流

例如:文件IO流:

    (1).FileInputStream:文件字节输入流

    (2).FileOutputStream;文件字节输出流

    (3).FileReader:文件字符输入流

    (4).FileWriter:文件字符输出流

例如:缓冲IO流

    (1).BufferedInputStream:字节缓冲输入流

    (2).BufferedOutputStream;字节缓冲输出流

    (3).BufferedReader:字符缓冲输入流

    (4).BufferedWriter:字符缓冲输出流

 

文件的IO操作

1.读取一个纯文本的文件

步骤:

public class Test{

        

    public void test01(){

        //1.创建源

            File file = new File("a.txt");

        //2.选择流----因为是去读一个纯文本文件,所以选自字符流

        FileReader fileReader = new FileReader(file);

        //3.操作---读,数据从a.txt中---->fileReader流中---->从流中开始读取

        char[] arr = new char[10];

        int len = fileReader.read(arr);     //将a.txt中的数据读入arr中,返回的是读取的字符个数

        System.out.println(new Sstring(arr));

        //4.关闭流

        fileReader.close();

    }

}

 

2.写一些数据到纯文本文件中

步骤:

    public class Test{

        public void test01{

            //1.创建源

                File file = new File("b.txt");

            //3.选择流

                FileWriter fileWriter  = new FileWriter(file);

            //3.操作---写,将程序中的数据写入b.txt中

                Scanner scanner = new Scanner(System.in);

                System.out.println("请输入一句话:");

                String str = scanner.nextLine();

                char[] ch = str.toCharArray();

                fileWriter.write(ch);   //将ch中的数据写入到b.txt中

                fileWriter.flush();       //刷新

                System.out.println(new String(ch));

            //4.关闭流

                fileWriter.close();

                scanner.close();

 

3.纯文字之间的复制,即将将a.txt中的文件复制到b.txt中

package com.iotest.FileWriter;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

/**

 * 实现边读边写

 */

public class FileReader_WriterSample2 {

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

             String s1 = "a.txt";

             String s2 = "b.txt";

             FileReader_WriterSample2 fi = new FileReader_WriterSample2();

             fi.test(s1, s2);

       }

       public void test(String srcFileName,String descFileName) throws IOException{

             //创建源

             File file1 = new File(srcFileName);  

             File file2 = new File(descFileName); 

             //选择流

             FileReader fr = new FileReader(file1);

             //FileWriter fw = new FileWriter(file2);  //这样会将b.txt中的原有的资料覆盖

             FileWriter fw = new FileWriter(file2, true);

             fw.append("\n");

             //操作流

             char[] ch = new char[(int)file1.length()];

             int len;

             while ((len = fr.read(ch)) != -1) {

                    fw.write(ch, 0, len); 

                    fw.flush();

             }

             //关闭流

             fw.close();

             fr.close();

       }

}

 

4.使用字节流,来读取文件(非纯文本文件)

package com.iotest.FileInputoutput;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

/**

 * 测试,边读边写

 *

 */

public class FileInput_OutputStreamSample {

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

             String s1 = "a.docx";

             String s2 = "b.docx";

             FileInput_OutputStreamSample fi = new FileInput_OutputStreamSample();

             fi.test(s1, s2);

       }

       public void test(String srcFileName,String descFileName) throws IOException{

             //创建源

             File file1 = new File(srcFileName);

File file2 = new File(descFileName);

             

             //选择流

             InputStream input = new FileInputStream(file1);

             OutputStream output = new FileOutputStream(file2);

             //操作流

             byte[] ch = new byte[(int)file1.length()];

             int len;

             while ((len = input.read(ch)) != -1) {

                    output.write(ch, 0, len);

                    output.flush();

             }

             //关闭流

             output.close();

             input.close();

       }

}

a.docx中:

纯文字:

“甩锅”大戏正式开始!万茜账号被盗事件,网易已然被动“接锅”

导语:“击鼓传花”开始!万茜账号被盗事件,知乎已成功“甩锅”网易,“甩锅”大戏正式开始!

前两天,万茜点赞宁静和郁可唯“黑评”的事引起了网友的热议。

在这条评论中,宁静被称为爱出风头的娱乐圈“黑洞”,而郁可唯则被称为宁静的“死忠”。

图片:

MP4:

b.docx中

纯文字:

“甩锅”大戏正式开始!万茜账号被盗事件,网易已然被动“接锅”

导语:“击鼓传花”开始!万茜账号被盗事件,知乎已成功“甩锅”网易,“甩锅”大戏正式开始!

前两天,万茜点赞宁静和郁可唯“黑评”的事引起了网友的热议。

在这条评论中,宁静被称为爱出风头的娱乐圈“黑洞”,而郁可唯则被称为宁静的“死忠”。

图片:

MP4:

 

5.缓冲IO流:

    是处理流,负责在其他IO流基础上增加缓冲功能

    BufferedReader--->Reader

    BufferedWriter---->Writer

    BufferedInputStream---->InputStream

    BufferedOutputStream--->outputStream

BufferedReader除了继承Reader的那些读的方法,还增加了一个:String readLine()读取一行,这里不会换行

while(str = bi.readLine()  != null){

        bo.write(str);

}---这里因为readLine不会换行,所以每读取一行的字符会在一起,需要手动加入换行:

    1.bo.write(str + "\n");---不建议使用,因为在记事本中打开,不起作用,因为记事本是由C++写的,换行符为\r\n---\r表示本行结束,\n把光标移动到下一行

    2.bo.newLine();   ----两种方法

BufferedWriter除了继承Writer的那些写的方法,还增加了一个:String newLine()相当于换行

为什么使用缓冲流可以加快速度?

默认的缓冲大小:8192字节/字符

案例:将A盘下的CentOS-7-x86_64-DVD-1810.iso复制到A盘的1.iso

package com.iotest.buffer;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

public class FileBufferedInput_OutputStream {

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

             String srcFile = "A:\\CentOS-7-x86_64-DVD-1810.iso";

             String desFile = "A:\\1.iso";

             long start = System.currentTimeMillis();

             FileBufferedInput_OutputStream.copy(srcFile, desFile);

             long end = System.currentTimeMillis();

             

 System.out.println("运行的时间为:" + (end - start));

       }

       

       public static  void copy(String srcFile,String desFile) throws IOException{       

             //1.创建源

             File file1 = new File(srcFile);

             File file2 = new File(desFile);

             //2.选择流

             /*

              * 这里相当于从file1--->fi--->bi读

              */

             FileInputStream fi = new FileInputStream(file1);

             BufferedInputStream bi = new BufferedInputStream(fi);

             /*

              * 这相当于从bo--->fo--->file2写

              */

             FileOutputStream fo = new FileOutputStream(file2);

             BufferedOutputStream bo = new BufferedOutputStream(fo);    

             //3.操作流

             byte[] bs = new byte[(int)file1.length()];

             while (bi.read(bs, 0, bs.length) != -1) {

                    bo.write(bs);

                    bo.flush();

             }       

             //4.关闭流

             /*

              * 这里关闭流是有次序的

              */

             bi.close();

             fi.close();

             bo.close();

             fo.close();

       }

}

 

6.转换流---InputStreamReader和OutputStreamWriter

    1.在字符串中的解码和编码

           字符-----字节:编码

     字节-----字符:解码

编码:字符串---字节

public class A{

    public static void main(String[] args){

        String str = "性命生命使命a";

        //编码

        byte[] byte = str.gteBytes();

        System.out.println(byte.length);    //19,因为是默认的字符集为utf-8,每一个汉字占三个字节,一个字母占1个字节

        byte[] byte = str.getBytes("UTF-16LE);   

        System.out.println(byte.length);      //14,因为UTF-16LE 汉字占2个字节,字母占2个字节

        byte[] byte = str.getBytes("gbk")

        System.out.println(byte.length);   //13,因为gbk汉字占2个字节,字母占1个字节

解码:字节---字符串

        str = new String(byte,0,byte.length,"utf-8");

        System.out.println(str.toString);

乱码问题:

1.字节数不够

    str = new String(byte,0,byte.length -3,"utf-8");

        System.out.println(str.toString);

2.字符集不统一

    str = new String(byte,0,byte.length,"gbk");             //eclipse中默认的字符集为utf-8,现在传进来的字符集为gbk

        System.out.println(str.toString);

 

2.解码:字节输入流转换为字符输入流

InputStreamReader:把字节转换为字符,同时还能指定编码方式

    案例:

        FileInputStream fi = new FileInputStream("d:/io.txt");

        //将fi中的字节流按照GBK进行解码为字符流

        InputStreamReader fis = new InputStreamReader(fi,"GBK");

        //解绑:d:/io.txt(GBK)-->fi(纯字节)-->fis(GBK)解成字符流--->按字符读取

        char[] ch = new Char[3];

        int len = fis.read(ch);

        System.out.println(new String(ch,0,len));

        //关闭流

        fis.close();

        fi.close();

 

 

3.编码:字符--->字节,把字符流转换为字节流

OutputStreamWriter:把字符流转为字节流,并且可以指定编码

    案例:

        String str = "和附近的哈哈飞机获得加分加分";

        FileOutputStream fo = new FileOutputStream("d:/io.txt");

        OutputStreamWriter fos = new OutputStreamWriter(fo,"GBK");

        //数据:str(字符)-->fos(字符)按照GBK编码为字节流--->fos--->io.txt

        fos.writer(str);

        //关闭流

        fos.close();

        fo.close();

 

 

7字节数组流---ByteArrayInputStream和ByteArrayOutputStream

package com.iotest.bytearray;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.nio.channels.NonWritableChannelException;

/*

* 实现ByteArrayInputStream

* 实现ByteArrayOutputStream

* A ByteArrayInputSteam包含一个内部缓冲区,其中包含可以从流中读取的字节。

* 关闭一个ByteArrayInputStream没有效果

* 1.相当于操作的是内存中的数据

2.不用手动释放,垃圾回收器回收

3.任何东西都可以转成字节数组,方便在网络上进行传输

4.不建议数据量过大

*/

public class ByteArrayInput_OutputStream {

    public static void main(String[] args) {

        ByteArrayInput_OutputStream byteArray = new ByteArrayInput_OutputStream();

        byteArray.ByteArrayInputStreamSample("files//a.txt");

        byteArray.ByteArrayOutputStreamSample();

    }

    public void ByteArrayInputStreamSample(String str){

        //创建源

        File file = new File(str);

        byte[] ch = new byte[(int) file.length()];

        InputStream inputStream = null;

        try {

            inputStream = new FileInputStream(file);

            try {

                inputStream.read(ch);

            } catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        } catch (FileNotFoundException e1) {

            // TODO Auto-generated catch block

            e1.printStackTrace();

        }

                

        byte[] bs = new String(ch).getBytes();

        //选择流

        ByteArrayInputStream byteArray = new ByteArrayInputStream(bs);   //使用bs作为其缓冲区数组

        try {

            byteArray.read(bs);

            String string = new String(bs);

            System.out.println(string);

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

  public void ByteArrayOutputStreamSample(){

        //创建源

        byte[] bs = "\n放假回家哈十分巨大的JFK接口对接".getBytes();

        //选择流

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();    

        //操作流

        try {

            outputStream.write(bs);

            outputStream.flush();     //刷新

            String string = new String(outputStream.toByteArray());

            System.out.println(string);

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

    

}

 

8.数据IO流---DataInputStream和DataOutputStream

package com.iotest.data;

import java.io.DataInputStream;

import java.io.DataOutput;

import java.io.DataOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

/*

* 程序中有这样一组数据:

* int num = 10;

* char c = '好';

* double d = 88.88;

* String info = "尚硅谷真好!";

* boolean good = true;

* 程序运行过程中,想要临时退出,下次希望从这个状态继续恢复执行。

* 希望Java能够输出各种数据类型的数据,读取时,能还原各种数据类型的数据。

* 因为这些数据不是纯文本,那么只能选择字节流。

* java中IO流的类的体系设计,隐含了一个设计模式:装饰着设计模式

* DataOutputStream在OutputStream的基础上,增加了很多方法:

* writeXxx()...

* DataOutputStream在InputStream的基础上,增加了喝多方法;

* Xxx readXxx()...

* 要求:

* 用DataOutputStream写的文件或数据,得用DataInputStream来读取。

* 并且要求读的顺序和写的顺序一致

*/

public class DataInput_OutputStream {

    /*

     * 文件a.dat中的数据为:

     * int num = 10;

        char c = '好';

        double d = 188.88;

        String info = "尚硅谷真好!";

        boolean good = true;

     */

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

        String desFile = "abc.txt";

        DataInput_OutputStream.dataWriter(desFile);

    }

    public static void dataWriter(String desFile) throws IOException{

        int num = 10;

        char c = '好';

        double d = 188.88;

        String info = "尚硅谷真好!";

        boolean good = true;

        //1.创建源

        File file2 = new File(desFile);

        //2.选择流

        /*

         * dop--->fo--->file2

         */

        FileOutputStream fo = new FileOutputStream(file2);

        DataOutputStream dop = new DataOutputStream(fo);

        //3.操作流

        /*

         * 将上面的数据写入desFile文件中

         */

        dop.writeInt(num);

        dop.writeChar(c);

        dop.writeDouble(d);

        dop.writeUTF(info);

        dop.writeBoolean(good);

        //关闭流

        dop.close();

        fo.close();

    }

}

 

8.对象的序列化和反序列化----ObjectInputStream和ObjectOutputStream

user类

package com.iotest.object;

import java.io.Serializable;

public class User implements Serializable{

       private int id;

       private String name;

       private String password;

       

       public User(int id,String name,String password){

             this.id = id;

             this.name = name;

             this.password = password;

       }

       public int getId() {

             return id;

       }

       public void setId(int id) {

             this.id = id;

       }

       public String getName() {

             return name;

       }

       public void setName(String name) {

             this.name = name;

       }

       public String getPassword() {

             return password;

       }

       public void setPassword(String password) {

             this.password = password;

       }

}

 

对象序列化和反序列化类

/*

* 序列:排队,

* 把对象转为字节序列,序列化的过程

 

什么是序列化

序列化是对象进行持久化处理,也就是说,将对象转化成一个字节流进行存储(比如存储为一个字节文件)或传输(通过网络传输字节)。同时,我们也可以从字节中反序列化一个对象出来。这是Java程序中一个重要的概念,因为网络应用中通常需要将对象序列化成字节传输。每一个需要序列化的对象,都要实现 Serializable 接口

*

* ObjectOutputStream:用于输出对象,把对象转成字节数据输出,对象的输出过程称为序列化。

*         ObjectOutputStream比OutputStream多了很多方法,其中一个是  writeObject(obj)

*

* 只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。

    writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应         ObjectInputstream 中读回对象。

在d.txt中存储的数据:

*

*

* ObjectInputstream:用于输入对象,把字节序列转为对象读取,对象的读取过程称为反序列化。

*         ObjectInputstream比InputStream多了很多方法,其中一个是 Object readObject()

*/

package com.iotest.object;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class ObjectInput_OutputStream {    

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

             ObjectInput_OutputStream object = new ObjectInput_OutputStream();

             String desFile = "d.txt";

             object.objectOutputStreamTest(desFile);         

             String srcFile = "d.txt";

             object.objectInputStreamTest(srcFile);

       } 

       public void objectOutputStreamTest(String desFile) throws IOException{     

             User user = new User(2, "张三", "123456");      

             //1.创建源

             File file = new File(desFile);

             //2.选择流

             /*

              * 程序--->obj---->fi---->file

              */

             FileOutputStream fi = new FileOutputStream(file);

             ObjectOutputStream obj = new ObjectOutputStream(fi);            

             //操作流

            /*这里会报错:    

                即,没有实现序列化接口的类都不能序列化,解决方法:

                

             obj.writeObject(user);

             //关闭流

             obj.close();

             fi.close();

       }

       public  void objectInputStreamTest(String srcFile) throws ClassNotFoundException, IOException{         

             //创建源

             File file = new File(srcFile);   

             //选择流

             FileInputStream fi = new FileInputStream(file);

             ObjectInputStream obj = new ObjectInputStream(fi);

             //操作流

             /*

                这里会报:ClassNotFoundException

              * 把字节流中的数据,转为一个对象,读取过程中会创建对象,new对象时需要找对象的类型

             User user = (User)obj.readObject();

             System.out.println(user.getPassword());

             //关闭流

             obj.close();

             fi.close();

       }

}

注意:这里需要注意序列化本版ID:

1.在user类中增加一个属性:---address

2.在ObjectInput_OutputStream中:

3.报错:

报这个错的原因是:流中关于类的serialVersionUID与本地类的serialVersionUID对不上,就会报InvalidClassException错误,

         * 如何解决?

         * (1)修改本地的serialVersionUID为流中的serialVersionUID

                    

                    运行之后,不再报错

         * (2)或者,在当初实现Serializable接口时,就固定一个serialVersionUID,这样每次编译就不会自动生成一个新的serialVersionUID

                    当没有固定序列版本id时,user类会有警告

                    

                    解决方式:

                    ---这里个1可以是任意数字

注意:对象中的有些属性不需要序列化

1.加入了transient 关键字的属性

Goods类---商品类

package com.iotest.object;

import java.io.Serializable;

public class Goods implements Serializable{

       private static final long serialVersionUID = 1L;

       private String name;

       private float price;   //价格

       private transient int sales;     //销售量

       public Goods(String name,float price,int sales){

             this.name = name;

             this.price = price;

             this.sales = sales;

       }

       public String getName() {

             return name;

       }

       public void setName(String name) {

             this.name = name;

       }

       public float getPrice() {

             return price;

       }

       public void setPrice(float price) {

             this.price = price;

       }

       public int getSales() {

             return sales;

       }

       public void setSales(int sales) {

             this.sales = sales;

       }

       @Override

       public String toString() {

             return "Goods [name=" + name + ", price=" + price + ", sales=" + sales + "]";

       }

}

GoodObjectInput_OutputStream类

package com.iotest.object;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class GoodObjectInput_OutputStream {

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

             GoodObjectInput_OutputStream good = new GoodObjectInput_OutputStream();

             String desFile = "e.txt";

             String srcFile = "e.txt";

             good.goodsOutputStream(desFile);

             good.goodsInputStream(srcFile);

       }

       public void goodsOutputStream(String desFile) throws IOException{

             Goods goods = new Goods("连衣裙",88,100);

             //创建源

             File file = new File(desFile);

             //选择流

             FileOutputStream fi = new FileOutputStream(file);

             ObjectOutputStream obj = new ObjectOutputStream(fi);

             //操作流

             obj.writeObject(goods);

             //关闭流

             obj.close();

             fi.close();

       }

       public void goodsInputStream(String srcFile) throws IOException, ClassNotFoundException{

             //创建源

             File file = new File(srcFile);

             //选择流

             FileInputStream fi = new FileInputStream(srcFile);

             ObjectInputStream obj = new ObjectInputStream(fi);

             //操作流

             Goods goods = (Goods)obj.readObject();

             System.out.println(goods.toString());

             //关闭流

             obj.close();

             fi.close();

       }

}

结果为:

如果想sales中的值不序列化,就是在这个属性中加入transient关键字

transient:表示sale属性不需要序列化

  

结果为:

2.加入了static关键字的属性

---加入静态的brand属性

在GoodObjectInput_OutputStream类中:

注意:当将Goods.setBrand("安踏")加入上面的位置时,结果如下:

无论是放在前面还是在后面,结果都一样

这是因为都在同一个机器(而且是同一个进程),因为这个jvm已经把brand加载进来了,所以你获取的是加载好的brand

看下面:

而在Test3类中:

package com.iotest.object;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

public class Test3 {

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

             Test3 t = new Test3();

             t.goodsInputStream("e.txt");;

       }

       public void goodsInputStream(String srcFile) throws IOException, ClassNotFoundException{

                    //创建源

                    File file = new File(srcFile);

                    //选择流

                    FileInputStream fi = new FileInputStream(srcFile);

                    ObjectInputStream obj = new ObjectInputStream(fi);

                    //操作流

                    Goods goods = (Goods)obj.readObject();

                    System.out.println(goods.toString());

                    //关闭流

                    obj.close();

                    fi.close();

             }

}

结果为:

----即可知道static修饰的属性,没有被序列化,反证明如下:

1.将brand属性不设置为static

 

2.在GoodObjectInput_OutputStream类中:

结果为:

3.在Test3类中:

结果为:
说明:
1. 序列化并不保存静态变量,无论改变量是否被transient修饰
2.transient只能修饰变量,不能修饰类和方法
3.transient修饰的变量的类需要实现Serializable接口
 
被序列化的一些中如果有引用对象,那么这个引用对象所对应的类需要序列化,如上面的类中的String类型,String实现了序列化接口
 
 
 
    Externalizable
 
        1.java.io.serializable接口:
                1.类通过实现java.io.serializable接口以启用其序列化功能。未实现此接口的类无法使用任何状态序列或反序列化
                2.可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于表示可序列化的语义
                3.如果实现serializable接口,对象如何序列化,各个属性序列化的顺序是什么,都是默认的,程序员无法指定,也不用关系
                4.如果属性前面有staic和transient修饰,不参与序列化
 
        2.java.io.Externalizable
                1.若某个要完全控制某一对象及其超类类型的流格式和内容,则它要实现Externalizable接口中的writeExternal和readExternal方法
                2.程序员在writeExternal方法中,自定定制哪些属性要序列化,顺序是什么样
                3.程序员在readExter方法中,自定定制哪些属性要反序列化,顺序和writeExternal的方法中一致
 
案例:
Goods类
package com.test.test01;
 
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
 
public class Goods implements Externalizable{
    private static String brand = "安踏";
    private String name;
    private double price;
    private transient int sale;
    public Goods(String name, double price, int sale) {
        super();
        this.name = name;
        this.price = price;
        this.sale = sale;
    }
    public Goods() {
        super();
    }
    public static String getBrand() {
        return brand;
    }
    public static void setBrand(String brand) {
        Goods.brand = brand;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getSale() {
        return sale;
    }
    public void setSale(int sale) {
        this.sale = sale;
    }
    @Override
    public String toString() {
        return "Goods [brand = " + brand +",name=" + name + ", price=" + price + ",sale = " + sale +"]";
    }
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        //程序员自己定制要序列化的内容,顺序等
        //这两个方法是在对象被序列化和反序列化的过程中,JVM帮我们调用
        out.writeUTF(brand);//静态的也序列化
        out.writeUTF(name);
        out.writeDouble(price);
        out.writeInt(sale);//有transient也序列化
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        //程序员自己定制要反序列化的内容,顺序等,建议与序列化的顺序一致
        brand = in.readUTF();
        name = in.readUTF();
        price = in.readDouble();
        sale = in.readInt();
    }
}
 
Test类
public class TestObject {
    @Test
    public void test01() throws IOException{
        Goods goods = new Goods("《从入门到放弃》", 99.99, 1000);
        Goods.setBrand("atguigu");
        
        FileOutputStream fos = new FileOutputStream("goods.dat");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        
        oos.writeObject(goods);
        
        oos.close();
        fos.close();
    }
    
    @Test
    public void test02()throws IOException, ClassNotFoundException{
        FileInputStream fis = new FileInputStream("goods.dat");
        ObjectInputStream ois = new ObjectInputStream(fis);
        
        Object obj = ois.readObject();
        System.out.println(obj);
        
        ois.close();
        fis.close();
    }
}
 
 
打印流:输出流
PrintStream
                    经典代表:
                                        System.out
                                        System.err
PrintWriter
        web阶段学习时,从服务器段往客户端返回消息时用到response,response.getWriter()返回PrintWriter对象
        即web服务器往客户端(例如:浏览器)返回html网页时,用的是PrintWriter对象的输出方法
 
案例:
        1.
                public static void main(String[] args){
                        PrintStream out = System.out;
                        out.println("hello");
                        out.println();
                }
 
        2.
                /*
                 *
                 *    new PrintStream(文件名)
                 *     new PrintStream(文件名,编码)
                 *     new PrintStream(另一个字节输出流)
                 */
                public static void main(String[] args){
                        //将下面的内容写入1.txt中
                        PrintStream ps = new PrintStream("1.txt","GBK");
                        ps.println("hello");
                        ps.println("world");
                        ps.println("您好");
                        ps.close();
                }
 
       3.
            public staic void main(String[] args){
                    //所有数据类型写出去,都是按照文本处理,即不是自身的类型
                    PrintStream ps = new PrintStream("1.txt");
                    ps.println(12);
                    ps.println(true);
                    ps.println(new Goods("李宁",99.99,100));
                    ps.close();
            }
                    
Scanner
 
package com.scanner.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Test {
       
        /*
        * System.in:默认情况下是从键盘输入的数据中扫描
        */
        public static void test01(){
              //System.in返回的是一个InputStream对象
             Scanner input = new Scanner(System. in);
             System. out.println( "请输入一个整数:");
              int num = input.nextInt();
             System. out.println( "num = " + num);
              input.close();
       }
       
        /*
        * Scanner:可以从指定的文本,流中读取文本数据
        */
        public static void test02() throws FileNotFoundException{
             Scanner input = new Scanner( new FileInputStream( new File( "1.txt")), "GBK");
             
              while ( input.hasNextLine()) {
                    String line = input.nextLine();
                    System. out.println( line);
             }
              input.close();
       }
       
        public static void main(String[] args) throws FileNotFoundException {
             Test. test01();
             System. out.println( "\n**************\n&&&&&&&&&&&&&&");
             Test. test02();
       }
}
结果为:
控制台:
请输入一个整数:
5
num = 5
**************
&&&&&&&&&&&&&&
hello
你好啊
是的,你好啊
welcome China
thank you
谢谢!!!
 
 
 
System
/*
* 在Java层面是常量对象,但是可以同C等底层语言进行修改
* System.in:
* System.out
* System.err
*/
public class TestSystem {
    @Test
    public void test02() throws FileNotFoundException{
        System.setOut(new PrintStream("1.txt"));
        //将下面的内容保存到了1.txt文件中,并不是像往常一样,打印到控制台,这是因为
        //System.setOut(new PrintStream("1.txt"));改变了它的打印方式,它的底层使用C语言写的
        System.out.println("aaaa");
        System.out.println("bbb");
        System.out.println("ccc");
        System.out.println("ddd");
    }
    
    @Test
    public void test01(){
        PrintStream out = System.out;
        System.out.println(out);
    }
}
 
 
IO标准步骤
package com.iotest.filetest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
 * IO流的标准步骤
 * @author zhuaisha98kbaoni
 *
 */
public class IOStandardProcedure {
        public static void main(String[] args) {
              //创建源
             File file = new File( "File/a.txt");
              //选择流
             InputStream inputStream = null;
              try {
                     inputStream = new FileInputStream( file);
              //操作(读取)
                    /*
                        读取的是汉字时---相当于将字节-->字符---read(byte[])---返回的整个文件中的文字的个数
                     byte[] bs = new byte[( int) file.length()];
                     try {
                            inputStream.read( bs);  //将文件中读取的字节存入字节数组
                           String string = new String( bs);
                           System. out.println( string.toString());
                    } catch (IOException e) {
                            e.printStackTrace();
                    }
                    */
                    /*读取的是字符串时----read()--返回的是单个字符的asscii码
                     */
                    int index = 0;
                    while((index = inputStream.read())!= -1){
                        System.out.printf("%c",(char(index));
                    }
             } catch (FileNotFoundException e) {
                     e.printStackTrace();
             } finally {
                     //关闭流
                     try {
                            inputStream.close();
                    } catch (IOException e) {
                            e.printStackTrace();
                    }
             }
       }
}
 
 
/*
        * 将程序中的数据存入文件
        */
        public void outputStream(){
              //创建源
             File file = new File( "File/b.txt");
              //选择流
             OutputStream out = null;
              try {
                     out = new FileOutputStream( file);
                     //写入相当于将字符-->字节
                    String str = "发健康的减肥空间安防监控的解放军";
                     byte[] bs = str.getBytes();
              //操作(写入)
                     try {
                            out.write( bs);
                    } catch (IOException e) {
                            e.printStackTrace();
                    }
             } catch (FileNotFoundException e) {
                     e.printStackTrace();
             } finally {
                     //关闭流
                     try {
                            out.close();
                    } catch (IOException e) {
                            e.printStackTrace();
                    }
             }      
       }
 
 
FileReader:通过字符的方式读取文件,仅适合字符文件
FileWriter:通过字节的方式写出或者追加数据到文件中,仅适合字符文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值