JAVA IO流

在这里插入图片描述

1. IO流的概念

内存与存储设备之间传输数据的通道
在这里插入图片描述

2. 流的分类

2.1 按方向

  • 输入流:将<存储设备>中的内容读入到<内存>中
  • 输出流:将<内存>中的内容写入到<存储设备>中

2.2 按单位

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

在不确定文件类型时,则优先使用字节流

2.3 按功能

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础之上增强功能

FileInputStreamFileOutputStream,节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。

BufferedInputStreamBufferedOutputStream,过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。

DataInputStreamDataOutputStream,过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。

3. 字节流

InputStream:字节输入流的所有类的超类
OutputStream:字节输出流的所有类的超类
子类名特点:子类名称都说以其父类名作为子类名的后缀

字节流的父类(抽象类)

//InputStream 字节输入流
public int read(){}//一次读取一个字节
public int read(byte[] b){}//一次读取一个字节数组
public int read(byte[] b, int off, int len){}//一次读取一个字节数组的一部分

//OutputStream 字节输出流
public void write(int n){}//一次读写一个字节
public void write(byte[] b){}
public void write(byte[] b, int off, int len){}

3.1 文件字节流

文件输入流

public void static main(String[] args) throws Exception {
  // 1 创建FileInputStream 并指定文件路径
  FileInputStream fis = new FileInputStream("d:\\abc.txt");
  
  // 2 读取文件
  // fis.read();
  // 2.1单字节读取
  int data = 0;
  while((data = fis.read()) != -1){
    System.out.println((char)data);
  }
  // 2.2 一次读取多个字节
  byte[] buf = new byte[3]; // 大小为3的缓存区
  int count = fis.read(buf); // 一次读3个
  System.out.println(new String(buf));
  System.out.println(count);
  int count2 = fis.read(buf); // 再读3个
  System.out.println(new String(buf));
  System.out.println(count2);
  
  // 上述优化后
  int count = 0;
  while((count = fis.read(buf)) != -1){
    System.out.println(new String(buf, 0, count));
  }
  
  // 3 关闭
  fis.close();
}

文件输出流

public static void main(String[] args) throws Exception {
  //1.创建文件字节输出流
  FileOutputStream fos = new FileOutputStream("路径", true);
  
  //2.写入文件
  fos.write(97);
  fos.write('a');
  //String string = "hello world";
  fos.write(string.getByte());
  
  //3.关闭
  fos.close();

3.2 图片复制案例

//1.创建流
//1.1 文件字节输入流
FileInputStream fis = new FileInputStream("路径");
//1.2 文件字节输出流
FileInputStream fos = new FileOutputStream("路径");

//2.边读边写
byte[] buf = new byte[1024];
int count = 0;
while((count = fis.read(buf)) != -1) {
  fos.write(buf, 0, count);
}

//3.关闭(释放资源)
fis.close();
fos.close();

3.3 字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream

  • 提高IO效率,减少访问磁盘次数
  • 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
//使用字节缓冲流,读取文件
public static void main(String[] arge) throws Exception {
  //1.创建BufferedInputStream
  FileInputStream fis = new FileInputStream("路径");
  BufferedInputStream bis = new BufferedInputStream(fis);
  
  //2.一次读取一个字节数据
  int data = 0;
  while((data = bis.read()) != -1) {
    System.out.println((char)data);
  }
  
  //3.一次读取一个字节数组数据
  byte[] buf = new byte[1024];
  int count = 0;
  while((count = bis.read(buf)) != -1) {
    System.out.println(buf, 0, count));
  }
  
  //4.关闭(释放资源)
  bis.close();
}
//使用字节缓冲流写入文件
public static void main(String[] args) throws Exception {
  //1.创建BufferedInputStream
  FileOutputStream fos = new FileOutputStream("路径");
  BufferedOutputStream bis = new BufferedOutputStream(fos);
  //2.写入文件
  for(int i = 0; i < 10; i++) {
    bos.write("hello".getBytes());
    bos.flush();
  }
  //3.关闭
  bos.close();
}

4. 字符流

字符流 = 字节流 + 编码表 字符流 = 字节流 + 编码表 字符流=字节流+编码表

//传统字节流去读
public static void main(String[] args) {
  //1.创建FileInputStream对象
  FileInputStream fis = new FileInputStream("路径");
  
  //2.读取
  int data = 0;
  while((data = fis.read()) != -1) {
    System.out.println((char)data);
  }
  
  //3.关闭
  fis.close();
}

4.1 字符流的父类(抽象类)

reader字符输入流

  • public int read(){}
  • public int read(char[] c){}
  • public int read(char[] b, int off, int len){}
    write字符输出流
  • public void write(int n){}
  • public void write(String str){}
  • public void write(char[] c){}

创建FileReader

//1.创建FileReader 文件字符输出流
FileReader fr = new FileReader("..");

//2.读取
//2.1 单个字符读取
int data = 0;
while((data = fr.read()) != -1) {
  System.out.println((char)data);
}
//2.2单个字符数组读取
char[] buf = new char[2];
int count = 0;
while((count = fr.read(buf) != -1)) {
  System.out.println(new String(buf, 0, count));
}

//3.关闭
fr.close();

创建FileWriter对象

// 1. 创建FileWriter对象
FileWriter fw = new FileWriter("..");
// 2. 写入
for(int i = 0; i < 10; i ++){
  fw.write("写入的内容");
  fw.flush();
}
// 3. 关闭
fw.close();
System.out.println("执行完毕");

4.2 (案例)使用上述内容进行文本文件复制

字符流不能复制图片或者二进制文件,使用字节流可以复制任意文件

public static void main(String[] args) throws Exception{
  // 1. 创建
  FileReader fr = new FileReader("...");
  FileWriter fw = new FileWriter("...");
  // 2. 读写
  int data = 0;
  while((data = fr.read()) != -1){
    fw.write(data);
    fw.flush();
  }
  // 3. 关闭
  fw.close();
  fr.close();
}

4.3 字符缓冲流

BufferedReader / BufferedWriter
高效读写,支持输入换行符,可一次写一行读一行

public static void main(String[] args) throws Exception{
  // 创建缓冲流
  FileReader fr = new FileReader("..");
	BufferedReader br = new BufferedReader(fr);
  // 读取
  // 1. 第一种方式
  char[] buf = new char[1024];
  int count = 0;
  while((count = br.read(buf)) != -1){
    System.out.println(new String(buf, 0, count));
  }
  // 2. 第二种方式 一行一行读取
  String line = null;
  while((line = br.readLine()) != null){
    System.out.println(line);
  }
  
	//3.关闭
  br.close();
}
public static void main(String[] args){
  // 1. 创建BufferedWriter对象
  FileWriter fw = new FileWriter("..");
  BufferedWriter bw = new BufferedWriter(fw);
  // 2. 写入
  for(int i = 0; i < 10; i ++){
    bw.write("写入的内容");
    vw.newLine(); // 写入一个换行符
    bw.flush();
  }
  // 3. 关闭
  bw.close(); // 此时会自动关闭fw
}
  • 特殊功能

void newLine()写一行行分隔符,行分隔符字符串由系统属性定义

String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null

4.4 PrintWriter

封装了print() / println() 方法 支持写入后换行
支持数据原样打印

public static void main(String[] args){
  // 1 创建打印流
  PrintWriter pw = new PrintWriter("..");
  // 2 打印
  pw.println(12);
  pw.println(true);
  pw.println(3.14);
  pw.println('a');
  // 3 关闭
  pw.close();
}

4.5 转换流

桥转换流InputStreamReader / OutputStreamWriter
可将字节流转换为字符流
可设置字符的编码方式

psvmpublic static void main(String[] args) throws Exception{
  // 1 创建InputStreamReader对象
  FileInputStream fis = new FisInputStream("..");
  InputStreamReader isr = new InputStreamReader(fis, "utf-8");
  // 2 读取文件
  int data = 0;
  while((data = isr.read()) != -1){
    System.out.println((char)data);
  }
  // 3 关闭
  isr.close();
}

public static void main(String[] args) throws Exception{
  // 1 创建OutputStreamReader对象
  FileOutputStream fos = new FisOutputStream("..");
  OutputStreamWRITER osw = new OutputStreamReader(fos, "utf-8");
  // 2 写入
  for(int i = 0; i < 10; i ++){
    osw.write("写入内容");
    osw.flush();
  }
  // 3 关闭
  osw.close();
}

5. IO特殊操作流

  1. 标准输入输出流
    public static final InputStream in;标准输入流
    通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
    public static final PrintStream in;标准输出流
    通常该流对于显示输出或由主机环境或用户指定的另一个输出目标
  • 使用步骤:
    1.可以独自实现键盘录入输入
    BufferedReader(InputStreamReader(System.in));
    调用readtLine()方法接收数据
    2.由于以上方式过于复杂,可以直接使用键盘输入Scanner sc = new Scanner(System.in);

6. 对象流

ObjectOutputStream / ObjectInputStream

  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串的功能
  • 增强了读写对象的功能
    1. readObject()从流中读取一个对象
    2. writeObject(Object obj)向流中写入一个对象
      使用流传输对象的过程成为序列化,反序列化

7. 序列化和反序列化

7.1 序列化

(使用ObjectOutputStream实现序列化)

public static void main(String[] args) {
  //1.创建对象流
  FileOutputStream fos = new FileOutputStream("d:\\st.bin");
  ObjectOutputStream oos = new ObjectOutputStream(fos);
  
  //2.序列化(写入操作)
  Student zhangsan = new Student("zs", 20);
  oos.WriteObject(zhangsan);
  
  //3.关闭
  oos.close();
  System.out.println("序列化完毕");

7.2 反序列化

(使用ObjectInputStream实现反序列化【读取重构对象】

public static void main(String[] args) {
  //1.创建对象流
  FileInputStream fis = new FileInputStream("d:\\stu.bin");
  ObjectInputStream ois = new ObjectInputStream(fis);
  
  //2.读取文件(反序列化)
  Student s = (Student)ois.readObject();
  
  //3.关闭
  ois.close();
  System.out.println("执行完毕");
  System.out.println(s.toString());

7.3 注意事项

  1. 某个类要想序列化必须实现Serializable接口
  2. 序列化类中对象属性要求实现Serializable接口
  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  4. 使用transient修饰属性,这个属性就不能序列化
  5. 静态属性不能序列化
  6. 序列化多个对象,可以借助集合来实现

8. 编码方式

UTF-8…不赘述

9. File类

概念:代表物理盘符中的一个文件或者文件夹

FIle类的使用

  1. 分割符
  2. 文件操作
  3. 文件夹操作
public class Demo {
  public static void main(String[] args) {
    separator();
  }
  
  //1.分隔符
  public static void separator() {
    System.out.println("路径分隔符" + File.pathSeparator);
    System.out.println("名称分隔符" + File.separator);
  }
  //2.文件操作
  public static void fileOpen() {
    //1.创建文件
    if(!file.exists()) {
      File file = new File("...");
      boolean b = file.creatNewFile();
    }
    // 2. 删除文件
    // 2.1 直接删除
    file.delete(); // 成功true
    // 2.2 使用jvm退出时删除
    file.deleteOnExit();
    
    // 3. 获取文件信息
    System.out.println("获取绝对路径" + file.getAbsolutePaht());
    System.out.println("获取路径" + file.getPath());
    System.out.println("获取文件名称" + file.getName());
    System.out.println("获取夫目录" + file.getParent());
    System.out.println("获取文件长度" + file.length());
    System.out.println("文件创建时间" + new Date(file.lashModified()).toLocalString());
    
    // 4. 判断
    System.out.println("是否可写" + file.canWrite());
    System.out.println("是否是文件" + file.isFile());
    System.out.println("是否隐藏" + file.isHidden());
  }
  
  
  // 文件夹操作
  public static void directoryOpe() throws Exception{
    // 1. 创建文件夹
    File dir = new File("...");
    System.out.println(dir.toString());
    if(!dir.exists()){
      //dir.mkdir(); // 只能创建单级目录
      dir.mkdirs(); // 创建多级目录
    }
    
    // 2. 删除文件夹
    // 2.1 直接删除
    dir.delete(); // 只能删除最底层空目录
    // 2.2 使用jvm删除
    dir.deleteOnExit();
    
    // 3. 获取文件夹信息
 	System.out.println("获取绝对路径" + dir.getAbsolutePaht());
    System.out.println("获取路径" + dir.getPath());
    System.out.println("获取文件名称" + dir.getName());
    System.out.println("获取夫目录" + dir.getParent());
    System.out.println("获取文件长度" + dir.length());
    System.out.println("文件夹创建时间" + new Date(dir.lashModified()).toLocalString());
    
    // 4. 判断
    System.out.println("是否是文件夹" + dir.isFile());
    System.out.println("是否隐藏" + dir.isHidden());
    
    // 5. 遍历文件夹
    File dir2 = new File("...");
    String[] files = dir2.list();
    for(String string : files){
      System.out.println(string);
    }
    
    // FileFilter接口的使用
    
    File[] files2 = dir2.listFiles(new FileFilter(){
      
      @Override
      public boolean accept(File pathname){
        if(pathname.getName().endsWith(".jpg")){
          return true;
        }
        return false;
      }
    });
    for(File file : files2){
      System.out.println(file.getName());
    }
  }
}

递归遍历文件夹

public static void main(String[] args) {
  listDir(new File("d:\\myfiles"));
}

public static void listDir(File dir) {
  File[] files = dir.listFiles();
  System.out.println(dir.getAbsolutePath());
  if(files != null && files.length > 0) {
    for(File file : files) {
      if(file.isDirectory()) {
        listDir(file);//递归
      }else{
        System.out.println(file.getAbsolutePath());
      }
    }
  }
}

递归删除文件夹

public static void deleteDir(File dir){
  File[] files = dir.listFiles();
  if(files != null && files.length > 0){
    for(File file : files){
      if(file.idDirectory()){
        deleteDir(file); // 递归
      }else{
        // 删除文件
        System.out.println(file.getAbsolutePath() + "删除" + file.delete());
      }
    }
  }
}

10. Properties类

  1. 概念

是一个Map体系的集合类
Properties可以保存到流中或从流中加载
属性列表中的每个键及其对应的值都是一个字符串

  1. Properties作为Map集合的特有方法
  1. Object setProperty(String key, String value)
    设置集合的键和值,都属于String类型,底层调用Hashtable方法put
  2. String getProperty(String key)
    使用此属性列表中指定的键搜索属性
  3. Set《String》stringPropertyNames()
    从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
  1. Properties和IO流相结合的方法
  1. void load(InputStream inStream)
    从输入字节流读取属性列表(键和元素对)
  2. void load(Reader reader)
    从输入字符流读取属性列表(键和元素对)
  3. void store(OutputStream out, String comments)
    将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream) 方法的格式写入输出字节流
  4. void store(Write writer, String comments)
    将此属性列表(键和元素对)写入此Properties表中,以适合使用load(Reader)方法的格式写入输出字符流
  1. 示例代码
public class PropertiesDemo03 {
public static void main(String[] args) throws Exception {
  //把集合中的数据保存到文件
  //myStore();
 
  //把文件中的数据加载到集合
  myLoad();

}
 
private static void myLoad() throws IOException {
  Properties prop = new Properties();
 
  //void load(Reader reader):
  FileReader fr = new FileReader("myOtherStream\\fw.txt");
  prop.load(fr);
  fr.close();
 
  System.out.println(prop);
}
 
private static void myStore() throws IOException {
        Properties prop = new Properties();
 
  prop.setProperty("itheima001","林青霞");
  prop.setProperty("itheima002","张曼玉");
  prop.setProperty("itheima003","王祖贤");
 
  //void store(Writer writer, String comments):
  FileWriter fw = new FileWriter("myOtherStream\\fw.txt");
  prop.store(fw,null);
  fw.close();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值