IO流:文件处理(二)

摘要:字节流、字符流;图片、文本复制;IO流异常处理;Properties配置读写

一、IO的分类

1.输入流、输出流

以内存为基准

  • 输入流:内存 <----硬盘
  • 输出流:内存 ----->硬盘

2.字节流、字符流

  • 字节流:以字节为单位,读写数据的流
    主要处理图片、视频类
  • 字符流:以字符为单位,读写数据的流
    主要处理文本数据

二、字节流

顶级父类:

  • java.io.InputStream
  • java.io.OutputStream

常用实现类:

  • FileInputStream
  • FileOutputStream

(1)FileInputStream fis使用demo:

/**
 *  以字节流的形式读取文件:java.io.FileInputStream;
 *  (1)创建输入流:FileInputStream fis = new FileInputStream(File/pathName);
 *  (2)用字节数组作为缓存,读取文件:
 *      byte[] b = new byte[1024];
 *      while ((len = fis.read(b)) != -1){
 *             fos.write(b,0,len);  //将文件写到目标文件中。
 *      }
 *
 */
public class FISRead {
    public static void main(String[] args) throws IOException {
        createFile();
        writeFile();
        //read1();  // 通过fis.read()读取单个字节,并返回字节int形式
        read2();
    }

    /*以字节数组的形式:读文件*/
    private static void read2() throws IOException {
        FileInputStream fis = new FileInputStream("read.txt");
        int len ;  //每次读取有效字节的长度
        byte[] bytes = new byte[2];  // 定义字节数组,作为装字节数据的容器
        while ((len = fis.read(bytes)) != -1){
            System.out.println(new String(bytes,0,len));    //这里从0写到len长度的数据。因为最后一次读取的数据len有效长度不定。
        }

    }

}

(2)FileOutputStream fos使用demo:

/**
 * 文件输出流:java.io.FileOutputStream;
 * 构造方法:
 *         (1)FileOutputStream fos = new FileOutputStream(new File("a.txt"));  //文件对象
 *         (2)FileOutputStream fos = new FileOutputStream("a.txt");  //文件路径
 *         (3)public FileOutputStream(File file, boolean append);   //append = true (追加写) false (覆盖写)
 * 基本方法:
 *         (1)public void close() :     关闭此输出流并释放与此流相关联的任何系统资源。
 *         (2)public void flush() :     刷新此输出流并强制任何缓冲的输出字节被写出。
 *         (3)public void write(byte[] b) : 将 b.length字节 从指定的字节数组写入此输出流。
 *  (***) (4)public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。(常用)
 */

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        //使用文件对象创建文件流对象
        File file = new File("a.txt");
        FileOutputStream fos = new FileOutputStream(file);
        //创建字节数组
        byte[] bytes = {97,98,99,100,101};
        for (int i = 0; i < bytes.length; i++) {
            //写入单个字节
            fos.write(bytes[i]);
            //mac下的换行符
            fos.write("\n".getBytes());
        }
        fos.close();

    }
}

(3)图片复制demo:字节流读写

public class PicCopy {
    public static void main(String[] args) throws IOException {
        //1.创建文件io流
        FileInputStream fis = new FileInputStream("/Users/caowei/Desktop/屏幕快照/1.jpg");
        FileOutputStream fos = new FileOutputStream("pictureCopy.jpg");
        //2.读写文件
        //读取的有效数据的长度
        int len ;
        //数据缓冲区
        byte[] b = new byte[1024];
        while ((len = fis.read(b)) != -1){
            fos.write(b,0,len);
            //System.out.println(Arrays.toString(b));
        }
        //3.关闭流
        fos.close();
        fis.close();
    }
}


三、字符流

顶级父类:

  • java.io.Reader
  • java.io.Writer

常用实现类:

  • FileReader
  • FileWriter

(1)FileReader使用

import java.io.FileReader;
import java.io.IOException;
/**
 * 字符输入流:java.io.Reader
 * 实现类:java.id.FileReader  extends OutputStreamReader  extends Reader
 * 构造方法:
 *      FileReader(File file) :
 *      FileReader(String fileName) :
 * 常用方法:
 *      read():每次读取一个字符,返回:字符的int型,游标自动下移,读至末尾,返回-1
 *      read(char[] cbuf) 使用字符数组,作为容器。每次读取cbuf.length()的长度个字符到数组中,返回读取到的有效字符个数.
 *
 */
public class FileRead {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("read.txt");    // 字符流,常用来处理文本信息。
        int len;
        char[] c = new char[1024];            //字符数组作为数据容器
        while ((len = fr.read(c)) != -1){
            System.out.println(new String(c,0 ,len));      //打印有效数据,len为有效数据长度。
            //这里也可以定义一个输出流,将数据写到硬盘中。
        }
    }
}

(2)FileWriter的使用步骤

/**
 * 字符输入流:java.io.Writer
 * 实现类:java.id.FileWriter
 * 构造方法:
 *      FileWriter(File file) :
 *      FileWriter(String fileName) :
 * 常用方法:
 *       //写字符数组
 *       write(char[] cbuf)
 *       write(char[] cbuf, int off, int len)
 *       //写字符串
 *       fs.write("字符串");
 *       fs.write("字符串,startIndex ,len")
 *
 * 使用步骤:
 *      1.创建FileWriter对象,构造方法绑定数据写入的目的地
 *      2.使用writer方法将数据写入到内存缓冲区中(不同于字节流)-->字符转换为字节的过程
 *      3.使用flush()方法,将内存缓冲区的数据刷新到文件中(大文件读写,应该及时刷新数据,不要占用内存缓冲区)
 *      4.释放资源:close()会先将缓冲区数据刷新到内存,再关闭资源。
 *
 */

public class FileWrite {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("read.txt");    // 字符流,常用来处理文本信息。
        FileWriter fw = new FileWriter("write.txt");
        int len;
        char[] c = new char[1024];            //字符数组作为数据容器
        while ((len = fr.read(c)) != -1){
            fw.write(c,0,len);    //将数据写到了内存的缓冲区。还没有刷新到硬盘中,不同于字节流!
        }
        //在使用字符流时,没有使用时flush,或者close是无法将数据从缓冲加到硬盘的。
        fw.close();
        fr.close();
    }
}

flush() 和 close()的区别: flush 刷新缓冲区,流对象可以继续使用; close 先刷新缓冲区,然后通知系统释放资源,流对象关闭


四、IO的异常处理

在实际的开发中,通常不会将异常抛出,而是捕获处理。

1.在jdk1.7之前,使用try catch finally 处理流中的异常的,步骤
       try{
           //可能产生异常的代码
       }catch(){
           //异常的处理逻辑
       }finally{
           //一定会执行的代码
           //释放资源
       }

例子

 public static void main(String[] args)  {
        //提高变量的作用域,让finally可以使用
        //定义变量的时候可以没有值,但是使用的时候必须有值。
        FileReader fr = null;
        FileWriter fw = null;
        try{
            //可能会产生异常的代码
             fr = new FileReader("read.txt");
             fw = new FileWriter("a.txt",false);

            int len = 0;
            char[] c = new char[1024];
            while ((len = fr.read(c)) != -1){
                fw.write(c,0,len);
            }

        }catch (IOException e){
            //异常的处理逻辑
            System.out.println(e);
        }finally {
            try {
                //执行close()的时候也有可能产生异常,捕获抛出异常
                fw.close();
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
2.JDK7异常处理

JDK7新特性:try(){}catch(){} 在try后新增加()括号,可以在其中定义流对象,作用范围为try{},try{}中代码执行完毕后,自动释放资源。不用写finally了。

public class TryCatchByJDK7 {
    public static void main(String[] args)  {
        //提高变量的作用域,让finally可以使用
        //定义变量的时候可以没有值,但是使用的时候必须有值
        try(FileReader fr = new FileReader("read.txt");
            FileWriter fw = new FileWriter("a.txt",false);
            ){
            //可能会产生异常的代码
            int len = 0;
            char[] c = new char[1024];
            while ((len = fr.read(c)) != -1){
                fw.write(c,0,len);
            }
        }catch (IOException e){
            //异常的处理逻辑
            System.out.println(e);
        }

    }
}
  • JDK9: 可以在try前面定义流对象,在try()的小括号中接收参数。

五、属性集Properties类

1.概念:

java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其 对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时, System.getProperties 方法就是返回 一个 Properties 对象。

2.基本方法
  1. 构造函数:
    public Properties() :创建一个空的属性列表。
  2. 存键值对:
    public Object setProperty(String key, String value) : 保存一对属性。
  3. 取值:
    public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
  4. 获取键的集合:遍历取值;
    public Set stringPropertyNames() :所有键的名称的集合。

使用,类似其超类Map的put()/get()/keySet()方法

3.与IO流相关的两个重要方法

load()/store():两种方法都有不同的重载形式,主要区别在于是否支持中文参数与。

  • void load(InputStream inStream)
    从输入流中读取属性列表(键和元素对)。
  • void load(Reader reader)
    按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
  • void store(OutputStream out, String comments)
    以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。
  • void store(Writer writer, String comments)
    以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。

读写配置文件的示例

public class PropertiesDemo {
    public static void main(String[] args) throws IOException {
        writeProp();  //写配置文件
        readProp();  //读取配置文件
    }

    /*读取配置文件,并打印*/
    private static void readProp() throws IOException {
        //1.创建Properties集合对象
        Properties prop = new Properties();
        //2.使用load()方法读取,并保存文件为键值对。
        prop.load(new FileReader("prop.txt"));
        //3.遍历prop集合
        Set<String> strings = prop.stringPropertyNames();
        for (String key : strings) {
            String value = prop.getProperty(key);
            System.out.println(value);
        }

    }

    /*写配置文件*/
    public static  void writeProp() throws IOException {
        //1.创建Properties集合,添加数据
        Properties prop = new Properties();
        prop.setProperty("ip","127.0.0.1");
        prop.setProperty("port","442");

        //2.创建字符输出流,构造函数绑定输出地址
        FileWriter fw = new FileWriter("prop.txt");

        //3.使用Properties集合中的store()方法,将集合中的临时数据写入到硬盘中
        prop.store(fw,"save data");

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值