IO流

JAVA学习网 2020-11-15 14:35:06

学习IO流知识梳理:

字节流

一些注意点:

英文 1字节

中文 gbk utf-8 2字节、3字节

相对路径———项目下寻找

File

❑ File类:文件和目录路径名的抽象表现形式

❑ 作用:通过File对象实现对文件或者文件夹的操作 ❑ 常用构造方法:

❑File(String URL)

❑ 常用方法: ❑String getName() --- 获取当前文件对象的名字

❑long length() --- 获取文件对象的大小 单位:字节

❑boolean isFile()/isDirectory()--- 判断文件/文件夹

❑boolean canRead()/canWrite()--- 判断文件可读/可写

❑boolean isHidden() --- 判断file对象是否为隐藏

❑long lastModified() --- 获取当前file对象最后修改时间

public class TestFile02 {
    public static void main(String[] args) {
//      test01();
//      test02();
        
        File file = new File("A");
        test03(file);
​
    }
​
    private static void test03(File file) {
        if(file.isDirectory()) {
            //如果是文件夹,遍历
            File[] files = file.listFiles();
            for (File file2 : files) {
                //继续判断文件类型
                test03(file2);
            }
            //删除空的文件夹
            file.delete();          
            
        }else {
            //只要是文件,直接删除
            file.delete();
        }
    }
​
    private static void test02() {
      File file = new File("test01.txt");   
      System.out.println(file.exists());
      
      if(!file.exists()) {
         
          try {
            file.createNewFile(); //创建文件
        
              
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      }
      
      
      File file2 = new File("A");
      if(!file2.exists()) {
          //创建文件夹
//        file2.mkdir();//只能创建单层文件夹
          file2.mkdirs();//创建多层文件夹
      }
      
      //删除文件或者文件夹
      //删除文件的时候,不管有没有内容都会删除
      //删除文件夹的时候,只能删除空文件夹
//    file.delete();
      file2.delete();
      
      //获取子文件
      File[] files = file2.listFiles();
      System.out.println(files);
      for (File file3 : files) {
        System.out.println(file3);
    }     
    }
​
    private static void test01() {
        // 相对路径:从项目底下去找
        // 绝对路径:从盘符去找
// File file = new File("src\\cn\\goktech\\test02.txt");
        File file = new File("D:" + File.separator + "源码\\龙岩实训\\LYSE进阶01\\src\\cn\\goktech\\test03.txt");
        System.out.println(file);
        // 获取绝对路径
        System.out.println(file.getAbsolutePath());
        // 判断文件是否存在
        System.out.println(file.exists());
        // 获取文件名
        System.out.println(file.getName());
        // 获取文件大小
        System.out.println(file.length());
        // 判断是否是文件/文件夹
        System.out.println(file.isFile());
        System.out.println(file.isDirectory());
        // 判断可读
        System.out.println(file.canRead());
        // 判断可写
        System.out.println(file.canWrite());
        // 判断是否隐藏
        System.out.println(file.isHidden());
        // 获取最后的修改时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(new Date(file.lastModified()));
        System.out.println(time);
​
    }
​
}

 

 

File类常用方法

➢ 常用变量:File.separator –目录分隔符(/)

➢ 常用方法: • boolean exists() -- 判断文件是否存在

• void createNewFile() -- 创建新文件

• void mkdir()/mkdirs() – 创建新文件夹

• delete() – 删除文件或者文件夹

• File[] listFiles() – 获取当前文件夹下所有的子项,如果当前文件下为空则返回null值

FileFilter和FilenameFilter

❑ 文件过滤器 来获取一个目录下 满足条件的部分子选项(即只获取文件或只获取 目录)

❑ 文件过滤器更多是被用于listFiles(FileFilter filter)的参数中。

❑ FileFilter接口: public boolean accept(File pathname)

❑ FilenameFilter接口: public boolean accept(File dir, String name)

public class TestFilter03 {
    public static void main(String[] args) {
        File file = new File("D:\\工作\\授课\\龙岩实训");
//      File[] files = file.listFiles(new FileFilter() {
//          
//          @Override
//          public boolean accept(File pathname) {
////                System.out.println(pathname);
//              return pathname.getName().endsWith(".xlsx");
//          }
//      });
        
        File[] files = file.listFiles(new FilenameFilter() {
            
            @Override
            public boolean accept(File dir, String name) {
//              System.out.println(dir);
//              System.out.println(name);
                return name.endsWith("xlsx");
            }
        });
        
        for (File file2 : files) {
            System.out.println(file2);
        }
    }
​
}

  

RandomAccessFile类

➢ RandomAccessFile支持访问文件随机的读入和读取 ➢ 构造函数: • RandomAccessFile(File file , String mode) • RandomAccessFile(File file , String mode) 参数说明: 1、第一个参数:要访问的文件对象/文件路径 2、第二个参数:读写模式(r:只读模式;rw:可读可写) • 常用方法: ◆ read() – 从此文件中读取一个数据字节 ◆ write(int b) – 向此文件中写入指定的字节 ◆ read()和write()都有多个重载的方法,详见API 写入字符串乱码- - 转。g e t B y t e

Byte[] b = new Byte[2];
read(b) 一丛读取多少
syso.....(new Strng(bt))转中文

RandomAccessFile类

➢ 利用RandomAccessFile类提供的方法可以进行对文件指针的操作 ➢ 方法说明: • long getFilePoint():获取该文件当前的指针位置 • void seek(long pos):该方法允许我们将指针移动到指定位置 • 常用地方: ◆ 结合多线程对文件进行多点复制(迅雷下载)

public class TestRandomAccessFile04 {
    public static void main(String[] args) {
        
        File file = null;
        RandomAccessFile raf = null;
        try {
            file = new File("test01.txt");
            raf = new RandomAccessFile(file, "rw");
            //写数据
            raf.write(65);
            raf.write(65);
            raf.write(65);
//          raf.writeUTF("国科科技");
            
            //先将字符串转成字节数组
            raf.write("国科科技".getBytes());
            //获取指针位置
            System.out.println(raf.getFilePointer());
            //设置指针位置
            raf.seek(3);
            System.out.println(raf.getFilePointer());
            
            //读数据(当读到文件末尾返回-1)
//          System.out.println((char)raf.read());
//          System.out.println((char)raf.read());
//          System.out.println((char)raf.read());
            //可以利用以一次性读多个字节读取中文
//          byte[] bt = new byte[4];
//          System.out.println(raf.read(bt));
//          System.out.println(new String(bt));
            
            byte[] bt = new byte[1024];
            int i= 0;
            while((i=raf.read(bt))!=-1) {
                System.out.println(new String(bt,0,i));
            }
        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if (raf != null) {
                try {
                    raf.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }
    }
}
​

  

 

InputStream类(字节输入流)

❑ 抽象类 以字节为基本单元

InputStream方法

 

FileInputStream

作用:从实际磁盘中读取文件的内容,从文件系统中的某个文件获得输入字节 (*用于读取图像数据之类的原始字节流) ➢ 构造方法 • FileInputStream(File file) • FileInputStream(String name)

OutputStream

 

FileOutputStream

❑ 把流写入到文件。 ❑ 构造方法 FileOutputStream(File file) FileOutputStream(File file, boolean append) FileOutputStream(String name) FileOutputStream(String name, boolean append) append:如果文件已经存在,append=true表示往文件追加内容,否则会覆盖 文件。 ❑ 举例:拷贝文件

public class TestInAndOut {
    public static void main(String[] args) {
        File file = new File("test02.txt");
//      testInputStream(file);
//      testOutputStream(file);
        testCopy();
    }
​
    private static void testCopy() {
        InputStream in = null;
        OutputStream out = null;
        try {
            long start = System.currentTimeMillis();
            in = new FileInputStream("头饰.png");
            out = new FileOutputStream("copy.png");
            int i = 0;
            byte[] bt = new byte[1024];
            while((i=in.read(bt))!=-1) {
                out.write(bt);
            }
            System.out.println("复制完成....");
            long end = System.currentTimeMillis();
            System.out.println(end-start);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
​
    private static void testInputStream(File file) {
        //输入流:从文件读取到系统内存
        InputStream in = null;
        try {
            in = new FileInputStream(file);
//          System.out.println(in.read());
            byte[] bt = new byte[1024];
            int i= 0;
            while((i=in.read(bt))!=-1) {
                System.out.println(new String(bt,0,i));
            }
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
​
    private static void testOutputStream(File file) {
        //输出流:从系统内存写入到文件
        OutputStream out = null;
        try {
            //append:true表示追加
            out = new FileOutputStream(file,true);
            
            out.write(65);
            out.write(65);
            out.write(65);
            out.write(65);
            out.write(65);
            out.write("国科科技".getBytes());
            System.out.println("写入完成。。。。");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
​
}

  

 

流的套接

❑ 流类可以分为 ❑底层流 包含以字节的形式读写的方法 ❑高层过滤器流 用于读写高层信息 ❑ 高层流要求底层流作为基础 ❑ 常用高层字节流: ❑DataInputStream ❑BufferedInputStream ❑ObjectInputStream

高级(过滤)流

❑ FilterInputStream/FilterOutputStream 类的子类包括

• DataInputStream/DataOutputStream ◆ DataInputStream和DataOutputStream提供多种多样的readxxx和writexxx方法是对多种数据的读写。 • BufferedInputStream/BufferedOutputStream ◆ 缓冲字节输入/输出流为InputStream/OutputStream对象增加了缓冲区功能,利用缓冲流可以增 加字节读写的速率,提升应用程序的性能 • PushbackInputStream/PushbackOutputStream

DataInputStream/DataOutputStream

❑ 提供读取/写入多种数据的能力 readXXX();writeXXX() ❑ 构造方法 DataInputStream(InputStream in) DataOutputStream(OutputStream out) ❑ DatainputStream/DataOutputStream中文乱码问题 ❑数据流如果用read/write方法读写中文,有可能会出现乱码问题,解决方法: ❑ String构造方法可以指定对byte数组做其他编码方式的解码,如 new String(bytes,”gbk”);同 时也可以使用readUTF和writeUTF方法解决乱码问题

public class TestData05 {
    public static void main(String[] args) {
        File file = new File("test01.txt");
//      testWrite(file);
        testRead(file);
    }
​
    private static void testRead(File file) {
        InputStream in = null;
        DataInputStream dis = null;
        try {
            in = new FileInputStream(file);
            dis = new DataInputStream(in);
            System.out.println(dis.readChar());
            System.out.println(dis.readUTF());
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
​
    private static void testWrite(File file) {
        DataOutputStream dos = null;
        OutputStream out = null;
        try {
            //创建字节输出流
            out = new FileOutputStream(file);
            //创建高级流,将普通流添加进去
            dos = new DataOutputStream(out);
            dos.writeChar('国');
            dos.writeUTF("龙岩学院");
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
​
}
 

  

BufferedInputStream/BufferedOutputStream

➢ 缓冲输入/缓冲输出 ➢ BufferedInputStream支持 mark 和 reset 方法 ➢ 构造方法: • BufferedInputStream(InputStream in) • BufferedInputStream(InputStream in, int size) ➢ 常用方法: • read(bytes[] b,int offset,int length) ◆ 第一个参数:构建缓冲区数组 ◆ 第二个参数:读取文件的起始位置 ◆ 第三个参数:每次读取文件的长度 • mark方法和reset方法 ◆ mark(int readlimit):在输入流的当前位置做标记,配合reset方法的后续调用将此流重新定位在最后标记的位置上,以便后续读取操作重新读取相同的字节 ◆ reset():将此流重新定位到对此输入流最后使用mark方法时的位置

BufferedOutputStream

➢ BufferedOutputStream常用方法: • flush():这是每个输出流都有的方法,作用为刷新此输出流 • write(bytes[] b,int offset,int length): ◆ 第一个参数:构建缓冲区数组 ◆ 第二个参数:写入文件的起始位置 ◆ 第三个参数:每次写入文件的长度 • write(int b):将指定字节b写入此缓冲的输出流中

PrintStream

➢ 方便地打印各种数据值表示形式 ➢ 与其他输出流不同,PrintStream 不会抛出 IOException;而是,异常情况仅设 置可通过 checkError 方法测试的内部标志。 ➢ 支持自动刷新;这意味着可在写入字节数组之后自动调用 flush 方法,可调用其 中一个 println 方法,或写入一个新行字符或字节 (‘\n’)。

public class TestBuffer06 {
    public static void main(String[] args) {
        File file = new File("test01.txt");
//      testWrite(file);
        testRead(file);
    }
​
    private static void testRead(File file) {
        InputStream in = null;
        BufferedInputStream bis = null;
        try {
            in = new FileInputStream(file);
            bis = new BufferedInputStream(in);
            int i = 0;
            byte[] bt = new byte[1024];
            while((i=bis.read(bt))!=-1) {
                System.out.println(new String(bt,0,i));
            }
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
​
    private static void testWrite(File file) {
        OutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            out = new FileOutputStream(file);
            bos = new BufferedOutputStream(out);
            
            bos.write("福建国科信息科技有限公司".getBytes());
            //刷新
            bos.flush();
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                bos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
​
}
 

  

字符流

配置文件

❑ 是一个文件,后缀一般为ini、properties或者xml文件

❑ 作用:用户登录时定义加载环境所需的设置和文件的集合

❑ 格式 键=值 ...... ➢ 例如 user=qq password=123456

 

读取配置文件
FileInputStream fis = new FileInputStream(“config.ini”);
Properties prop = new Properties();
//从文件中加载配置
prop.load(fis);
//根据键名取值
String user = prop.getProperty(“user”);
www.goktech.cn
10
修改并保存配置到文件
//修改健名为user的健值admin,如果健名不存在,
//则新增。
prop.setProperty("user", "admin");
...
//把prop里的健值对保存到文件config.ini
FileOutputStream fos = new FileOutputStream("config.ini");
prop.store(fos, “备注”);

  


 

Reader

FileReader

➢ 使读取字符文件成为可能

➢ 构造方法 • FileReader(File file) • FileReader(String fileName)

BufferedReader

➢ 从字符输入流中读取文本,缓冲各个字符,从而提供单个字符、数组和字符串的 高效写入。

➢ 构造方法:BufferedReader(Reader r) ➢ readLine() 从流中读一行

Writer

FileWriter

➢ 允许将字符类型数据写入文件

➢ 构造方法 ➢ FileWriter(File file); ➢ FileWriter(String fileName);

BufferedWriter

❑ 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高 效写入。 ❑ newLine() ❑ write(String s, int off, int len) ❑ 除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可 能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如, PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

字节流和字符流转换

➢ InputStreamReader 把字节输入流转换成字符流

➢ OutputStreamWriter 把字符流写到字节流

➢ 例子:用字节流打开文件,然后转成字符流 FileInputStream fis = new FileInputStream("e:/student.c"); InputStreamReader isr = new InputStreamReader(fis);

获取键盘输入

//System.in是键盘输入流 //把键盘输入转成字符流 InputStreamReader isr = new InputStreamReader(System.in); //用缓冲字符流封装,以允许读一行 BufferedReader br = new BufferedReader(isr); //从键盘读取一行 String line = br.readLine();

public class test {
​
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        File file = new File("text.text");
        
        test01(file);
        test02(file);
    }
​
    private static void test02(File file) {
        // TODO Auto-generated method stub
        OutputStream os= null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            os = new FileOutputStream(file);
            osw = new OutputStreamWriter(os,"utf-8");
            osw.write("三好学生");
            
            bw =new BufferedWriter(osw);
            bw.write("全额奖学金");
            bw.flush();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
​
    private static void test01(File file) {
        //字节流字符流转换
        //注意文件的编码格式。如果不相同会产生乱码。可以转字节流
        //将字节的输入流转换成字符输入流
        InputStream in = null;
        InputStreamReader isr = null;
        BufferedReader br =null;
        try {
            in = new FileInputStream(file);
            isr = new InputStreamReader(in,"utf-8");//可以指定读取的编码格式
            System.out.println((char)isr.read());//不指定采用系统的编码格式
            
            //也可以使用缓冲流
            br = new BufferedReader(isr);
            System.out.println(br.readLine());
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
​
}
private static void testSystem() {
        //高级流可以使用
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader reader = new BufferedReader(isr);
        try {
            System.out.println(reader.readLine());
        } catch (Exception e) {
            // TODO: handle exception
        }
        
    }

  

序列化

➢ 序列化是把一个对象的状态写入一个字节流的过程。 ➢ 如果一个对象引用到其它对象,而这些对象又引用另外的对象,那么所有这些对 象都会被序列化。

Serializable接口

➢ 只有实现Serializable接口的对象才能被序列化工具存储或者恢复。 ➢ 声明为transient的变量不被序列化工具存储。 ➢ static变量同样不被存储。

ObjectOutputStream

➢ 构造方法 public ObjectOutputStream(OutputSteam os) ➢ 负责向流写入对象 public void writeObject(Object obj)

ObjectInputStream

➢ 构造方法 public ObjectInputStream(InputSteam is) ➢ 负责从流读出对象(反序列化) public Object readObject()

序列化

public class demo02 {
    public static void main(String[] args) {
    People p1 = new People(1,"小明","男",20,"1992-02-18","福建福州");
    People p2 = new People(2,"小红","女",20,"1992-02-18","福建厦门");
    File file = new File("People.text");
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;
    FileInputStream fis = null;
    ObjectInputStream ois = null;
    
    //序列化
    try {
        fos = new FileOutputStream(file);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(p1);
        oos.writeObject(p2);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally {
        try {
            oos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    //反序列化
    try {
        fis = new FileInputStream(file);
        ois = new ObjectInputStream(fis);
        People p3 = (People)ois.readObject();
        People p4 = (People)ois.readObject();
        System.out.println(p3.toString());
        System.out.println(p4.toString());
    } catch (Exception e) {
        // TODO: handle exception
    }
    }
}
​
public class People implements Serializable{
    private int no;
    private String name;
    private String sex;
    private int age;
    private String date;
    private String address;
    public People(int no, String name, String sex, int age, String date, String address) {
        super();
        this.no = no;
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.date = date;
        this.address = address;
    }
    @Override
    public String toString() {
        return "People [no=" + no + ", name=" + name + ", sex=" + sex + ", age=" + age + ", date=" + date + ", address="
                + address + "]";
    }
}

  

 

阅读(2377) 评论(0)