黑马笔记---IO流

IO流就是存储和读取数据的解决方案

I:input O:output 流:像水流一样传输数据

作用:用于读写数据(本地文件,网络)

分类:

何为纯文本文件

用windows系统自带的记事本打开并且能够读懂的文件

1.FileOutputStream

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中

书写步骤:1.创建字节输出流对象 2.写数据 3.释放资源

package IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class demo1 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileOutputStream fileOutputStream=new FileOutputStream("..\\JavaSE\\a.txt");
        //2.写出数据
        fileOutputStream.write(97);//输出a
        //3.释放资源
        fileOutputStream.close();
    }
}

细节:

创建对象

1.参数时字符串表示的路径或者时file对象都是可以的

2.如果文件不存在会创建一个新的文件,目录要保证父路径是存在的

3.如果文件已经存在,则会清空文件

4.续写,在对象后面添加一个true,开关默认为false关闭状态。

写数据

1.write方法的参数时整数,但是实际上写到本机文件的参数在ASCII上对应的字符

释放资源

每次使用完流之后都要释放资源。原因:解除资源的占用

1.1写的3种数据方式

package IO;

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

public class demo3 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileOutputStream fileOutputStream=new FileOutputStream("..\\JavaSE\\a.txt",true);
       //换行
        String s="\r\n";//换行的意思
        byte[] bytes = s.getBytes();
        fileOutputStream.write(bytes);

        String str="dsaads";
        byte[] bytes1 = str.getBytes();
        fileOutputStream.write(bytes1);

        String s1="\r\n";//换行的意思
        byte[] bytess = s1.getBytes();
        fileOutputStream.write(bytess);

        String str1="11sadas1";
        byte[] bytes2= str1.getBytes();
        fileOutputStream.write(bytes2);

        //续写

        //3.释放资源
        fileOutputStream.close();
    }
}

2.FileInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。

步骤:1.创建字节输入流对象 2.读数据 3.释放资源

package IO.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class inputDemo1 {
    public static void main(String[] args) throws IOException {
       //1.创建对象
        FileInputStream fileInputStream=new FileInputStream("..\\JavaSE\\a.txt");
        //2.读取数据
        for (int i = 0; i < 10; i++) {
            int b = fileInputStream.read();
            System.out.println((char) b);
        }

        //3.释放资源
        fileInputStream.close();;
    }
}

细节:

1.如果文件不存在,直接报错

2.一次读一个字节,读出来的数据在ASCII上对应的数字

3.读到文件末尾了,read方法返回-1.

2.1循环读取

package IO.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class inputDemo1 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fileInputStream = new FileInputStream("..\\JavaSE\\a.txt");
        //2.读取数据
        int b;
        while ((b = fileInputStream.read()) != -1) {
            System.out.print((char) b);
        }
        //3.释放资源
        fileInputStream.close();
        ;
    }
}

练习1:文件拷贝

package IO.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class inputDemo2 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fileInputStream=new FileInputStream("..\\JavaSE\\a.txt");
        FileOutputStream fileOutputStream=new FileOutputStream("..\\JavaSE\\cope.txt");
        //拷贝
        //边读边写
        long l = System.currentTimeMillis();


        int b;
        byte[]bytes=new byte[1024*1024*5];
        while ((b=fileInputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0,b);
        }

        fileOutputStream.close();
        fileInputStream.close();
        
       long end= System.currentTimeMillis();
        System.out.println(end-l);
    }
}

读取问题:

IO流:如果拷贝的文件过大,速度会很慢

原因:FileInputStream一次读写一个字节

2.2一次读取多个字节

一个读一个字节数组的数据,每次读取尽可能把数组装满

package IO.FileInputStream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class inputDemo3 {
    public static void main(String[] args) throws IOException {
        //1.创建对象
        FileInputStream fileInputStream=new FileInputStream("..\\JavaSE\\a.txt");
       byte[]bytes=new byte[2];//一次读取两个字节
        int r = fileInputStream.read(bytes);
        System.out.println(r);
        String str=new String(bytes,0,1);
        System.out.println(str);

        int r1 = fileInputStream.read(bytes);
        System.out.println(r1);
        String str2=new String(bytes,0,2);
        System.out.println(str2);


        int r2 = fileInputStream.read(bytes);
        System.out.println(r2);
        String str3=new String(bytes,0,3);
        System.out.println(str3);


        fileInputStream.close();
    }
}

2.3异常处理

finally:里面的代码一定会被执行,除非虚拟机停止

3.字符集

Unicode字符集是UTF-8编码格式

一个英文占一个字节,二进制第一位是0,转成十进制是正数

一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数

为什么会有乱码:

1.读取数据时未读完整个汉字

2.编码和解码时的方式不统一

如何不产生乱码:

1.不要用字节流读取文本文件

2.编码解码时使用同一个码表,同一个编码方式

Java中编码的方式

Java中解码的方式

package IO.charset;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.Arrays;

public class demo1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码
        String str="ai积极";
        byte[] bytes1 = str.getBytes();
        System.out.println(Arrays.toString(bytes1));

        byte[] gbks = str.getBytes("GBK");
        System.out.println(Arrays.toString(gbks));
        //解码
        String str2=new String(bytes1);
        System.out.println(str2);
        String str3=new String(bytes1,"GBK");
        System.out.println(str3);

    }
}

4.字符流

字符流的底层就是字节流

特点:

输入流:一次读一个字节,遇到中文时,一次读多个字节

输出流:底层会把数据按照指定的编码的编码方式进行编码,变成字节在写到文件中

使用场景:对于纯文本进行读写操作

4.1FileReader

1.创建字符输入流对象

2.读取数据

3.释放资源

4.2FileWiter

构造方法

1.创建字符输出流对象

        细节:参数是字符表示的路劲或者file对象都是可以的

         细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的

        细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关

2.写数据

        细节:如果writer方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符

3.释放资源

练习:加密文件和解密

package IO.MyText;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Text1 {
    public static void main(String[] args) throws IOException {
        //1.获取文件
        FileInputStream fileInputStream=new FileInputStream("..\\JavaSE\\cope.txt");
        FileOutputStream fileOutputStream=new FileOutputStream("..\\JavaSE\\copy.txt");
        int len;
        while ((len=fileInputStream.read())!=-1){
            fileOutputStream.write(len^2);
        }
        fileOutputStream.close();
        fileInputStream.close();
    }
}

5.高级流

5.1缓冲流

5.1.1字节缓冲流

原理:底层自带了长度为8192的缓冲区提高性能

package IO.MyText;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Text1 {
    public static void main(String[] args) throws IOException {
        //1.获取文件
        FileInputStream fileInputStream=new FileInputStream("..\\JavaSE\\cope.txt");
        FileOutputStream fileOutputStream=new FileOutputStream("..\\JavaSE\\copy.txt");
        int len;
        while ((len=fileInputStream.read())!=-1){
            fileOutputStream.write(len^2);
        }
        fileOutputStream.close();
        fileInputStream.close();
    }
}

5.1.2字符缓冲流

原理:底层自带了长度为8192的缓冲区提高性能

package IO.MyText;

import java.io.*;

public class Text2 {
    public static void main(String[] args) throws IOException {
//        //字符输入流
//        BufferedReader bufferedReader=new BufferedReader(new FileReader("..\\JavaSE\\a.txt"));
        String line=bufferedReader.readLine();
        System.out.println(line);

        String line1=bufferedReader.readLine();
        System.out.println(line1);
//
//        String line;
//        while((line=bufferedReader.readLine())!=null){
//            System.out.println(line);
//        }
//
//        bufferedReader.close();

        //字符输出流
        BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("b.txt" ,true));
        bufferedWriter.write("123");
        bufferedWriter.newLine();

        bufferedWriter.write("2344");
        bufferedWriter.newLine();
        bufferedWriter.close();
    }
}

5.2转换流

字符转换输入流:InputStreamReader

字符转换输出流:OutputStreamWriter

字符流和字节流之间的桥梁

作用1:指定字符集读写

作用2:字节流想要使用字符流中的方法

将文件中的GBK文件转成UTF-8

package IO.convteStream;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;

public class demo3 {
    public static void main(String[] args) throws IOException {
        FileReader fileReader=new FileReader("..\\JavaSE\\c.txt", Charset.forName("GBK"));
        FileWriter fileWriter=new FileWriter("..\\JavaSE\\e.txt",Charset.forName("UTF-8"));
        int c;
        while ((c=fileReader.read())!=-1){
            fileWriter.write(c);
        }
        fileWriter.close();
        fileReader.close();
    }
}

利用字节流,一次读取一行,中文不能出现乱码

package IO.convteStream;

import java.io.*;

public class demo4 {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream("..\\JavaSE\\a.txt")));
        String c;
        while ((c=bufferedReader.readLine())!=null){
            System.out.println(c);
        }
        bufferedReader.close();
    }
}

5.3序列化流

5.3.1对象操作输出流

可以把java中的对象写到本地文件中

细节:使用对象输出流将对象保存到文件时会出现NotSerializableException异常

解决方案:需要让Javabean类实现Serlizable接口

package IO.objeckStream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class demo1 {
    public static void main(String[] args) throws IOException {
        //创建对象
        student s=new student("zhangsan",18);
        //2.创建序列化流的对象
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\JavaSE\\a.txt"));
        oos.writeObject(s);
        oos.close();
    }
}
package IO.objeckStream;

import java.io.Serializable;

public class student implements Serializable {
    private String name;
    private int age;

    public student() {
    }

    public student(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;
    }
}

Serializable接口里面没有抽象方法,是一个标记型接口

实现了这个接口,代表当前的student类可以被序列化流

5.3.2对象操作输入流

可以把序列化搭配本地文件中的对象,读取到程序中来

package IO.objeckStream;

import Fuction.Student;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class demo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream oi=new ObjectInputStream(new FileInputStream("..\\JavaSE\\a.txt"));
        Student o = (Student) oi.readObject();
        System.out.println(o);
        oi.close();
    }
}

5.4打印流

PrinStream,PrinWriter两个类

特点1:打印流只操作文件目的地,不操作数据源

特点2:特有的写出方法可以实现,数据原样写出 例:打印:97 文件中:97

特点3:特有的写出方法,可以实现自动刷新,自动换行  打印一次数据=写出+换行+刷新

5.4.1字节打印流

字节流底层没有缓冲区,开不开自动刷新都一样

构造方法:

成员方法:

package IO.PrintStream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.nio.charset.Charset;

public class demo1 {
    public static void main(String[] args) throws FileNotFoundException {
        //1.c创建对象
        PrintStream ps=new PrintStream(new FileOutputStream("..\\JavaSE\\a.txt"),true, Charset.forName("UTF-8"));
        ps.println(97);
        ps.printf("%s爱上了%s","阿正","阿强");
        ps.close();
    }
}

5.4.2字符打印流

字符打印流底层有缓冲区,想要自动刷新需要开启

成员方法:

package IO.PrintStream;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class demo2 {
    public static void main(String[] args) throws IOException {
        PrintWriter printWriter=new PrintWriter(new FileWriter("..\\JavaSE\\a.txt"),true);
        printWriter.println(999);
        printWriter.printf("%s爱上了%s","阿正","阿强");
        printWriter.close();
    }
}

5.5解压缩流

5.5.1解压缩流

解压的本质:把每一个ZipEntry按照层级拷贝到本地另一个文件夹中

package IO.ZipStream;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class demo1 {
    public static void main(String[] args) throws IOException {
        //1.创建一个file表示要解压的压缩包
        File src=new File("D:\\learn\\JavaSE\\aaa.zip");
        //2.创建一个file表示解压的目的地
        File dest=new File("D:\\");
        upzip(src,dest);

    }
    //定义一个方法来解压
    public static void upzip(File src,File dest) throws IOException {
       //创建一个压缩流来读取压缩包中的数据
        ZipInputStream zipInputStream=new ZipInputStream(new FileInputStream(src));
        //获取压缩包里面的每一个zipentry对象
        ZipEntry entry;
        while((entry=zipInputStream.getNextEntry())!=null){
            System.out.println(entry);
            if(entry.isDirectory()){
                //文件夹:需要在目的地dest处创建一个同样的文件夹
                File file=new File(dest,entry.toString());
                file.mkdirs();
            }else {
                //文件:需要读取到压缩包的文件,并把它存放到目的地dest文件夹中
                FileOutputStream fos=new FileOutputStream(new File(dest,entry.toString()));
                int b;
                while ((b=zipInputStream.read())!=-1){
                    fos.write(b);
                }
                fos.close();
                zipInputStream.closeEntry();
            }
        }
    }
}

5.5.1压缩流

压缩包里面的每一个文件或者文件夹都是zipentry

压缩的本质:把每一个(文件/文件夹)堪称ZioEntry对象放到压缩包中

package IO.ZipStream;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class demo2 {
    public static void main(String[] args) throws IOException {
        //1.创建File对象表示要压缩的文件
        File src=new File("D:\\learn\\JavaSE\\aaa\\aaa\\aaa.txt");
        //2.创建file对象表示要存放的位置
        File dest=new File("D:\\");
        //3.调用方法来压缩
        tozip(src,dest);
    }
    public static void tozip(File src,File dest) throws IOException {
        //1.创建压缩流关联压缩包
        ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));
        //2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
        ZipEntry entry=new ZipEntry("a.txt");
        //3.把ZipEntry对象放到压缩包当中
        zos.putNextEntry(entry);
        //4.读写数据
        ZipInputStream zis=new ZipInputStream(new FileInputStream(src));

        int b;
        while ((b=zis.read())!=-1){
            zos.write(b);
        }
        zos.closeEntry();
        zos.close();

    }
}

6常用的工具

6.1Commons-io

Commons-io是apache开源基金组织提供的一组有关io操作的开源工具包

作用:提高io的开发效率

使用步骤

1.在项目中创建一个文件夹:lib

2.将jar包复制粘贴到lib文件夹

3.右键点击jar包,选择Add as Library->点击ok

4.在类中导包使用

方法:

package IO.Commons;

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.nio.charset.Charset;

public class demo1 {
    public static void main(String[] args) throws IOException {
//        File src=new File("..\\JavaSE\\txt.txt");
//        File dest=new File("..\\JavaSE\\copy.txt");
//        FileUtils.copyFile(src,dest);

//        File src=new File("D:\\learn\\JavaSE\\aaa");
//        File des=new File("D:\\bbb");
//        FileUtils.copyDirectoryToDirectory(src,des);

        File src=new File("..\\JavaSE\\txt.txt");
        FileUtils.readFileToByteArray(src);
    }
}

6.2Hutool

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值