【Io流】

目录

一.File类

1.简介

2.创建

3添加操作

4.删除操作

5.修改操作

6.查询操作

二.Io流

1.Io流概述
2.字符输入和输出流(Reader/Writer)

     2.1.Writer(输出)

     2.2.Reader(输入)

     2.3.使用字符流完成文件复制(先读取后写入):

3.字节输入输出流(InputStream/OutPutStream)

    3.1.概述:

    3.2.字节输出流(OutPutStream)

    3.3.字节输入流(InputStream)

    3.4.使用字节流完成文件复制(先读取后写入):

    3.5.注意:

4.缓冲流(Buffer)

   4.1.概述:

   4.2.创建:

   4.3.写入和读取(字节缓冲流)

5.对象流/序列化流(Object)

   5.1.概述:

   5.2.创建:

   5.3.序列化

   5.4.反序列化


一.File类

1.简介

File 类 就是当前系统中 文件或者文件夹的抽象表示 
    
通俗的讲  就是 使用File对象 才操作我们电脑系统中的文件或者文件夹

学习File类 其实就是学习 如果通过file对象 对系统中的文件/文件夹进行增删改查

2.创建


1 前期准备
    在电脑的非系统盘 创建一个 test文件夹 今天所有的操作都在这个文件夹中

2 创建
    public void test() {

        /*  路径分割符
         *  D:\haha\hehe\123.mp4    称之为路径  其中 \ 就是路径分割符 代表的是 下级目录
         *  在windows系统中 路径分割符为  \   在 Linux 和 Mac 中 路径分割符是 /
         *  我们写的java代码  需要跨平台 多环境运行   开发环境:windows   生成环境:Linux
         *  此时就会出现一个问题  如果我们的路径分隔符 写成 \  在 windows中好使 到了 Linux就不识别
         *  所以我们可以使用以下两种方式解决:
         *
         * */
        /* 方式1 :  windows不仅支持 \ 还支持/ */
        File file1 = new File("D:/aaa/123.txt");

        /* 方式2:   使用动态识别的常量  */
        // ;
        System.out.println(File.pathSeparator);
        // \ 
        System.out.println(File.separator);
       
        File file2 = new File("D:" + File.separator + "aaa" + File.separator + "123.txt");
    }

3添加操作

        File file = new File("E:/AAA/bbb.txt");
        file.createNewFile();//创建文件
        File file1 = new File("E:/AAA/ccc");
        file1.mkdir();//创建目录
        File file2 = new File("E:/AAA/eee/ddd");
        file2.mkdirs();//创建多级目录

4.删除操作

        File file3 = new File("E:/AAA/bbb.txt");
        file3.delete();//删除指定文件
        File file4 = new File("E:/AAA/ccc");
        file4.delete();//删除指定的空目录
        File file5 = new File("E:/AAA/bbb.txt");
        file5.deleteOnExit();//程序结束后删除

5.修改操作

        File file6 = new File("E:/AAA/bbb.txt");
        file6.setReadable(false);//设置指定文件不可读取
        File file7 = new File("E:/AAA/bbb.txt");
        file7.setWritable(false);//设置指定文件不可编写
        File file8 = new File("E:/AAA/bbb.txt");
        file8.renameTo(new File("E:/AAA/a.txt"));//重命名

6.查询操作

        File file9 = new File("E:/AAA/a.txt");
        String name = file9.getName();//查看文件名
        System.out.println(name);

        String parent = file9.getParent();//查看父级路径
        System.out.println(parent);

        String path = file9.getPath();//得到文件的路径
        System.out.println(path);

        boolean f = file9.isFile();//判断是否为文件
        System.out.println(f);

        boolean directory = file9.isDirectory();//判断是否为目录
        System.out.println(directory);

        File file10 = new File("E:/AAA");
        String[] list = file10.list();//列出AAA下所有子文件的名称
        System.out.println(Arrays.toString(list));

        File[] files = file10.listFiles();//列出AAA下所有文件对象
         for(File f1: files){
             System.out.println(f1.toString());
         }

二.Io流

1.Io流概述

IO都是全大写 说明肯定是两个单词的首字母
I   inputstream 输入流     O  outputstream  输出流
    
IO 称之为 java的输入输出流
    
其实学习IO  就是学习  如何通过java代码 对文件内容 进行   读(输入流)  写(输出流)
所以有一话:   读进来 写出去 

Java流的分类
按流向分:
输入流: 程序可以从中读取数据的流。
输出流: 程序能向其中写入数据的流。
    
按数据传输单位分:
字节流: 以字节为单位传输数据的流
字符流: 以字符为单位传输数据的流
    
按功能分:
节点流: 用于直接操作目标设备的流                                                      ----  四大基流
过滤流: 是对一个已存在流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。    ----  包装流  
    
四大基流:
        字节输入流
        字节输出流 
    
        字符输入流
        字符输出流

2.字符输入和输出流(Reader/Writer)

   2.1.Writer(输出)

public class MyWriter {
    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("E:/AAA/oo.txt",true);//加上true表示最佳内容时不会覆盖前面的内容
        String str = "abcdefg";
        writer.write(str);//给指定文件内添加内容

        String str1 = "higklmn";
        writer.write(str1);

        writer.flush();//刷新流
        writer.close();//关闭流
    }
}

   2.2.Reader(输入)

public class Text3 {
    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("E:/BBB/c.txt");//创建Reader对象,通过FileReader实现
        int r = reader.read();//读取内容的方法,默认每次只读取一个字符,返回字符对应的数字,
        char a = (char) r;//强转为字符型
        System.out.println(a);
    }
}

 这样读取每次指挥读取一个字符,效率太慢所以我们定义新的方法。

public class MyReader {
    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("E:/BBB/c.txt");
        int count=0;//记录妹子读取的个数
        char[] cs = new char[5];//定义char型数组,长度为5
        while ((count=reader.read(cs))!=-1){//读取指定目录里的5个元素放入char中,如果返回不等于-1执行循环
            String str = new String(cs,0,count);//将cs转为字符串型,从索引0的位置开始转,每次读取count个字符
            System.out.print(str);
        }
    }
}

2.3.使用字符流完成文件复制(先读取后写入):

public class Fuzhi {
    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("D:/AAA/p.txt");
        Reader reader = new FileReader("E:/BBB/o.txt");
        int count=0;
        char[] cs = new char[5];
        while ((count = reader.read(cs))!=-1){
            writer.write(cs,0,count);//写出cs,从0的位置开始,每次写count个字符
            writer.flush();//刷新流
        }
        writer.close();//关闭流
        reader.close();//关闭流
    }
}

3.字节输入输出流(InputStream/OutPutStream)

   3.1.概述:

  一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

   3.2.字节输出流(OutPutStream)

      写出数组型:

public class MyOutPutStream {
    public static void main(String[] args) throws IOException {
        //创建一个FileOutputStream对象, OutputStream 是一个抽象类,通过FileOutputStream实现
       OutputStream ops = new FileOutputStream("D:/AAA/uu.txt",true);//true表示可以续写,不会覆盖上次写的内容
       String str ="王五你好";
       //将字符串转为byte数组
       byte[] b = str.getBytes();
       ops.write(b);
       
       String str2 = "张三你好";
       byte[] b2 = str2.getBytes();
       ops.write(b2);
       
        ops.flush();//刷新流
        ops.close();//关闭流
    }
}

    写出字符型:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("D:/AAA/uu.txt");     
      	// 写出数据
      	fos.write(97); // 写出第1个字节
      	fos.write(98); // 写出第2个字节
      	fos.write(99); // 写出第3个字节
      	// 关闭资源
        fos.close();
    }
}
输出结果:
abc

     写出指定长度字节数组:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("D:/AAA/uu.txt");     
      	// 字符串转换为字节数组
      	byte[] b = "abcde".getBytes();
		// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
        fos.write(b,2,2);
      	// 关闭资源
        fos.close();
    }
}
输出结果:
cd

    3.3.字节输入流(InputStream)

     读取字节:

public class MyInputStream {
    public static void main(String[] args) throws IOException {
        InputStream ips = new FileInputStream("D:/AAA/y.txt");
        int read =  ips.read();//输出一个字节,返回int型
        System.out.println((char) read);//打印,将int型转为char型
        read = ips.read();
        System.out.println((char) read);
        read = ips.read();
        System.out.println((char) read);
        read = ips.read();
        System.out.println((char) read);
        read = ips.read();
        System.out.println(read);//内容读完后返回-1
        ips.close();//关闭流
    }
}
结果:
a
b
c
d
-1

     这样读取的效率比较第所以采用循环读取

      循环读取:

    @Test
    public void MyInputStram() throws IOException {
        InputStream ips = new FileInputStream("D:/AAA/y.txt");
        int count=0;//记录读取到的个数
        byte[] b = new byte[5];//定义一个byte型数组,长度5
        while ((count=ips.read(b))!=-1){//每次读取5个字节放入b中
            //将字节数组转为字符串型
            String str = new String(b,0,count);//读取b的内容,从0的位置开始,每次读取count个
            System.out.println(str);
        }
    }
结果:
abcd

3.4.使用字节流完成文件复制(先读取后写入):

public class FuZhi2 {
    public static void main(String[] args) throws IOException {
        OutputStream ops = new FileOutputStream("D:/AAA/y.txt");
        InputStream ips = new FileInputStream("E:/BBB/c.txt");
        int count = 0;
        byte[] b = new byte[5];
        while ((count=ips.read(b))!=-1){
            ops.write(b,0,count);
            ops.flush();
        }
        ops.close();
        ips.close();
    }
}

3.5.注意:

在使用字节流读取文本类内容时如果byte型数组设置的长度不够长可能会导致中文乱码。原因:一个中文字符占3个字节所以读取时读取一个字会占三个byte空间,循环读取时可能读取某一个字符时byte数组空间不够无法放入完整字符。所以建议读取文本内容时使用字符流。

4.缓冲流(Buffer)

  4.1.概述:

缓冲流,也叫高效流,是对4个基本的FileXxx 流的增强,所以也是4个流,按照数据类型分类:

字节缓冲流:BufferedInputStream,BufferedOutputStream
字符缓冲流:BufferedReader,BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

 4.2.创建:

// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
// 创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
// 创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));

 4.3.写入和读取(字节缓冲流)

public class MyBuffer {
    public static void main(String[] args) throws Exception{
        //写入
        OutputStream ops = new FileOutputStream("D:/AAA/p.txt");
        BufferedOutputStream bops = new BufferedOutputStream(ops,1);
        String str = "李四你好";
        byte[] b = str.getBytes();
        bops.write(b);
        bops.close();
        //读取
        InputStream ips = new FileInputStream("D:/AAA/p.txt");
        BufferedInputStream  biops = new BufferedInputStream(ips);
        int count=0;
        byte[] b2 = new byte[5];
        while ((count=biops.read(b2))!=-1) {
            String str1 = new String(b2,0,count);
            System.out.print(str1);
        }
    }
}

5.对象流/序列化流(Object)

  5.1.概述:

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。

   5.2.创建:

FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);

   5.3.序列化

一个对象要想序列化,必须满足两个条件:
1.该类必须实现java.io.Serializable 接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException 。
2.该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。

public class Employee implements java.io.Serializable {
    public String name;
    public String address;
    public transient int age; // transient瞬态修饰成员,不会被序列化
    public void addressCheck() {
      	System.out.println("Address  check : " + name + " -- " + address);
    }
}

写出对象:

public class SerializeDemo{
   	public static void main(String [] args)   {
    	Employee e = new Employee();
    	e.name = "zhangsan";
    	e.address = "beiqinglu";
    	e.age = 20; 
    	try {
      		// 创建序列化流对象
          ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.txt"));
        	// 写出对象
        	out.writeObject(e);
        	// 释放资源
        	out.close();
        	fileOut.close();
        	System.out.println("Serialized data is saved"); // 姓名,地址被序列化,年龄没有被序列化。
        } catch(IOException i)   {
            i.printStackTrace();
        }
   	}
}
输出结果:
Serialized data is saved

  5.4.反序列化

public class DeserializeDemo {
   public static void main(String [] args)   {
        Employee e = null;
        try {		
             // 创建反序列化流
             FileInputStream fileIn = new FileInputStream("employee.txt");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             // 读取一个对象
             e = (Employee) in.readObject();
             // 释放资源
             in.close();
             fileIn.close();
        }catch(IOException i) {
             // 捕获其他异常
             i.printStackTrace();
             return;
        }catch(ClassNotFoundException c)  {
        	// 捕获类找不到异常
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
        }
        // 无异常,直接打印输出
        System.out.println("Name: " + e.name);	// zhangsan
        System.out.println("Address: " + e.address); // beiqinglu
        System.out.println("age: " + e.age); // 0
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值