Java_I\O流
I/O框架
1.0流的概念
内存与存储设备之间传输数据的通道
2.0流的分类
2.1按方向[重点]
- 输入流:将<存储设备>中的内容读到<内存>中
- 输出流:将<内存>中的内容写到<存储设备>中
2.2按单位
- 字节流:以字节为单位,可以读写所有数据
- 字符流:以字符为单位,只能读写文本数据
2.3按功能
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础之上增强功能
3.0字节流
字节流的父类(抽象类)
- 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文件字节流
- FilleInputStream:
- public int read(byte[] b) //从流中读取多个字节,将读到的内容存入b数组中,返回实际 读到的字节数;如果达到文件底部,则返回-1.
package com.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* 演示FileInputStream的使用
* 文件字节输入流
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
//创建fileInputStream,并指定文件路劲
FileInputStream fis = new FileInputStream("D:\\aaa.txt");
//读取文件
/* 单个字节读取
int data = 0;
while ((data = fis.read())!=-1){
System.out.print(data+" ");
System.out.println((char) data);
}
*/
//一次性读取多个字节
byte[] bytes = new byte[1024];
int count = 0;
while ((count=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,count));
}
//3.关闭
fis.close();
System.out.println("执行完毕");
}
}
其中new String(bytes,0,count)中bytes - 要解码为字符的字节, offset - 要解码的首字节的索引, length - 要解码的字节数
- FileOutputStream:
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流
new FileOutputStream(第一个参数name:存储文件的位置,第二个参数:默认为false(可以不写))(如果为TRUE,则表示在末尾追加,为FALSE则表示覆盖)
package com.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
* 演示文件字节输出流的使用
* FileOutputStream
*/
public class Demo02 {
public static void main(String[] args) throws Exception {
//1.创建文件字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\bbb.txt",true);
//2.写入文件
fos.write(97);//会转化成Ascall吗
fos.write('b');
fos.write('a');
String string = "helloworld";
fos.write(string.getBytes());
//3.关闭
fos.close();
System.out.println("执行完毕");
}
}
3.2图片复制案例
package com.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 使用文件字节流实现文件复制
*/
public class Demo03 {
public static void main(String[] args) throws Exception{
//1.创建流
//1.1文件字节输入流
FileInputStream fis = new FileInputStream("D:\\java\\IO\\timg.jpg");
//1.2文件字节输出流
FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\timg1.jpg");
//一边读,一边写
byte[] bytes = new byte[1024];
int count = 0;//count 是用来保存实际读取数据
while ((fis.read(bytes))!=-1){
fos.write(bytes,0,count);
}
//关闭流
fis.close();
fos.close();
System.out.println("复制完毕");
}
}
3.3字节缓冲流
缓冲流:BufferedInputStream/ BufferedOutputStream
- 提高IO效率,减少访问磁盘次数
- 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
再补充一下,如果我们写入的文件大小刚好和缓冲区容量一致时,就会自动将文件写入到路径中,如果不满,就需要close或flush;打个比方,文件20k,缓冲10k,如果不使用close或flush
package com.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
/**
* 使用字节缓冲流读取
* BufferedInputStream
*/
public class Demo04 {
public static void main(String[] args) throws Exception{
//1.创建BufferedInputStream
FileInputStream fis = new FileInputStream("D:\\java\\IO\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.读取
// int data = 0;
// System.out.println((char) bis.read());
// System.out.println((char)bis.read());
// while ((data = bis.read())!=-1){
// /*
// bis.read()会读入一个字节,然后data = bis.read(),则sout((char)data),则会输出读入的字节
// 因为当读入的字节为最后一个的时候,会返回-1,所以data!=-1的时候,会直接输出读入的字节
// */
// System.out.print((char)data);
// }
// 用自己创建的缓冲流
byte[] bytes = new byte[1024];
int count = 0;
while ((count = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,count));
}
//关闭
bis.close();
}
}
package com.io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
/**
*使用字节缓冲流写入文件
* BufferedOutputStream
*/
public class Demo05 {
public static void main(String[] args) throws Exception {
//1.创建字节输出缓冲流
FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\buffer.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//2.写入文件
for (int i = 0;i<10;i++){
bos.write("helloworld \r\n".getBytes());//先写入缓冲区
bos.flush();//刷新到硬盘
}
//3.关闭(内部会调用fiush方法)
bos.close();
}
}
4.0对象流
ObjectOutputStream / ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串的功能
- 增强了读写对象的功能
readObject()
从流中读取一个对象writeObject(Object obj)
向流中写入一个对象
使用流传输对象的过程称为序列化、反序列化
5.0序列化与反序列化
package com.io;
import java.io.Serializable;
/**
* 学生类
*/
//Serializable :可序列化
//implements Serializable是一个标记接口,仅仅是告诉我们Student类可以序列化
public class Student implements Serializable {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
5.1序列化
package com.io;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
*使用ObjectOutputStream实现对象序列化
* 要求:序列化类必须实现Serializable接口
*/
public class Demo06 {
public static void main(String[] args) throws Exception{
//1.创建对象流
FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.实现序列化(写入操作)
Student zhangsan = new Student("zhangsan", 20);
oos.writeObject(zhangsan);
//3.关闭
oos.close();
System.out.println("序列化完毕");
}
}
5.2反序列化
package com.io;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* 使用ObjectInputStream实现反序列化
*
*/
public class Demo07 {
public static void main(String[] args) throws Exception{
//1.创建对象流
FileInputStream fis = new FileInputStream("D:\\java\\IO\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取文件(反序列化)
Student s = (Student) ois.readObject();
//3.关闭
ois.close();
System.out.println("执行完毕");
System.out.println(s.toString());
}
}
5.3注意事项
- 某个类要想序列化必须实现Serializable接口
- 序列化类中对象属性要求实现Serializable接口
- 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
- 使用transient修饰属性,这个属性就不能序列化 transient:瞬间的
- 静态属性不能序列化
- 序列化多个对象,可以借助集合来实现
6.0编码方式
UTF-8,GBK...
7.0字符流
7.1字符流的父类(抽象类)
reader
字符输入流
public int read(){}
public int read(char[] c){}
public int read(char[] b, int off, int len){}
Writer
字符输出流
public void write(int n){}
public void write(String str){}
public void write(char[] c){}
7.2文件字符流
- FileReader:
- public int read[char[] c] //从流中读取多个字符,将读到的内容存到c数组中,返回实际读到的字符数;如果达到文件底部,则返回-1
package com.io.demo;
import java.io.FileReader;
/**
* 使用FileReader读取文件
*
*/
public class Demo08 {
public static void main(String[] args) throws Exception{
//1.创建FileReader 文件字符输入流
FileReader fr = new FileReader("D:\\java\\IO\\hello.txt");
//2读取
//2.1单个字符读取
// int data = 0;
// while ((data = fr.read())!=-1){
// System.out.print((char) data); // 读取一个字符
// }
//2.2
char[] chars = new char[1024];// 字符缓冲区读取
int count = 0;
while ((count = fr.read(chars))!=-1){
System.out.println(new String(chars,0,count));
}
//3关闭
fr.close();
}
}
- FileWriter:
- public void write(String str) //一次写入多个字符,将b数组中所有字符写入输出流
package com.io.demo;
import java.io.FileWriter;
/**
* 使用FileWriter 写入文件
*/
public class Demo09 {
public static void main(String[] args) throws Exception{
//1.创建FileWriter对象
FileWriter fw = new FileWriter("D:\\java\\IO\\write.txt");
//2.写入
for (int i = 0;i<10;i++) {
fw.write("Java是世界上最好的语言\r\n");
fw.flush();
}
//3.关闭
fw.close();
System.out.println("执行完毕");
}
}
7.3(案例)使用上述内容进行文件文本复制
字符流不能复制图片或二进制文件,使用字节流可以复制任意文件
package com.io.demo;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
/**
* 使用FileReader 与 FileWriter复制文本文件,不能复制二进制数据
*/
public class Demo10 {
public static void main(String[] args) throws Exception{
//1.使用FileReader 与 FileWriter
FileReader fr = new FileReader("D:\\java\\IO\\write.txt");
FileWriter fw = new FileWriter("D:\\java\\IO\\write2.txt");
//2.读写
int data = 0;
while ((data = fr.read())!=-1){
fw.write(data);
fw.flush();
}
//3.关闭
fr.close();
fw.close();
System.out.println("复制完毕");
}
}
7.4字符缓冲流
- 缓冲流:BufferedReader / BufferedWriter
- 高效读写
- 支持输入换行符
- 可一次写一行读一行
1.BufferedReader
package com.io.demo;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* 使用字符缓冲流读取文件
* BufferedReader
*/
public class Demo11 {
public static void main(String[] args) throws Exception{
//创建缓冲流
FileReader fr = new FileReader("D:\\java\\IO\\write.txt");
BufferedReader br = new BufferedReader(fr);
//读取
//第一种方式
// char[] chars = new char[1024];
// int count = 0;
// while ((count = br.read(chars))!=-1){
// System.out.print(new String(chars,0,count));
// }
//第二种方式:一行一行读
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
//关闭
br.close();
}
}
2.BufferedWriter
package com.io.demo;
import java.io.BufferedWriter;
import java.io.FileWriter;
/**
* 使用BufferedWriter的使用
*/
public class Demo12 {
public static void main(String[] args) throws Exception{
//1.创建BufferedWrite对象
FileWriter fw = new FileWriter("D:\\java\\IO\\bw.txt");
BufferedWriter bw = new BufferedWriter(fw);
//2.写入
for (int i=0;i<10;i++){
bw.write("好好学习,天天向上");
bw.newLine(); //写入一个换行符,相当于 \r\n
bw.flush();
}
//3.关闭
bw.close();
System.out.println("执行完毕");
}
}
7.5PrintWrite
封装了print() / println()
方法 支持写入后换行
支持数据原样打印
package com.io.demo;
import java.io.PrintWriter;
/**
* PrintWriter的使用
*/
public class Demo13 {
public static void main(String[] args) throws Exception{
//1.创建打印流
PrintWriter pw = new PrintWriter("D:\\java\\IO\\print.txt");
//2.打印
pw.println(100);
pw.println(3.14);
pw.println(true);
pw.println("abc");
pw.println('你');
//3.关闭
pw.close();
System.out.println("执行完毕");
}
}
7.6转换流
桥转换流 InputStreamReader / OutputStreamWriter
可将字节流转换为字符流
可设置字符的编码方式
1.InputStreamReader
package com.io.demo;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* InputStreamReader读取文件,可以指定使用的编码
*/
public class Demo14 {
public static void main(String[] args) throws Exception{
//创建InputStreamReader对象
FileInputStream fis = new FileInputStream("D:\\java\\IO\\write.txt");
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
//读取文件
int data = 0;
while ((data = isr.read())!=-1){
System.out.print((char)data);
}
//关闭
isr.close();
}
}
2.OutputStreamWriter
package com.io.demo;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
/**
* 使用OutputStreamWriter写入文件,可以指定编码
*/
public class Demo15 {
public static void main(String[] args) throws Exception{
//创建OutputStreamWriter
FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\info.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
//写入
for (int i=0;i<10;i++){
osw.write("我是你爸爸\r\n");
osw.flush();
}
//关闭
osw.close();
System.out.println("执行完毕");
}
}
8.0 File类
- 概念:代表物理盘符中的一个文件或者文件夹
- 方法:
- createNewFile() //创建一个新文件
- mkdir() //创建一个新目录
- delete() //删除文件或空目录
- exists() //
- getAbsolutePath() //获取文件的绝对路径
- getName() //取得名字
- getParent() //获取文件/目录所在目录
- isDirectory() //是否Wie目录
- isFile() //是否为文件
- length() //获取文件长度
- listFiles() //列出目录中的所有内容
- renameTo() //修改文件名为
8.1文件操作
package com.io.demo;
import java.io.File;
import java.util.Date;
/**
* File类的使用
* (1)分隔符
* (2)文件操作
* (3)文件夹操作
*/
public class Demo16 {
public static void main(String[] args) throws Exception{
separator();
fileOpen();
}
//(1)分隔符
public static void separator(){
System.out.println("路径分隔符"+ File.pathSeparator);
System.out.println("名称分隔符"+ File.separator);
}
//(2)文件操作
public static void fileOpen() throws Exception{
//1.创建文件
File file = new File("D:\\java\\IO\\file.txt");
if (! file.exists()){ //exists()方法,判断文件是否存在
boolean b = file.createNewFile();//createNewFile()方法:如果文件创建成功,返回true,否则返回false
System.out.println("创建结果:"+b);
}
//2.删除文件
//2.1直接删除
// System.out.println("删除结果:"+file.delete());
//2.2 使用jvm退出删除
// file.deleteOnExit();
//3.获取文件信息
System.out.println("获取绝对路径" + file.getAbsolutePath());
System.out.println("获取路径" + file.getPath());
System.out.println("获取文件名称" + file.getName());
System.out.println("获取夫目录" + file.getParent());
System.out.println("获取文件长度" + file.length());
//判断
System.out.println("是否可写:"+file.canWrite());
System.out.println("是否是文件:"+file.isFile());
System.out.println("是否隐藏:"+file.isHidden());
}
}
8,2文件夹操作
//(3)文件夹操作
public static void directoryOpen() {
//1.创建文件夹
File file = new File("D:\\java\\aaa\\bbb");
System.out.println(file.toString());
if (!file.exists()){
// file.mkdirs();//只能创建单级目录
System.out.println("创建结果:"+file.mkdirs());//创建多级目录
}
//2.删除文件夹
//2.1直接删除
//只删除最里面的那个目录,而且该目录必须是空目录
// System.out.println("删除结果:"+file.delete());
//3.获取文件夹信息
System.out.println("获取绝对路径" + file.getAbsolutePath());
System.out.println("获取路径" + file.getPath());
System.out.println("获取文件名称" + file.getName());
System.out.println("获取父目录" + file.getParent());
System.out.println("获取文件长度" + file.length());
//4.判断
System.out.println("判断是否为文件夹:"+file.isDirectory());
System.out.println("是否隐藏:"+file.isHidden());
//5.遍历文件夹
File file1 = new File("D:\\图片");
String[] list = file1.list();
System.out.println("================================");
for (String s:list){
System.out.println(s);
}
8.3FileFilter 接口
-
public interface FileFilter
- boolean accept(File pathname)
-
但调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中
System.out.println("-------------FileFilter接口的使用--------------");
File[] files = file1.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".png")) {
return true;
}
return false;
}
});
for (File f:files){
System.out.println(f.getName());
}
8.4递归遍历文件夹
package com.io.demo;
import java.io.File;
/**
* 案例1:递归遍历文件夹
*/
public class ListDemo {
public static void main(String[] args) {
listDir(new File("D:\\java"));
}
public static void listDir(File directory){
File[] files = directory.listFiles();
System.out.println(directory.getAbsolutePath());
if (files!=null && files.length>0){
for (File file:files){
if (file.isDirectory()){
listDir(file);//递归
}
else {
System.out.println(file.getAbsolutePath());
}
}
}
}
}
8.5递归删除文件夹
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{
// 删除文件
sout(file.getAbsolutePath() + "删除" + file.delete());
}
}
}
}
9.0 Properties
- Properties:属性集合
- 特点:
- 1.存储属性名和属性值
- 2.属性名与属性值都是字符串类型
- 3.没有泛型
- 4.和流有关
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!