Java中IO流的简单使用

IO

一、文件类

File类被定义为文件和目录路径名的抽象表示形式,这是因为File类既可以表示文件也可以表示目录,他们都通过对应的路径来描述。

通过构造函数创建一个File类对象,则该对象就是指定文件的引用,可以通过该对象对文件操作

//创建一个File类对象f,可通过f对temp.txt进行操作
File f = new File("D:\\temp.txt"); 

路径分隔符:

  • Windows下路径分隔符使用反斜线\,而Java程序中的反斜线表示转义字符,如果需要在Windows路径下使用反斜线,则应使用两条反斜线,如:C:\\mytest.txt
  • 使用斜线/,Java程序支持将斜线当成平台无关的路径分隔符

File类常见方法:

  • isHidden():判断是否是隐藏文件
  • canRead():是否可读
  • canWrite():是否可写
  • getPath():获取文件的路径
  • getAbsolutePath():获取文件的绝对路径
  • getName():获取文件名
  • isDirectory():是否是目录
  • isFile():是否是文件
  • mkdir():创建目录
  • lastModified():最后修改时间
  • length():文件长度
  • listFiles():返回目录下的所有文件和目录
public class Demo {
    /*
     * 	|---File类---文件和目录(文件夹)的抽象表示形式---File类将文件当成一个整体,不能对文件的内容进行操作,如果对文件的内容操作,需要使用IO流
     * 通过File类的对象和文件或目录建立关联,操作File类的对象,就是操作相应的文件或者目录
     *
     * */
    public static void main(String[] args) {
        //创建File类的对象  java.io....
        /*
         * 文件的路径有两种写法
         * C:\\Users\\Raymond\\Desktop\\test\\a.txt
         * C:/Users/Raymond/Desktop/test/a.txt
         *
         * \ 转义字符----和其后的第一个字符结合,表示特殊的含义    \n \t
         * 如果要表示\,必须写两条\
         *
         * */
        //File f = new File("C:\\Users\\Maxwell\\Desktop\\a.txt");
        File f = new File("D:/a.txt");

        //File类中常见的方法
        //判断文件是否是隐藏文件
        System.out.println("是否隐藏:" + f.isHidden());
        //大小  Byte
        System.out.println("文件的大小:" + f.length());
        //文件名
        System.out.println("文件名:" + f.getName());
        //绝对路径
        System.out.println("绝对路径:" + f.getAbsolutePath());
        //是否可读
        System.out.println("是否可读:" + f.canRead());
        //是否可写
        System.out.println("是否可写:" + f.canWrite());
        /*
         * 时间戳---->表示时间的字符串(xxxx年xx月xx日 xx:xx:xx)
         *
         * SimpleDateFormat
         * 		|
         * 	  Date()
         * 		|
         * 	       时间戳
         * 时间戳---->Date()
         * */
        //文件最后修改时间
        long lastMdate = f.lastModified();
        Date date = new Date(lastMdate);
        //Date---String
        SimpleDateFormat sft = new SimpleDateFormat("yyyy年MM月dd日  HH:mm:ss");
        String dateStr =  sft.format(date);
        System.out.println("最后修改时间:" + dateStr);

        //判断是否是文件夹
        System.out.println("是否是文件夹:" + f.isDirectory());

        File f1 = new File("D:/test123/");
        //判断文件或文件夹是否存在
        //System.out.println("是否存在:" + f1.exists());
        if(!f1.exists()) { //不存在创建该文件夹
            //创建文件夹  Linux mkdir
            f1.mkdir();
        }

        File[] fArr = f1.listFiles();
        for (File file : fArr) {
            System.out.println(file.getName());
        }
    }
}

File类中没有提供对文件的读写操作,如果要实现对文件的读写,需要通过IO流来进行操作。

案例:列出一个目录下所有的文件和目录(包括子目录中的目录和文件)

public class Demo{
    /*
     * f表示需要被遍历的文件夹
     * */
    public static void listFiles(File f) {
        File[] farr = f.listFiles();
        for(File subf : farr) {
            System.out.println(subf.getAbsolutePath());
            if(subf.isDirectory()) {
                listFiles(subf);
            }
        }
    }

    public static void main(String[] args) {
        File file = new File("D:/test123/");
        listFiles(file);
    }
}

二、IO

1.1概念

I/OInput/Output的缩写

  • :数据在存储设备和内存之间的传输通道
  • 数据借助流传输

2.2IO流分类

按照数据流流向不同

  • 输入流:将存储设备中的内容读到内存当中InputStreamReader
  • 输出流:将内存中的内容写入到存储设备中OutputStreamWriter

按照处理的数据单元不同

  • 字节流:以字节为单位,可以读写所有数据,InputStreamOutputStream
  • 字符流:以字符为单位,只能读写文本数据,ReaderWriter

按照功能不同

  • 节点流:具有实际传输数据的读写功能
  • 处理流(过滤流):就是在节点流的基础上增强功能

三、字节流

3.1字节抽象类

  • 字节输入流:InputStream

  • 主要方法:

    • read():从输入流中读取数据的下一个字节
    • read(byte[] b):从此输入流中将最多b.length个字节的数据读入一个byte数组中
    • read(byte[] b, int off,int len):将输入流中最多len个数据字节读入byte数组
    • close():关闭此输入流并释放与该流关联的所有系统资源
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //创建FileInputStream对象
        FileInputStream fis = new FileInputStream("a.txt");
        //使用read方法返回一个字节对应的Unicode码值
        //如果读到文件末尾没有值就返回-1
        //通过文件输入流进行操作
        System.out.println(fis.read());

        //read(byte[])一次读取缓冲区个字节,并将内容读入字节数组中,并返回读取长度
        //自定义缓冲区
        byte[] b = new byte[10];
        int len = fis.read(b);
        System.out.println(Arrays.toString(b));
        System.out.println(len);

        byte[] buf = new byte[50];
        int len1;
        len1=fis.read(buf,0,1024);
        System.out.println(Arrays.toString(buf));
        System.out.println(len1);

        //关闭资源
        fis.close();
    }
}

字节输出流OutputStream

主要方法:

  • write(int b):将指定的字节写入此输出流
  • write(byte[] b):将b.length个字节从指定的byte数组写入此输出流
  • write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此输出流
  • flush():刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标
  • close():关闭此输出流并释放与该流关联的所有系统资源
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //创建OutputStream对象
        FileOutputStream fos= new FileOutputStream("a.txt",true);
        //通过输出流写内容
        fos.write(65);
        fos.write(65);
        fos.write(65);

        //write(byte[] );向文件中写入一个字节数组 有内容
        //通过字节数组写内容
        byte[] b = "hello ,java ".getBytes();
        fos.write(b);

        
        byte[] b2 = "HHHH".getBytes();
        fos.write(b2,0,b2.length);
        
        //关闭资源
        fos.close();
        
    }
}

总结:

  1. 使用输出流时如果文件不存在会自动创建,但是要保证父目录的存在
  2. 使用输出流写内容的时,在构造方法改为true,表示在原有内容上追加(默认会覆盖原有内容)
  3. 将io操作写在try中,释放资源卸载finally中
  4. 新语法

四、缓冲流

4.1字节缓冲流

  • 根据数据操作单位可以把缓冲流分为:

    • BufferedInputStreamBufferedOutputStream
  • 提高IO效率,减少磁盘的访问次数

  • 数据存储在缓冲区中,flush将缓冲区的内容写入文件中,也可以直接close

import java.io.*;

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
/*
        //提高io效率,减少访问磁盘的次数
        //通过文件输入流创建一个缓冲输入流
        FileInputStream fis = new FileInputStream("a.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        byte[] b = new byte[1024];
        int len;
        while ((len=bis.read(b))!=-1){
            String str = new String(b,0,len);
            System.out.println(str);
        }
        bis.close();
        */


        //通过文件输出流创建一个缓冲输出流
        FileOutputStream fos = new FileOutputStream("c.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //fos.write();  这个是直接访问磁盘进行操作

        bos.write("aaa".getBytes());//还在缓冲区中
        bos.close();

    }
}

文件拷贝案例

import java.io.*;

public class CopyFileDemo {
    //文件拷贝案例
    public static void main(String[] args) throws Exception {
        //记录开始时间
        long start = System.currentTimeMillis();
        copy1();
        //计算结束时间
        long end = System.currentTimeMillis();
        //输出运行时间
        System.out.println(end-start);

    }
    public static void copy1() throws IOException {
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("b.txt");

        byte[] buf = new byte[1024];
        int len;
        while ((len=fis.read(buf))!=-1){//当读到返回值
            fos.write(buf,0,len);
        }
        fos.close();//后用的先关闭
        fis.close();
    }

    public static void copy2() throws Exception{
        //需要普通的流进行支持
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("b.txt");

        //创建缓冲流
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        byte[] buf = new byte[1024];
        int len;
        while ((len=bis.read(buf))!=-1){//当读到返回值
            fos.write(buf,0,len);
        }

        bos.close();//后用的先关闭
        bis.close();
        fos.close();
        fis.close();
    }
}

4.2字符缓冲流

  • 缓冲流BufferedReaderBufferedWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class BufferedWriterDemo01 {
    public static void main(String[] args) throws Exception{
/*
        //创建字符缓冲输入对象
        BufferedReader br = new BufferedReader(new FileReader("b.txt"));

        //br.readLine() 一次读取一行内容返回字符串 读到流的末尾就是null
        System.out.println(br.readLine());

        //通过字符缓冲流循环读取文件内容
        String line;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }
        //释放资源
        br.close();
        */
        
        
        //ch字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("e.txt"));
        
        //通过字符流写出内容
        bw.write("aaaaaa");
        
        //释放资源
        bw.close();

    }
}
使用缓冲流实现文件拷贝
import java.io.*;

public class CopyBufferedDemo {
    public static void main(String[] args) throws Exception {
        BufferedReader fr = new BufferedReader(new FileReader("d.txt"));
        BufferedWriter fw = new BufferedWriter(new FileWriter("e.txt"));

        char[] ch = new char[1024];
        int len = 0;
        while ((len = rd.read(ch)) != -1) {
            wr.write(ch, 0, len);
        }

        fw.close();
        fr.close();
        //只有纯文本才能使用字符流
    }
}

五、对象流

  • ObjectOutputStreamObjectInputStream
  • 增加了缓冲区功能
  • 增加了读写八种基本数据类型和字符串功能
  • 增加了读写对象的功能
    • readObject()从流中读取一个对象
    • writeObject()向流中写入一个对象
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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

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

public class ObjectDemo01 {
    public static void main(String[] args) throws Exception{
/*
      //创建文件输出流
        FileOutputStream fos = new FileOutputStream("d.txt");
        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //创建学生对象
        Student stu = new Student("aaa", 20);
        //通过对象流讲对象写入到d.txt
        //NotSerializableException 为序列化异常
        oos.writeObject(stu);
        //释放资源
        oos.close();
        fos.close();

*/

        //创建对象输入流
        FileInputStream fis = new FileInputStream("d.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);

        //通过对象流读取d.txt中的对象
        Object stu =  ois.readObject();
        System.out.println(stu);

        //释放资源
        ois.close();
        fis.close();


    }
}

注意事项:

  • NotSerializableException 为序列化异常

  • 序列化:讲对象编程可以读写的字节序列

  • 反序列化:将字节序列变成java对象

  • 如何解决这个问题:实现序列化接口 Serializable

  • 对象流使用细节:

    1. 对象流读取完数据会抛出异常EOFEException

    2. 序列化ID作用是:保证序列化安全

    3. transient修饰的属性不会被序列化

    4. 对象流提供了一些直接读写的基本类型+String方法

案例(模拟注册):

package IODemo03;

public class User {
    private String userName;
    private String passWord;

    public User() {
    }

    public User(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", passWord='" + passWord + '\'' +
                '}';
    }
}

import java.io.*;
import java.util.ArrayList;

public class ObjectDemo02 {
    public static void main(String[] args) throws Exception {
        //对象流读写集合

        //注册
        User user = new User("admin", "123");
        ArrayList<User> userList = new ArrayList<>();

        File file = new File("user.obj");
        if(!file.exists()){//表示第一次注册
            userList.add(user);
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"));
            oos.writeObject(userList);
            oos.close();
        }else{
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"));
            userList = (ArrayList<User>)ois.readObject();

            //判断用户是否存在
            if(true) {
                //略 存在就返回出去
            }
            //不存在就返回
            userList.add(user);
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"));
            oos.writeObject(userList);
            oos.close();

        }
    }

六、字符流

6.1字符抽象类

  • 字符输入流:Reader
  • 字符输出流:Writer

6.2字符输入流用法

import java.io.FileReader;

public class Demo01 {
    public static void main(String[] args) throws Exception{
        //创建字符文件输入流对象
        FileReader fr = new FileReader("a.txt");

        //通过字符输入流读取内容
        //read() 一次读取一个字符返回这个字符对应的Unicode码
        //读到流的末尾会返回-1
        System.out.println(fr.read());
        System.out.println(fr.read());
        System.out.println(fr.read());
        System.out.println(fr.read());

/*        
        //read(cbud,offset,count)一次读取缓冲区个字符读到字符数组中,并返回读取的长度
        //读到末尾返回-1
      char[] cbuf = new char[1024];
        int len;
        while ((len=fr.read(cbuf))!=-1){
            String str = new String(cbuf,0,len);
            System.out.println(str);
        }
    */
        //read(cbud,offset,count)一次读取缓冲区个字符读到字符数组中,并返回读取的长度
        //读到末尾返回-1
        //可以指定读到缓冲区数组下标指定的位置,指定读取字符个数
        char[] cbuf = new char[1024];
        fr.read(cbuf,2,2);
        fr.close();

    }
}

6.3字符输出流用法

import java.io.FileWriter;

public class Demo02 {
    public static void main(String[] args) throws Exception {
        //创建字符文件输出流对象
        FileWriter fw = new FileWriter("b.txt",true);

        //通过字符流写出内容
        fw.write("hello,word");

        //释放资源
        fw.close();
    }
}

七、转换流

import java.io.*;

public class Demo01 {
    public static void main(String[] args) throws Exception{

/*
        //将字节输入流转换成字符输出流
        FileInputStream fis = new FileInputStream("a.txt");

        InputStreamReader isr = new InputStreamReader(fis);

        BufferedReader br = new BufferedReader(isr);

        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
        isr.close();
        fis.close();
      */

        //zhi'd
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("e.txt"),"GBK"));

        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }

        br.close();

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值