java之输入输出流(I/O)总结

本文详细介绍了Java中的文件操作,包括文件的基本概念、创建、信息获取和删除。接着,讲解了IO流的原理、分类,如字节流与字符流的对比,以及流的体系结构。文章还深入讨论了节点流与处理流,如BufferedInputStream和BufferedOutputStream的作用。此外,对象流(ObjectInputStream和ObjectOutputStream)的序列化和反序列化过程,以及转换流(InputStreamReader和InputStreamWriter)在解决文件乱码问题中的应用也有涉及。最后,提到了Properties类在处理配置文件中的应用。
摘要由CSDN通过智能技术生成

源自韩顺平老师的java课程总结


一、文件

(1)文件的基本介绍

1.文件:保存数据的地方,如文档,图片,视频,声音。数据库,磁盘等。
2.文件流:文件在程序中是以流的形式来操作的。
:数据在数据源(文件/磁盘)和程序(内存)之间经历的路径。
输入流:数据从文件到程序的路径。
输出流:数据从程序到文件的路径。

(2)常用的文件操作:

1.三种创建文件对象的方式。
2.createNewFile创建新文件。

//第一种方式
 File file = new File("d:\\news1.txt");
 //第二种方式
 File file1 = new File("d:\\");
 String fileName="news2.docx";
 File file = new File(file1, fileName);
 //第三种方式
 String ParentPath="d:\\";
 String name="cline1.ppt";
 File file = new File(ParentPath, name);

(3)获取文件相关的信息

目录在java中是一种特殊的文件。

   	  File file = new File("d:\\news1.txt");
        System.out.println("文件名字="+file.getName());
        System.out.println("文件绝对路径="+file.getAbsolutePath());
        System.out.println("文件父级目录="+file.getParent());
        System.out.println("文件大小(字节)="+file.length());
        System.out.println("文件是否存在"+file.exists());
        System.out.println("是不是一个文件文件"+file.isFile());
        System.out.println("是不是一个目录"+file.isDirectory());
        System.out.println("文件是否可读"+file.canRead());
        System.out.println("文件是否可写"+file.canWrite());

(4)目录的操作和文件的删除

mkdir:创建一级目录。
mkdirs:创建多级目录。
delete:删除文件和空目录。

二、IO流原理及流的分类

(1)I/O流的原理:

1.I/O:用于处理数据传输,如读/写文件、网络通讯。
2.java程序中,数据的输入输出以“流”的方式进行。
3.java.io包下提供了各种“流”类和接口。可以获取不同种类的数据,并提供相应的方法。
4.输入input:读取外部数据到程序中。
5.输出output:将程序中的数据输出到外部设备(磁盘、光盘等存储设备)中。

(2)流的分类:

1.按操作数据的单位不同:字节流和字符流。(根据编码方式不同,一个字符也对应不同的字节数。)
2.按数据流的流向不同:输入流和输出流。
3.按流的角色不同:节点流和处理流(包装流)。
在这里插入图片描述

java的io流设计的类都是由4个抽象基类派生的。
由这四个类派生出的子类名称都是以其父类作为子类的后缀名。

(3)字节流和字符流的比较

一般来说字符流效率高些,但

字节流在操作二进制文件时,如声音文件、视频文件、word文件,可以保证读取文件操作是无损操作
字符流操作文本文件比较好。因为文本也是用字符来存储的。

(4)IO流体系图

在这里插入图片描述

(5)常用的类

InputStream:字节输入流。
常用子类
FileInputStream:用于处理文件。
BufferedInputStream:带缓冲的方式,也可以处理文件,以字节的方式。
ObjectInputStream:可以处理对象。

(6)FileInputStream和FileOutputStream

1.FileInputStream读取文件的两种方式
(1)一个字节一个字节的读。
(2)一次读取一个字符数组长度的数据。
2.FileOutputStream写入文件的两种方式(以追加方式和覆盖方式):
(1)写入一个字符。
(2)写多个字符。
(3)以指定方式写多个字符。

//1.以覆盖方式
//fo=new FileOutputStream(path);
//2.以追加方式
fo=new FileOutputStream(path,true);
//1.写一个字符
//fo.write('K');
//写多个字符
String s="KSJDfhksdhfeabkj";
//fo.write(s.getBytes());
//指定方式写多个字符
fo.write(s.getBytes(),0,4);

两者结合可以实现文件的拷贝。

(7)FileReader和FileWriter

字符流,按照字符来操作io。
1.FileReader常用方法
读取单个字符。
读取字符数组。
2.相关API
将char[] -->String。
将char[]指定部分–>String。
3.FileWriter常用方法
(1)以覆盖模式写入(流的指针在首端)
(2)以追加模式写入(流的指针在尾端)
(3)可以写入单个字符,字符串,字符数组,或其指定部分。

三、节点流和处理流

(1)结点流和处理流基本介绍

节点流:从一个特定的数据源读写数据,如FileReader和FileWriter。
处理流:对节点流进行包装,使节点流的功能更加强大。
在这里插入图片描述
文件、数组、字符串、管道都是特定的数据源。

(2)节点流和处理流的区别和联系:

1.节点流是底层流/低级流,直接跟数据源相接。
2**.处理流**包装结点流,可以消除不同节点流的实现差异,,也可以提供更方便的方法来完成输入输出。
3.处理流对节点流进行包装,不会直接与数据源相连。

(3)BufferedInputStream和BufferedOutputStream

内部是一个缓冲数组。

        bis=new BufferedInputStream(new FileInputStream(srcPath));
        bos=new BufferedOutputStream(new FileOutputStream(descPath));
       byte[] bytes=new byte[1024];
       int Len=0;
       while((Len=bis.read(bytes))!=-1){
           bos.write(bytes,0,Len);
       }
            System.out.println("拷贝成功");

(4)BufferedReader和BufferedWriter

属于字符流,是按照字符来读取数据的。
BufferedReader:字符、数组和行的读取效率高。
readLine()方法,一行一行的读,如果已到达流的末尾,则为null。
BufferedWriter:
write()写入。
newLine():插入一个和系统相关的换行符。
两者也可以实现文本的拷贝。
不要操作二进制文件,可能会造成文件的损坏。

   br=new BufferedReader(new FileReader(srcPath));
   bw=new BufferedWriter(new FileWriter(descPath));
   String line=null;
     while ((line=br.readLine())!=null){
         bw.write(line);
         bw.newLine();
      }

四、对象流-ObjectInputStream和ObjectOutputStream

(1)序列化和反序列化:

序列化:在保存数据时,同时保存数据的值和数据类型
反序列化:在恢复数据时,恢复其值和数据类型。
若要让某个对象支持序列化机制,必须让其类是可序列化的。为了让类可序列化,这必须让该类实现可序列化接口:Serizialable和Externalizable中的一个。

(2)对象流基本介绍:

ObjectInputStream:提供反序列化功能。
ObjectOutputStream:提供序列化功能。
序列化

//序列化后,保存的文本格式,不是存文本,而是按照它的格式来保存的。
String filePath="d:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到data.dat文件之中
        oos.writeInt(1234);
        oos.writeBoolean(true);
        oos.writeChar('Y');
        oos.writeUTF("凭心而动");
        oos.writeDouble(13.54);
//保存一个dog对象
        oos.writeObject(new Dog("旺柴",7));
        oos.close();
        System.out.println("写入成功,序列化完成");

让Dog类实现可序列化

public class Dog implements Serializable {
    private String name;
    private int age;
//serialVersionUID 序列化的版本号,可以提高兼容性。
    private static final long serialVersionUID=1L;
    //这样,当这个类中重新加入一个属性后,不会认为这个类是一个全新的类,只会认为这个类作了一次更新。
    private transient String color="red";
    //transient:短暂的。不会进行序列化。
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

反序列化:

        String filePath="d:\\data.dat";
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(filePath));
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readUTF());
        System.out.println(ois.readDouble());
        Object o = ois.readObject();
        System.out.println(((Dog)o));
        System.out.println(((Dog)o).getName());
        ois.close();
        System.out.println("反序列化完成,数据恢复");

(3)对象流注意事项和细节:

(1)读写顺序要一致。
(2)要实现序列化和反序列化的对象,必须实现Serializable接口
(3)序列化的类中添加SerialVersionUID,可以提高版本的兼容性。
(4)序列化对象时,里面static和transient修饰的成员不进行序列化,其他都进行序列化。
(5)序列化对象时,里面属性的类型也需要实现序列化接口
(6)序列化具备可继承性,某类实现序列化,默认其所有子类也实现序列化。

五、转换流-InputStreamReader和InputStreamWriter

可以解决文件乱码问题。
转换流:把一种字节流转换成字符流。
在这里插入图片描述
转换成字符流,可以有效解决中文乱码问题

  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path),"gbk"));
        String s=null;
        while((s=br.readLine())!=null){
            System.out.println(s);
        }
        br.close();
        System.out.println("读取完毕");

(1)输入流:

1.将字节输入流转成字符输入流。
2.字符流传入BufferedReader进行包装。

 	    String filePath="d:\\new2.txt";
        String charSet="gbk";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
        osw.write("踏云");
        osw.close();
        System.out.println("以"+charSet+"方式写入完毕");

(2)输出流:

直接将字节输出流转成字符输出流。

六、标准输入输出流

在这里插入图片描述
System类中的两个属性in和out
System.in编译类型是InputStream,运行类型是BufferedInputStream
System.out的编译类型和运行类型一致。
System.out.println():默认输出到显示器。
Scanner sc=new Scanner(System.in):将一个BufferedInputStream对象输送给扫描器。

七、打印流

1.打印流没有输入流。

2.字节打印流-PrintStream:

  	    PrintStream out=System.out;
        out.println("桑落");
        //print底层使用的是write,所以可以直接用write进行输出。
        out.write("月华".getBytes());
        out.close();
        //可以去修改打印流输出的位置/设备
        //输出修改成d:\\f1.txt
        System.setOut(new PrintStream("d:\\f1.txt"));
        System.out.println("风花雪月");

3.字符打印流-PrintWriter:

//标准输出
  //    PrintWriter printWriter = new PrintWriter(System.out);
  //输出到知道位置。
        PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\new1.txt"));
        printWriter.print("hi");
        printWriter.close();

八、Properties类

(1)Properties类基本介绍:

1.以.properties结尾的是配置文件。
mysql.properties文件:

ip=192.168.100.100
user=root
pwd=123456

Properties类是专门用于读写配置文件的集合类。

(2)配置文件的格式:

键=值
键=值
键值对不需要空格和引号。默认类型是String。

(3)常见方法:

在这里插入图片描述

        Properties properties = new Properties();
        //1.load方法来加载配置文件。
        properties.load(new FileReader("src\\mysql.properties"));
        //2.显示信息-到控制台。
        properties.list(System.out);
        //3.根据k-v获取值。
        String user = properties.getProperty("user");
        String pwd = properties.getProperty("pwd");
        System.out.println("用户名是"+user+"密码是"+pwd);
        //得到ip的值
//        String ip = properties.getProperty("ip");
//        System.out.println("ip的值为:"+ip);

(4)使用Properties类创建配置文件,并修改配置文件的内容:

        Properties properties = new Properties();
        properties.setProperty("123","大象");
        properties.setProperty("456","鲸鱼");
        properties.setProperty("789","恐龙");

        //存储文件
//properties.store(new FileWriter("src\\mysql2.properties"),null);
        properties.store(new FileWriter("src\\mysql2.properties"),"hello,你好");

        System.out.println("保存配置文件成功");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值