IO流

File类的使用

File类的理解:

  1. File类的一个对象,代表一个文件或者一个文件目录
  2. File类声明在java.io包下
  3. File类中涉及到的关于文件或者文件目录的创建、删除、重命名、修改时间、文件大小等方法

File的实例化:

  1. 常用构造器
File(String filePath)
File(String parentPath,String childPath)
File(File parentFile,String childPath)
  1. File类常用方法
public String getAbsolutePath()获取绝对路径
public String getPath()获取路径
public String getName()获取名称
public String getParent()获取上层文件目录路径。若无,返回null
public long length()获取文件长度(即:字节数),不能获取目录的长度
public long lastModified()获取最后一次的修改时间,毫秒值
public String[] list()获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles()获取指定目录下的所有文件或者文件目录的File数组
public boolean renameTo(Filedest)把文件重命名为指定的文件路径
public boolean isDirectory()判断是否是文件目录
public boolean isFile()判断是否是文件
public boolean exists()判断是否存在
public boolean canRead()判断是否可读
public boolean canWrite()判断是否可写
public boolean isHidden()判断是否隐藏
public boolean createNewFile()创建文件,若文件存在,则不创建,返回false
public boolean mkdir()创建文件目录。如果此文件目录存在,就不创建了.如果此文件目录的上层目录不存在,也不创建
public boolean mkdirs()创建文件目录。如果上层文件目录不存在,一并创建注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目路径下
public boolean delete()删除文件或者文件夹,Java中的删除不走回收站。要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
  1. 例题:输出所有文件
public class FileDemo {
    public static void main(String[] args) {
        File file = new File("F:\\数据结构");
        int size = showFile(file);
        System.out.println(size);
    }
    private static int showFile(File file) {
        int size = 0;
        if(file.isFile()){
            System.out.println(file.getName());
            size += file.length();
        }else{
            File[] files = file.listFiles();
            for(File f : files){
                if(f.isFile()){
                    System.out.println(f.getName());
                    size += f.length();
                }else {
                    showFile(f);
                }
            }
        }
        return size;
    }
}

FileReader和FileWriter

流的分类

  1. 操作数据单位:字节流、字符流
  2. 数据的流向:输入流、输出流
  3. 流的角色:节点流、处理流
    在这里插入图片描述

流的体系结构
在这里插入图片描述
输入、输出的标准化过程
输入过程:

  1. 创建File类的对象,指明读取的数据的来源(要求此文件一定要存在)
  2. 创建相应的输入流,将File类的对象作为参数,传入流的构造器中
  3. 具体的读入过程,创建相应的byte[]char[]
  4. 关闭流资源

输出过程:

  1. 创建File类的对象,指明写出的数据的位置(不要求此文件一定要存在)
  2. 创建相应的输出流,将File类的对象作为参数,传入流的构造器中
  3. 具体的写出过程,调用write()
  4. 关闭流资源

FileReader的使用:

  1. read()理解:返回读入的一个字符。如果达到文件末尾,返回-1
  2. 异常处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally处理
 public void testFileReader() {
     //1.实例化File类的对象,指明要操作的文件
     File file = new File("hello.txt");
     //2.提供具体的流
     FileReader fileReader = new FileReader(file);
     //3.数据读入
     //使用read(char[] cbuf);
     char[] chars = new char[5];
     int len;
     while((len = fileReader.read(chars)) != -1){
         for (int i = 0; i < len; i++) {
             System.out.print(chars[i]);
         }
     }
     //4.流的关闭
	fileReader.close();
}

FileWriter的使用:

  1. 输出操作,对应的File可以不存在的。并不会报异常
  2. File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
  3. File对应的硬盘中的文件如果存在:如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的覆盖;如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容
public void testFileWriter() throws IOException {
   //1. 提供File类的对象,指明写出到的文件
    File file = new File("hi.txt");

    //2. 提供FileWriter的对象,用于数据的写出
    FileWriter fileWriter = new FileWriter(file,true);

    //3. 写出的操作
    String str = "1111";
    fileWriter.write(str);
    //4.资源流关闭
    fileWriter.close();
}

文本文件的复制

public void testCopyFile(){
    //从hello中读
    File file1 = new File("hello.txt");
    //将读的写到hello1中
    File file2 = new File("hello1.txt");
    //读写操作
    FileReader fileReader = new FileReader(file1);
    FileWriter fileWriter = new FileWriter(file2);
    char[] cbuf = new char[5];
    int len;
    while((len = fileReader.read(cbuf)) != -1){
        fileWriter.write(cbuf,0,len);
    }
    if (fileWriter != null){
    	fileWriter.close();
    }
    if (fileReader != null) {
        fileReader.close();
    }
}

InpuStream和OutputStream

 public void copyFile(String src,String dest){
    File file1 = new File(src);
    File file2 = new File(dest);
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try{
        fis = new FileInputStream(file1);
        fos = new FileOutputStream(file2);
        int len;
        byte[] buffer = new byte[1024];
        while((len = fis.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (fos != null){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fis != null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

缓冲流

缓冲流涉及到的类:

  1. BufferedInputStream
  2. BufferedOutputStream
  3. BufferedReader
  4. BufferedWriter

作用:提高流的读取、写入的速度(原因是内部提供了一个缓冲区)
在这里插入图片描述
BufferedInputStreamBufferedOutputStream使用:

public void copyFile(String src,String dest){
    File file1 = new File(src);
    File file2 = new File(dest);
    FileInputStream fis = null;
    FileOutputStream fos = null;
    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try{
        fis = new FileInputStream(file1);
        bis = new BufferedInputStream(fis);
        fos = new FileOutputStream(file2);
        bos = new BufferedOutputStream(fos);
        int len;
        byte[] buffer = new byte[1024];
        while((len = bis.read(buffer)) != -1){
            bos.write(buffer,0,len);
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(bos != null){
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(bis != null){
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedReaderBufferedWriter的使用

public void testBufferedReaderWriterTest(){
   BufferedReader br = null;
    BufferedWriter bw = null;

    try {
        br = new BufferedReader(new FileReader("dbcp.txt"));
        bw = new BufferedWriter(new FileWriter("dbcp1.txt"));

        char[] buffer = new char[1024];
        int len;
        while((len = br.read(buffer)) != -1){
            bw.write(buffer,0,len);
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (bw != null) {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

转换流

转换流涉及到的类:

  1. InputStreamReader:将一个字节的输入流转换成字符的输入流
  2. OutputStreamWriter:将一个字符的输出流转换成字节的输入流

在这里插入图片描述
常见编码集:

ASCII美国标准信息交换码。用一个字节的7位可以表示
ISO8859-1拉丁码表。欧洲码表 ,用一个字节的8位表示
GB2312中国的中文编码表,最多两个字节编码所有字符
GBK中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
Unicode国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的 字符码。所有的文字都用两个字节来表示
UTF-8变长的编码方式,可用1-4个字节来表示一个字符
public void testInputStreamReader() {
    InputStreamReader isr = null;
    try {
        FileInputStream fis = new FileInputStream("dbcp.txt");

        isr = new InputStreamReader(fis,"UTF-8");

        char[] cbuf = new char[5];
        int len;
        while((len = isr.read(cbuf)) != -1){
            for (int i = 0; i < len; i++) {
                System.out.print(cbuf[i]);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (isr != null) {
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

其他流的使用

标准输入输出流:

  1. System.in:标准的输入流,默认从键盘输入
  2. System.out:标准输出流,默认从控制台输出
  3. 修改默认的输入和输出行为:使用System类的SetIn(InputStream is) / SetOut(PrintStream ps)方式指定输入和输出的流
public static void main(String[] args) {
    BufferedReader br = null;
    try {
        InputStreamReader isr = new InputStreamReader(System.in);
        br = new BufferedReader(isr);

        while (true) {
            System.out.println("请输入字符串:");
            String data = br.readLine();
            if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
                System.out.println("程序结束");
                break;
            }

            String upperCase = data.toUpperCase();
            System.out.println(upperCase);

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

        }
    }
}

打印流

public void test2() {
    PrintStream ps = null;
    try {
        FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
        // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
        ps = new PrintStream(fos, true);
        if (ps != null) {// 把标准输出流(控制台输出)改成文件
            System.setOut(ps);
        }
        for (int i = 0; i <= 255; i++) { // 输出ASCII字符
            System.out.print((char) i);
            if (i % 50 == 0) { // 每50个数据一行
                System.out.println(); // 换行
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ps != null) {
            ps.close();
        }
    }
}

数据流

public void test3() throws IOException {
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
    dos.writeUTF("刘建辰");
    dos.flush();//刷新操作,将内存中的数据写入文件
    dos.writeInt(23);
    dos.flush();
    dos.writeBoolean(true);
    dos.flush();
    dos.close();
}
public void test4() throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
    String name = dis.readUTF();
    int age = dis.readInt();
    boolean isMale = dis.readBoolean();
    System.out.println("name = " + name);
    System.out.println("age = " + age);
    System.out.println("isMale = " + isMale);
    dis.close();
}

对象流

对象流

  1. ObjectOutputStream:内存中的对象 --> 存储中的文件、通过网络传输出去
  2. ObjectInputStream:存储中的文件、通过网络接收过来 --> 内存中的对象

对象的序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其他程序获取了这种二进制流,就可以恢复成原来的Java对象

实现序列化对象所属类需要满足的 要求

  1. 需要实现接口:Serializable
  2. 当前类提供一个全局常量:serialVersionUID
  3. 除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的(默认情况下,基本数据类型可序列化)
  4. ObjectOutStreamObjectInputStream不能序列化statictransient修饰的成员变量
//序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
public void testObjectOutputStream(){
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
	oos.writeObject(new String("我爱北京天安门"));
	oos.flush();//刷新操作
	oos.writeObject(new Person("王铭",23));
	oos.flush();
	oos.writeObject(new Person("张学良",23,1001,new Account(5000)));
	oos.flush();
	oos.close();
}
//反序列化:将磁盘文件中的对象还原为内存中的一个java对象
public void testObjectInputStream(){
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.dat"));
	Object obj = ois.readObject();
	String str = (String) obj;
	Person p = (Person) ois.readObject();
	Person p1 = (Person) ois.readObject();
	System.out.println(str);
	System.out.println(p);
	System.out.println(p1);
	ois.close();
}

RandomAccessFile

特点:

  1. RandomAccessFile直接继承于java.lang.Object类,实现了DataInputDataOutput接口
  2. RandomAccessFile即可以作为一个输入流,又可以作为一个输出流
  3. 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。如果写出到的文件存在,则会对源文件内容进行覆盖(默认情况下是从头覆盖)
  4. 可以通过相关的操作,使用RandomAccessFile实现"插入"数据的效果
//使用RandomAccessFile实现数据的插入效果
@Test
public void test3() throws IOException {
    RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");
    raf1.seek(3);//将指针调到角标为3的位置
    //保存指针3后面的所有数据到StringBuilder中
    StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
    byte[] buffer = new byte[20];
    int len;
    while((len = raf1.read(buffer)) != -1){
        builder.append(new String(buffer,0,len)) ;
    }
    //调回指针,写入“xyz”
    raf1.seek(3);
    raf1.write("xyz".getBytes());
    //将StringBuilder中的数据写入到文件中
    raf1.write(builder.toString().getBytes());
    raf1.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值