16.IO流(字节流,字符流,数据流、对象流)

I/O框架

1. IO框架介绍

I:input

O:output

流:

按数据流向划分:输入流、输出流

按处理单元划分:字节流,字符流

2. File类

2.1 File类构造方法

File类提供了用于操作文件和获取文件信息的一系列方法

1.File类的构造方法:

File(String pathname) :

File(File parent, String child): 根据父类路径名与子类路径名字字符串创建新的file实例(便于先处理父类路径);

File(String parent, String child): 与上式类似

2.2 File类常用方法(增删改查)

1.创建:

  • createNewFile()

  • mkdir() 创建文件夹

  • mkdirs() 创建多级文件夹,用\\或/隔开

  • renameTo(File dest) 重命名文件或文件夹,如果目标文件与源文件是在同一个路径下,那么renameTo的作用是重命名,如果目标文件与源文件不是在同一个路径下,那么renameTo的作用就是剪切,而且还不能操作文件夹。

注:

separatorChar:目录分隔符

separator包含一个separatorChar,字符串形式。

均是静态,File类直接调用

new File("C:" + File.separator + "a.txt");

2.删除:

  • delete() 删除文件或一个空文件夹(非空不能删),有返回值

  • deleteOnExit() 保证程序异常时创建的临时文件也可以被删除,无返回值,一般用于删除临时文件

3.判断

  • exists()

  • isFile()

  • isDirectory()

  • isAbsolute() 测试此抽象路径名是否为绝对路径名。

4.获取

  • getName()

  • getPath()

  • getAbsolutePath()

  • length()

  • lastModified() 获取最后一次被修改的时间(毫秒值)。

/**
 *  File类 提供了文件和目录相关的操作的方法
 *  位于java.io包
 * @author asus
 *
 */
public class TestFile {
    public static void main(String[] args) {
        File file = new File("A");
        file.mkdir(); // 创建一个文件夹 
        
        File files = new File("B/C/D");
        files.mkdirs(); 
        file.delete();
        files.delete(); // B 文件夹中有内容 不能删除    
        File file1 = new File("a.txt"); // 相对路径 相对于我们当前操作的目录而言的路径
        File file2 = new File("C:\\Users\\WHD\\Desktop\\test.txt"); // 绝对路径 具体的路径
        try {
            file1.createNewFile(); // 返回值 true表示创建成功  false表示创建失败
            file2.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        System.out.println("a.txt文件是否存在" + file1.exists());
        System.out.println("a.txt文件的相对路径" + file1.getPath());
        System.out.println("a.txt文件的绝对路径" + file1.getAbsolutePath());
        System.out.println("a.txt文件的大小" + file1.length());
        System.out.println("a.txt文件的名称" + file1.getName());
        System.out.println("a.txt是否是一个文件" + file1.isFile());
        System.out.println("a.txt是否是一个文件夹" + file1.isDirectory());
        System.out.println("是否删除成功" + file1.delete());
    }
}

3.字节流

3.1 FileInputStream

父类abstract InputStream

子类FileInputStream:基于字节的文件输入流

int read():每次读取一个字节,返回值是读取的内容的ascii码

int read(byte[] datas): 可以读取指定数组长度的内容,返回值是每次读取的长度,读取的内容存放在数组中,可以使用String类构造方法来封装为字符串 new String(byte[], int offset, int length);

int available(): 可读取的剩余字节数,即容量


/**
 *  字节输入流
 *  read() 每次读取一个字节
 *  read(byte[] datas) 读取一个byte数组 返回值是读取的长度
 * @author asus
 *
 */
public class TestFileInputStream3 {
    public static void main(String[] args) throws IOException {
        File file = new File("a.txt");
        file.createNewFile();
            
        FileInputStream fis = new FileInputStream(file);
        System.out.println(fis.available());
//      byte [] datas = new byte[100];
        byte [] datas = new byte[fis.available()];
        int dataCount = -1;
        while((dataCount = fis.read(datas)) != -1){
//          System.out.println(dataCount);
            System.out.println(new String(datas, 0, dataCount));
        }   
    }
}

3.2 FileOutputStream

父类 abstract OutputStream

void write():每次写入一个字节

void write(byte[] datas):写入一个byte数组,可以使用String类的getBytes()方法将字符串转换为byte数组

支持的参数为byte数组和int

flush() :将内容从缓存中刷新到文件中。close会自动调用。字节流中不是必须的,但字符流必须刷新

close():关闭资源

/**
 *  字节输出流 
 * @author asus
 *
 */
public class TestFileOutPutStream2 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("c.txt", true);
            String str = "床前明月光,疑是地上霜,举头望明月,低头思故乡";
            byte [] datas = str.getBytes();
            fos.write(97);
            fos.write(datas);
            fos.flush(); // 将缓存中的内容刷新到文件
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.字符流

字符流若未关闭资源,必须手动调用flush,否则不会写出资源

4.1输入字符流(3种,含缓冲流Bufferedxxx)

父类:abstract Reader

1.子类FileReader:基于字符的文件输入流

int read():每次读取一个字符

int read(char[] datas):每次读取char数组长度的内容,返回值是读取的长度,读取的内容存放在数组中。(若要直接打印,可能出现字节增大,但也可以通过设置数组长度为available避免),最好的方式是new一个新的String来输出。

2.子类:BufferedReader:基于字符的输入缓冲流

在以上方法的基础上还有:

readLine() :每次读取一行

close():关闭资源

3.子类: inputStreamReader:可以指定编码格式的字符输入流 

字节流到字符流的桥梁,BufferedReader创建时需要Reader,InputStreamReader即是Reader的子类,可传它,且InputStreamReader创建时可传字节流) 多态

/**
 * 字符读取流  一次读取一个字符  也可以读取一个字符数组
 * 字符是16位   unicode编码
 * 字节   8位  byte ascii 
 * @author asus
 */
public class TestFileReader2 {
    public static void main(String[] args) {
        FileReader fReader = null;
        try {
            fReader = new FileReader("c.txt");
            char [] datas = new char[100];
            int dataCount = -1;
            while((dataCount = fReader.read(datas)) != -1){
                //System.out.println(dataCount);
                //System.out.println(datas);//若字符长度设为available即,剩余字节数,可正常打印,
                                            //否则可能打印多余的内容。即最后一次未读满,倒数第二次读的部分内容仍被输出
                System.out.println(new String(datas,0,dataCount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fReader != null){
                try {
                    fReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 * 带有缓冲流的字符读取流
 * 可以读取一个字符  也可以一次读取一行
 * readLine()
 * @author asus
 *
 */
public class TestBufferedReader2 {
    public static void main(String[] args) {
        FileReader fr = null;
        BufferedReader bReader = null;
        try {
            fr = new FileReader("c.txt");
            bReader = new BufferedReader(fr);
            int data = -1;
            while((data = bReader.read()) != -1){
                System.out.println((char)data);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bReader != null){
                try {
                    bReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
 *  乱码出现的原因:
 *  编码的方式和解码的方式不一致 
 *  解决方式:
 *  1.统一编码
 *  2.可以将出现乱码的内容打散(iso-8859-1) 按照我们自己的编码方式组合
 *  常见的编码格式:
 *  GBK 国标扩展板   简体和繁体
 *  GB2312 国标版本 只支持简体
 *  ISO-8859-1 最原始的编码方式 通常用于解决乱码
 *  UTF-8 unicode万国码 包含世界大多数国家的语言编码
 *  ANSI 不具体指定某一种编码 因为在不同的操作系统上 表示对应的编码 比如 win10中文版 GBK 
 * @author asus
 */
public class TestInputStreamReader {
    public static void main(String[] args) {
        FileInputStream fis = null;
​
        try {
            fis = new FileInputStream("testCode.txt");
            InputStreamReader isr = new InputStreamReader(fis,"GBK");
            char []datas = new char[100];
            int dataCount = -1;
            while((dataCount  = isr.read(datas)) != -1) {
                System.out.println(new String(datas,0,dataCount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭资源
        }
    }
}

4.2输出字符流(3种,含缓冲流Bufferedxxx)

父类:abstract writer

1.子类:FileWriter

new实例时末尾添加true,表示在文本末尾追加内容

writer() : 每次写入一个字符

write(char [] datas):每次写入一个char数组

write(String str):每次写入一个字符串

2.子类:BufferedWriter

write():每次写入一个字符

write(char[] datas):每次写入一个char数组

write(String str) 每次写入一个字符串,也可设置起始位置

newLine():换行

3.子类:OutputStreamWriter 可指定编码的字符输出流

字节流到字符流的桥梁,BufferedWriter创建时需要Writer,OutputStreamWriter即是Writer的子类,可传它,且OutputStreamWriter创建时可传字节流)

write():每次写入一个字符

write(char [] datas):每次写入一个char数组

write(String str):每次写入一个字符串,也可设置起始位置

/**
 *  字符缓冲流写入流
 *  可以写入一个字符 或者字符串
 *  还可以换行
 *  newLine()
 * @author asus
 *
 */
public class TestBufferedWritet {
    public static void main(String[] args) {
        FileWriter fWriter = null;
        BufferedWriter bWriter = null;
        try {
            fWriter = new FileWriter("e.txt",true);
            bWriter = new BufferedWriter(fWriter);
            bWriter.write("hello word1");
            bWriter.newLine();
            bWriter.write("hello world2");
            bWriter.flush();//与字节流不同。。。不刷新或关闭资源不显示
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bWriter !=null){
                try {
                    bWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fWriter != null){
                try {
                    fWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 * @author asus
 */
public class TestFileWriter {
    public static void main(String[] args) {
        FileWriter fWriter =null;
        try {
            fWriter  = new FileWriter("d.txt", true);
            fWriter.write("hello word2\n");
            
             // 将缓存中的内容刷新到文件
            fWriter.flush();//与字节流不同,若为关闭资源,必须刷新内容,否则不显示
        
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            /*if(fWriter != null){
                try {
                    fWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }*/
        }   
    }
}
public class TestOutputStreamWriter {
	public static void main(String[] args) {
		FileOutputStream fos;
		try {
			fos = new FileOutputStream("f.txt");
			OutputStreamWriter osw = new OutputStreamWriter(fos);
			osw.write("hello world");
			osw.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

5.数据流(二进制,依赖并属于字节流)

数据流属于字节流,用于读取二进制文件,比如图片、音频、视频等。。。。。

DataInputStream:基于字节的二进制文件输入流,读入只有byte存

DataOutputStream:基于字节的二进制文件输出流,输出有byte数组,或字符串,或字符多种形式

/**
 * DataInputStream  负责读取二进制文件
 * DataOutPutStream 负责写入二进制文件
 * @author asus
 */
public class TestDataStream {
	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		DataInputStream dis = null;
		DataOutputStream dos = null;
		
		try {
			fis = new FileInputStream("D:\\图片.png");
			dis = new DataInputStream(fis);
			fos = new FileOutputStream("copy2.png");
			dos = new DataOutputStream(fos);
			byte [] datas = new byte[fis.available()];
			int dataCount = -1;
			while((dataCount = dis.read(datas)) != -1){
				//dos.write(datas, 0, dataCount);
				dos.write(datas);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
            //关闭资源
        }
}

6.对象流(依赖并属于字节流)

对象流属于字节流,用于输入对象和输出对象

ObjectOutputStream-序列化:将对象以二进制的形式存储在文件中 readObject()

ObjectInputStream-反序列化:将保存有对象的二进制文件读取出来转换为对象 writeObject

序列化要求:被序列化的对象必须实现Serializable接口,此接口是空接口,相当于一个标识,实现此接口的类才可以序列化

/**
 * ObjectInputStream  对象输入流
 * ObjectOutputStream 对象输出流
 * 序列化:将对象写入到文件中
 * 反序列化:将存有对象的文件读取出来生成对象
 * @author asus
 *
 */
public class TestObjectStream {
	public static void main(String[] args) {
		FileOutputStream fos = null;
		ObjectOutputStream oos = null;
		FileInputStream fis = null;
		ObjectInputStream ois = null;

		try {
			fos = new FileOutputStream("stu.txt");
			oos = new ObjectOutputStream(fos);
			Student stu1 = new Student("赵四", 20);
			Student stu2 = new Student("广坤", 21);
			Student stu3 = new Student("大拿", 22);
			oos.writeObject(stu1);
			oos.writeObject(stu2);
			oos.writeObject(stu3);

			fis = new FileInputStream("stu.txt");
			ois = new ObjectInputStream(fis);
			while(fis.available() > 0){
				Object obj = ois.readObject();
				if(obj instanceof Student){
					Student stuRead = (Student) obj;
					System.out.println(stuRead);
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
            //关闭资源
	}
}
/**
 * Serializeable 空接口 相当于一个标识 标识此接口的类才能被序列化化
 * @author asus
 */
public class Student implements Serializable{
	private String name;
	private int 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;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

每日问题

1.判断是否是文件

2.判断是否是目录

3.判断是否存在

4.删除文件的方法

5.文件的相对路径

6.文件的绝对路径

7.FileInputStream是什么流?

8.字节写入流是哪个对象?

9.字节流写入的方法是什么,支持参数是什么?

10.FileInputStream如何使每次读取两个字节

11.读取图片应该使用什么对象?

12.BufferedReader独有的读取文件的方法是什么

13.什么是序列化,什么是反序列化,序列化的对象有什么要求

14.实现序列化的步骤是什么

15.写入对象使用哪个对象的哪个方法

16.读取一个对象是什么方法

解答:

1.判断是否是文件 isFile();

2.判断是否是目录 isDirectory();

3.判断是否存在 exists()

4.删除文件的方法 delete();

5.文件的相对路径 getPath();

6.文件的绝对路径 getAbsolutePath();

7.FileInputStream是什么流? 字节读取流

8.字节写入流是哪个对象? FileOutputStream

9.字节流写入的方法是什么,支持参数是什么?

      write(); byte数组      int num 显示对应的ascii

10.FileInputStream如何使每次读取两个字节

      byte [] datas = new byte[2]; read(byte[] datas); 返回值是每次读取的长度,内容存放在datas数组中

11.读取图片应该使用什么对象? DataInputStream

12.BufferedReader独有的读取文件的方法是什么 readLine();

13.什么是序列化,什么是反序列化,序列化的对象有什么要求

     将对象以二进制的形式存储在 文件中 将存储有对象的二进制文件读取出来转化为对象 实现Serializable

14.实现序列化的步骤是什么

     先实现Serializable接口,然后使用ObjectOutputStream写入对象,再使用 ObjectInputStream读取对象 15.写入对象使用哪个对象的哪个方法 使用ObjectOutputStream写入对象,writeObject()

16.读取一个对象是什么方法 readObject();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值