JAVA-IO专题

IO流(未完待续)

文件

文件流介绍

文件对我们并不陌生,文件是保存数据的地方。

文件在程序中是以流的形式来操作的

image-20221218131259875

流 :数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)之间的路径

输出流:数据从程序(内存)到数据源(文件)的路径

常用的文件操作

  • 根据路径构建一个 File 对象

    new File(String pathname)

    createNewFile() 创建新文件

    String filePath = "e:\\news1.txt";
    File file = new File(filePath);
    try {
        file.createNewFile();
        System.out.println("文件创建成功");
    } catch (IOException e) {
    	e.printStackTrace();
    }
    
  • 根据父目录文件+子路径构建

    new File(File parent, String child)

    File parentFile = new File("e:\\");
    String fileName = "news2.txt";
    //这里的 file 对象,在 java 程序中,只是一个对象
    //只有执行了 createNewFile 方法,才会真正的,在磁盘创建该文件
    File file = new File(parentFile, fileName);
    try {
        file.createNewFile();
        System.out.println("创建成功~");
    } catch (IOException e) {
    	e.printStackTrace();
    }
    
  • 根据父目录+子路径构建

    new File(String parent, String child)

    String parentPath = "e:\\";
    String fileName = "news4.txt";
    File file = new File(parentPath, fileName);
    try {
        file.createNewFile();
        System.out.println("创建成功~");
    } catch (IOException e) {
    	e.printStackTrace();
    }
    

获取文件的相关信息

  • getName 获取文件名
  • getAbsolutePath 获取文件绝对路径
  • getParent 获取父级file
  • length 获取文件的大小(单位是字节)
  • exists 是否存在
  • isFile 是否是文件
  • isDirectory 是否是目录
File file = new File("c:\\Code\\news1.txt");
try {
    file.createNewFile();
    System.out.println("文件创建成功");
} catch (IOException e) {
    e.printStackTrace();
}

System.out.println("文件名字=" + file.getName());
System.out.println("文件绝对路径=" + file.getAbsolutePath());
System.out.println("文件父级目录=" + file.getParent());
System.out.println("文件大小(字节)=" + file.length());
System.out.println("文件是否存在=" + file.exists());
System.out.println("是不是一个文件=" + file.isFile());
System.out.println("是不是一个目录=" + file.isDirectory());
文件创建成功
文件名字=news1.txt
文件绝对路径=c:\Code\news1.txt
文件父级目录=c:\Code
文件大小(字节)=0
文件是否存在=true
是不是一个文件=true
是不是一个目录=false

目录的操作和文件的删除

在 Java 编程中,目录被当作一种特殊的文件

mkdir 创建一级目录,下面给出简略代码

File file = new File("C:\\demo");
file.mkdir()

mkdirs 创建多级目录

File file = new File("C:\\demo\\a\\b\\c");
file.mkdirs();

delete 删除空目录或文件

IO流原理及流的分类

IO流原理

  1. I/O 是Input/Output 的缩写,I/O 技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等
  2. Java 程序中,对于数据的输入/输出操作以”流(stream)“的方式进行
  3. Java.io 包下提供了各种”流“类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
  4. 输入 input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  5. 输出 output:将程序(内存)数据输出到磁盘、光盘等存储设备中

流的分类

  1. 按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)文本文件
  2. 按数据流的流向不同分为:输入流,输出流
  3. 按流的角色的不同分为:节点流,处理流/包装流
抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWrinter

Java 的 IO 流共涉及 40 多个类,实际上非常规则,都是从如上 4 个抽象基类派生的,由这 4 个类派生出来的子类名称都是以其父类名作为子类名后缀

IO 流体系图 - 常用的类

image-20221218220126712

FileInputStream 🚩

FileInputStream 属于字节输入流,方法如下图所示

image-20221226193052249

使用 FileInputStream 读取 hello.txt 文件,并将文件内容显示在控制台上

方式一:使用 read()来读取,但每次只能读取单字节,效率低。hello.txt 里存的是 hello,world(若包含中文,则会出现乱码)

注意:char 和 int 可以说是等价的

String filePath = "e:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
    //创建 FileInputStream 对象,用于读取 文件
    fileInputStream = new FileInputStream(filePath);
    //从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
    //如果返回-1 , 表示读取完毕
    while ((readData = fileInputStream.read()) != -1) {
    	System.out.println((char)readData);//转成 char 显示
	}
} catch (IOException e) {
	e.printStackTrace();
} finally {
    //关闭文件流,释放资源.
    try {
    	fileInputStream.close();
    } catch (IOException e) {
    	e.printStackTrace();
    }
}

结果:

h
e
l
l
o
,
w
o
r
l
d    

方式二:使用 read(byte[] b) 读取文件,提高效率

String filePath = "e:\\hello.txt";
//字节数组
byte[] buf = new byte[8]; //一次读取 8 个字节. int readLen = 0;
FileInputStream fileInputStream = null;
try {
    //创建 FileInputStream 对象,用于读取 文件
    fileInputStream = new FileInputStream(filePath);
    //从该输入流读取最多 b.length 字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
    //如果返回-1 , 表示读取完毕
    //如果读取正常, 返回实际读取的字节数
    while ((readLen = fileInputStream.read(buf)) != -1) {
    	System.out.println(new String(buf, 0, readLen));//显示
	}
} catch (IOException e) {
	e.printStackTrace();
} finally {
//关闭文件流,释放资源. try {
	fileInputStream.close();
} catch (IOException e) {
	e.printStackTrace();
	}
}

通过debug 可知,一次循环 读取8 个字节的数据

结果:

hello,wo
rld    

FileOutputStream🚩

FileOutputStream 是字节输出流

image-20221226195921854

请使用 FileOutputStream 在 a.txt 文件中写入 “hello,world”,(如果文件不存在,会自动创建文件,前提是目录已经存在)

//创建 FileOutputStream 对象
String filePath = "e:\\a.txt";
FileOutputStream fileOutputStream = null;
try {
    //得到 FileOutputStream 对象 
    //1. new FileOutputStream(filePath) 创建方式,当写入内容时,会覆盖原来的内容
    //2. new FileOutputStream(filePath, true) 创建方式,当写入内容时,是追加到文件后面
    fileOutputStream = new FileOutputStream(filePath, true);
    //写入一个字节
    //fileOutputStream.write('H');
    //写入字符串
    String str = "hello,world";
    //str.getBytes() 可以把 字符串-> 字节数组
    fileOutputStream.write(str.getBytes());
    //write(byte[] b, int off, int len) 将 len 字节从位于偏移量 off 的指定字节数组写入此文件输出流
    //fileOutputStream.write(str.getBytes(), 0, 3);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
    	fileOutputStream.close();
    } catch (IOException e) {
    	e.printStackTrace();
    }
}

应用案列—拷贝图片

思路:

  1. 创建文件输入流,将文件读入到程序
  2. 创建文件输出流,将读取到的文件数据输出到指定位置
  3. 边读取边输出,因为如果文件过大,内存会不够,故采用循环
String srcFilePath = "e:\\Koala.jpg";
String destFilePath = "e:\\Koala3.jpg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
    fileInputStream = new FileInputStream(srcFilePath);
    fileOutputStream = new FileOutputStream(destFilePath);
    //定义一个字节数组,提高读取效果
    byte[] buf = new byte[1024];
    int readLen = 0;
    while ((readLen = fileInputStream.read(buf)) != -1) {
        //读取到后,就写入到文件 通过 fileOutputStream
        //即,是一边读,一边写
        fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法
	}
	System.out.println("拷贝 ok~");
} catch (IOException e) {
	e.printStackTrace();
} finally {
	try {
    //关闭输入流和输出流,释放资源
    if (fileInputStream != null) {
    	fileInputStream.close();
    }
    if (fileOutputStream != null) {
    	fileOutputStream.close();
    }
    } catch (IOException e) {
    	e.printStackTrace();
    }
}

FileReader 和 FileWriter

FileReader 相关方法;

  1. new FileReader(File/String)
  2. read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回 -1
  3. read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回 -1

相关API:

  1. new String(char[]):将 char[] 转换成 String
  2. new String(char[], off, len):将 char[] 指定的部分转换成 String

FileWriter 相关方法:

  1. new FileWriter(File/String):覆盖模式,相当于流的指针在首端
  2. new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
  3. write(int):写入单个字符
  4. write(char[]):写入指定数组
  5. write(char[], off, len):写入数组的指定部分
  6. write(String):写入整个字符串
  7. write(String, off, len):写入字符串的指定部分

**相关API:**String 类:toCharArray:将 String 转换成 char[]

注意:FileWriter 使用后,必须要关闭(close)或刷新(flush),否则写入不到指定的文件!

**案例一:**使用 FileReader 从 story.txt 读取内容,并显示

  1. 每次读一个字符

    String filePath = "e:\\story.txt";
    FileReader fileReader = null;
    int data = 0;
    //1. 创建 FileReader 对象
    try {
        fileReader = new FileReader(filePath);
        //循环读取 使用 read, 单个字符读取
        while ((data = fileReader.read()) != -1) {
        	System.out.print((char) data);
    	}
    } catch (IOException e) {
    	e.printStackTrace();
    } finally {
        try {
        if (fileReader != null) {
        	fileReader.close();
    	}
    } catch (IOException e) {
    	e.printStackTrace();
    	}
    }
    
  2. 每次读取多个字符

    String filePath = "e:\\story.txt";
    FileReader fileReader = null;
    int readLen = 0;
    char[] buf = new char[8];
    //1. 创建 FileReader 对象
    try {
        fileReader = new FileReader(filePath);
        //循环读取 使用 read(buf), 返回的是实际读取到的字符数
        //如果返回-1, 说明到文件结束
        while ((readLen = fileReader.read(buf)) != -1) {
        	System.out.print(new String(buf, 0, readLen));
        }
    } catch (IOException e) {
    	e.printStackTrace();
    } finally {
        try {
        if (fileReader != null) {
            fileReader.close();
        }
    } catch (IOException e) {
    	e.printStackTrace();
    }
    }
    

案例二:使用 FileWriter 将 “风雨之后,定见彩虹” 写入到 note.txt 文件

String filePath = "e:\\note.txt";
//创建 FileWriter 对象
FileWriter fileWriter = null;
char[] chars = {'a', 'b', 'c'};
try {
    fileWriter = new FileWriter(filePath);//默认是覆盖写入
    fileWriter.write("风雨之后,定见彩虹");
} catch (IOException e) {
	e.printStackTrace();
} finally {
    try {
        fileWriter.close();
    } catch (IOException e) {
    	e.printStackTrace();
    }
}

节点流和处理流

打印流PrintStream 和 PrintWriter

Properties类

//创建 FileWriter 对象
FileWriter fileWriter = null;
char[] chars = {‘a’, ‘b’, ‘c’};
try {
fileWriter = new FileWriter(filePath);//默认是覆盖写入
fileWriter.write(“风雨之后,定见彩虹”);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}


## 节点流和处理流









## 打印流PrintStream 和 PrintWriter







## Properties类







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值