9 IO流

    IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式。

  • 流按操作数据分为:字节流和字符流

  • 流按流向分为:输入流和输出流


9.1 IO流常用基类

  • 字节流的抽象类

    InputStream,OutputStream

  • 字符流的抽象类

      Reader,Writer


9.2 FileWriter和FileReader

9.2.1 FileWriter

    该对象一被初始化就必须要明确被操作的文件,而且该文件会被创建到指定目录下。如果该目录已有同名文件,将被覆盖。若传递一个true参数,则不覆盖已有文件,在末尾追加数据。

    FileWriter fw = new FilrWriter(“demo.txt”,true);

    调用write方法,将数据写入到流中,在使用flush或者close方法刷新流中的数据。


9.2.2 FileReader

    创建一个文件读取流对象,和指定的文件相关联,该文件必须已经存在,如果不存在,则报FileNotFoundException异常。

    使用read方法读取数据,读到文件末尾返回-1。


9.3 带缓冲区的字符流

  • BufferedWriter

  • BufferedReader

    缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要先有流对象。只要将流对象作为参数传递给缓冲区的构造函数即可。


1、通过缓冲区,往文件中写内容
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterDemo {

    public static void main(String[] args) throws IOException {

        //创建字符写入流对象
        FileWriter fw = new FileWriter("buf.txt");
        //加入缓冲
        BufferedWriter bw =new BufferedWriter(fw);
        bw.write("abcde");
        //只要用到缓冲区,就要刷新
        bw.flush();
        
        //关闭资源
        bw.close();
    }
}

2、通过缓冲区,从文件中读取内容

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {

        FileReader fr = new FileReader("buf.txt");
        
        BufferedReader br = new BufferedReader(fr);
        String line = null;
        
        while (null!=(line=br.readLine())) {
            System.out.println(line);
        }
        
        br.close();
    }
}

3、通过缓冲区,复制文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedCopy {

    public static void main(String[] args) {

        BufferedReader br = null;
        BufferedWriter bw = null;
        
        try {
            br = new BufferedReader(new FileReader("in.txt"));
            bw = new BufferedWriter(new FileWriter("out.txt"));
            
            String line = null;
            
            while (null!=(line=br.readLine())) {
                bw.write(line);

                bw.newLine();

                bw.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException("读写失败");
        }finally{
            try {
                if (null!=br) {
                    br.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("读取关闭失败");
            }
            try {
                if (null!=bw) {
                    bw.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("写入关闭失败");
            }
        }
    }
}


4、常用方法:

    newLine();换行

    readLine();读一行文本,只返回回车符之前的内容,达到末尾返回null;

    BufferedReader的子类LineNumberReader提供了行号功能:setLineNumber和getLineNumber

   

9.4 字节流

  • FileOutputStream

  • FileInputStream

1、通过字节流,读写数据

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


public class FileStreamDemo {

    public static void main(String[] args) throws IOException {
        readFile();
        writeFile();
    }
    
    public static void readFile() throws IOException{
        FileOutputStream fos = new FileOutputStream("fos.txt");
        fos.write("abcde".getBytes());
        
        fos.close();
    }
    
    public static void writeFile() throws IOException{
        FileInputStream fis = new FileInputStream("fos.txt");
        
        byte[] buf = new byte[1024];
        int len = 0;
        
        while ((len=fis.read(buf))!=-1) {
            System.out.println(new String(buf, 0, len));
        }
        
        fis.close();
    }
}


9.5 带缓冲区的字节流

  • BufferedOutputStream

  • BufferedInputStream

1、通过带缓冲区的字节流,复制文件

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

public class BufferedStreamDemo {

    public static void main(String[] args) throws IOException {
        copyFile();
    }
    
    public static void copyFile() throws IOException{
        
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.mp3"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("2.mp3"));
        
        int b = 0;
        
        while ((b=bis.read())!=-1) {
            bos.write(b);
        }
        
        bos.close();
        bis.close();
    }
}

9.6 转换流

  • InputStreamReader:字节流转换为字符流

  • OutputStreamWriter:字符流转换为字节流

    转换流可以指定编码表

1、通过转换流,赋值文件内容

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class TransStream {

    public static void main(String[] args) throws IOException {

        //获取键盘录入
        //InputStream is = System.in;
        FileInputStream fis =new FileInputStream("in.txt");
        //将读取字节流转为字符流
        InputStreamReader isr = new InputStreamReader(fis);
        
        BufferedReader br = new BufferedReader(isr);
        
        //OutputStream os = System.out;
        FileOutputStream fos =new FileOutputStream("out.txt");
        //将写入字节流转为字符流
        OutputStreamWriter osw =new OutputStreamWriter(fos);
        BufferedWriter bw =new BufferedWriter(osw);
        
        String line =null;
        while ((line=br.readLine())!=null) {
            
            if ("over".equals(line)) {
                break;
            }
            bw.write(line.toUpperCase());
            bw.newLine();
            bw.flush();
        }
        
        br.close();

    }
}


9.7 流操作的基本规律

1、明确源和目的

    源:InputStream,Reader

    目的:OutputStream,Writer

2、操作的数据是否是纯文本

    是:字符流

    不是:字节流

3、当体系确定后,再明确要使用哪个具体的对象

    源设备:内存、硬盘、键盘

    目的设备:内存、硬盘、控制台


9.8 File类

    用来将文件或者文件夹封装成对象,方便对文件或者文件夹的属性信息进行操作。

1、File对象可以作为参数传递给流的构造函数

    File f1 = new File(“c:\\a\\a.txt”);

    File f2 = new File(“c:\\a”,b.txt);

    "\\"不利于跨平台,要使用File.separator来代替


2、File类常见方法

创建

    boolean createNewFile();在指定位置创建文件,如果该文件已经存在,则不创建

        File f1 = new File(“c:\\a\\a.txt”);

        f1.createNewFile();

    boolean mkdir();创建文件夹

    boolean mkdirs();

删除

    boolean delete();删除指定目录的文件

    void deleteOnExit();退出的时候,删除文件

判断

    boolean canRead();是否可读

    boolean canWrite();是否可写

    boolean exists();是否存在

    boolean isFile();是否是文件

    boolean isDirectory();是否是文件夹

获取

    getName();获取文件名

    getPath();获取文件路径

    getParent();获取文件的父目录,是绝对路径中的父目录;如果获取的是相对路径则返回null。


3、遍历文件

import java.io.File;

public class ShowFile {

    public static void main(String[] args) {

        File f =new File("c:\\");
        
        File[] ff = f.listFiles();
        
        for(File file : ff){
            System.out.println(file);
        }
    }
}


4、过滤文件

import java.io.File;
import java.io.FilenameFilter;

public class FileFilter {

    public static void main(String[] args) {

        File f =new File("c:\\");
        
        File[] ff = f.listFiles(new FilenameFilter() {
            
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".dll");
            }
        });
        
        for(File file : ff){
            System.out.println(file);
        }
    }
}

9.9 Properties类

  • Properties是HashTable的子类,具备Map集合的特点,它里面存储的键值对是字符串。

  • Properties是集合中和IO技术结合的容器。

特点:可以用于键值对形式的配置文件


1、往Properties中插入值并取出

import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

    public static void main(String[] args) {

        Properties p =new Properties();
        p.setProperty("zhangsan", "20");
        p.setProperty("lisi", "30");
        
        Set<String> s = p.stringPropertyNames();
        
        for(String name:s){
            
            System.out.println(name+":"+p.getProperty(name));
        }
    }
}


2、读取配置文件、加载配置文件和修改配置文件中的值

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class PropertiesIO {

    public static void main(String[] args) throws IOException {

        method1();

        method2();

        method3();
    }
    //读取配置文件

    public static void method1() throws IOException{
        
        BufferedReader br =new BufferedReader(new FileReader("properties.txt"));
        
        String line = null;
        Properties p  = new Properties();
        
        while ((line=br.readLine())!=null) {
            String[] pro = line.split("=");
            
            p.setProperty(pro[0], pro[1]);
        }
        br.close();
        System.out.println(p);
    }
    //加载配置文件

    public static void method2() throws IOException{
        
    FileReader fr =new FileReader("properties.txt");
       
        Properties p  = new Properties();
   
        p.load(fr);
        p.list(System.out);
    }
    //修改配置文件中的值

    public static void method3() throws IOException{
    
    FileInputStream fr =new FileInputStream("properties.txt");
    FileOutputStream fw = new FileOutputStream("properties.txt");
    
        Properties p  = new Properties();
        
        p.load(fr);
        fr.close();
        p.setProperty("lis", "20");
        p.store(fw, null);
        p.list(System.out);
        fw.close();
    }
}