(注:本篇文章分为两个部分,如果想更为深刻的了解IO,请关注下一篇;欢迎大家学习讨论和批评指正)
将数据在虚拟机内存和本地磁盘之间进行传输
I:input 输入
O:output 输出
相当于管道,作用为进行数据传输
从传输方向上看
从传输单位上看
从传输功能上看
FileInputStream fis=new FileInputStream("本地的文件路径");
路径:
绝对路径:以电脑磁盘为基点的完整路径
FileInputStream fis = new FileInputStream("D:\\test\\a.txt");
FileInputStream fis = new FileInputStream("D:/test/a.txt");
相对路径:以当前项目路径为基点的路径,前提是文件必须在项目下
FileInputStream fis = new FileInputStream("file\\a.txt");
FileInputStream fis = new FileInputStream("file/a.txt");
路径书写必须截至至文件
文件必须存在,否则抛出异常
package com.by.test;
import java.io.FileInputStream;
public class TestFIS {
public static void main(String[] args)throws Exception {
// FileInputStream fis = new FileInputStream("D:\\test\\a.txt");
// FileInputStream fis = new FileInputStream("D:/test/a.txt");
// FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\Chp16\\file\\a.txt");
FileInputStream fis = new FileInputStream("file\\a.txt");
//FileInputStream fis = new FileInputStream("file/a.txt");
//读取一个字节
//利用循环读取文件所有内容
while (true) {
//先接收本次读取内容
int n = fis.read();
//判断读取是否到达末尾
if (n == -1) {
break;
}
//未到达末尾,输出查看
System.out.println((char) n);
}
//利用read(byte[])+循环读取文件所有内容
while (true) {
byte[] bs = new byte[3];
//接收本次读取结果
int n = fis.read(bs);
//判断读取是否到达末尾
if (n == -1) {
break;
}
//遍历数组查看本次读取结果
for (int i = 0; i < bs.length; i++) {
System.out.println(bs[i]);
}
}
//关流
fis.close();
System.out.println("执行成功!");
}
}
FileOutputStream fos=FileOutputStream("本地的文件路径",true|false);
package com.by.test;
import java.io.FileOutputStream;
public class TestFOS {
public static void main(String[] args)throws Exception {
FileOutputStream fos=new FileOutputStream("file/b.txt");
//写入一个字节
fos.write(65);
fos.write(66);
fos.write(67);
//写入一个数组
String str = "abcdefg123456";
byte[] bs = str.getBytes();
fos.write(bs);
//关流
fos.close();
System.out.println("执行成功!");
}
}
try(
//需要自动关流的创建语句
){
}catch(){
}
package com.by.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFOS2 {
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("file/b.txt");
){
//写入一个字节
fos.write(65);
fos.write(66);
fos.write(67);
//写入一个数组
String str = "abcdefg123456";
byte[] bs = str.getBytes();
fos.write(bs);
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败");
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
System.out.println("执行成功!");
}
}
package com.by.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class TestFileCopy {
public static void main(String[] args) {
copy1();
copy2();
}
/**
* 一次复制一个字节
*/
public static void copy1(){
try (
//创建输出节点流-复制到的文件路径
FileOutputStream fos=new FileOutputStream("d:/test/2.pdf");
//创建输入节点流-被复制的文件路径
FileInputStream fis=new FileInputStream("d:/test/1.pdf")
) {
//先循环读取文件所有内容
while (true) {
int n = fis.read();
if (n == -1) {
break;
}
//将本次读取的字节写入到目标文件
fos.write(n);
}
System.out.println("复制成功!");
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
/**
* 一次复制一个字节数组
*/
public static void copy2(){
try (
//创建输出节点流-复制到的文件路径
FileOutputStream fos=new FileOutputStream("d:/test/3.pdf");
//创建输入节点流-被复制的文件路径
FileInputStream fis=new FileInputStream("d:/test/1.pdf")
) {
//先循环读取文件所有内容
while (true) {
//创建数组
byte[] bs = new byte[1024];
//读取一个数组的数据
int n = fis.read(bs);
if (n == -1) {
break;
}
//将数组中的数据写入到目标文件
fos.write(bs);
}
System.out.println("复制成功!");
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
}
BufferedInputStream bis=new BufferedInputStream(fis对象);
BufferedOutputStream bos=new BufferedOutputStream(fos对象);
拥有一个内置的数据缓冲区, 文件数据将对接至数据缓冲区中,在缓冲区刷新或关闭时再将内部内容一并的给到目标文件
/**
* 一次复制一个字节+缓冲过滤流
*/
public static void copy3(){
try (
//创建输出节点流-复制到的文件路径
FileOutputStream fos=new FileOutputStream("d:/test/4.pdf");
//创建输入节点流-被复制的文件路径
FileInputStream fis=new FileInputStream("d:/test/1.pdf");
//添加缓冲过滤流
BufferedOutputStream bos=new BufferedOutputStream(fos);
BufferedInputStream bis=new BufferedInputStream(fis)
) {
//先循环读取文件所有内容
while (true) {
int n = bis.read();
if (n == -1) {
break;
}
//将本次读取的字节写入到目标文件
bos.write(n);
}
System.out.println("复制成功!");
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
如果先写后读,需要在写入完成后刷新缓冲区才能保证读取的正常进行
关流时外层过滤流关闭内层节点流会一并关闭
package com.by.test;
import java.io.*;
public class TestBuffered {
public static void main(String[] args) {
try(
//输出
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("file/a.txt"));
//输入
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("file/a.txt"))
){
//先写
bos.write("abcd".getBytes());
//刷新缓冲区
bos.flush();
//bos.close();
//再读
while (true) {
int n = bis.read();
if (n == -1) {
break;
}
System.out.println((char) n);
}
}catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
}
读取: ois.readXxx()
写入: oos.writeXxx(值);
注: Xxx对应的为基本类型名,首字母大写
package com.by.test;
import java.io.*;
public class TestObject_Double {
public static void main(String[] args) {
try (
//输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("file/c.txt"));
//输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("file/c.txt"))
) {
//先写
oos.writeDouble(10.5);
//强刷缓冲区
oos.flush();
//读取
System.out.println(ois.readDouble());
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
e.printStackTrace();
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
}
读取: Object ois.readObject() 读取到达末尾,抛出EOFException异常
写入: oos.writeObject(对象) 可以自动刷新缓冲区,所以先写后读时无需进行flush
package com.by.test;
import java.io.*;
public class TestObject_String {
public static void main(String[] args) {
try (
//输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("file/c.txt"));
//输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("file/c.txt"))
) {
//先写
oos.writeObject("床前明月光");
oos.writeObject("疑是地上霜");
oos.writeObject("举头望明月");
oos.writeObject("低头思故乡");
//后读
while (true) {
try {
String s =(String) ois.readObject();
System.out.println(s);
} catch (EOFException e) {
//读取到达末尾,跳出循环
break;
}
}
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
e.printStackTrace();
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
}
自定义类必须实现Serializable接口,表示允许被序列化,否则IO流没有读写权限
序列化:拆分对象信息的过程
反序列化:通过信息组装对象的过程
将属性通过transient修饰符修饰则可以防止其参与序列化
如果对象中有自定义类型的属性,则必须使该属性类型也实现序列化接口或者通过transient修饰符对其修饰
package com.by.entity;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
//防止被序列化
private transient double score;
// private Teacher tea;
//省略getter、setter、构造、toString
}
package com.by.test;
import com.by.entity.Student;
import java.io.*;
public class TestObject_Student {
public static void main(String[] args) {
try (
//输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("file/c.txt"));
//输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("file/c.txt"))
) {
//先写
oos.writeObject(new Student("zhangsan", 20, 88.5));
//后读
System.out.println((Student)ois.readObject());
} catch (FileNotFoundException e) {
System.out.println("文件路径不正确");
} catch (IOException e) {
System.out.println("读写失败!");
e.printStackTrace();
} catch (Exception e) {
System.out.println("未知异常!");
e.printStackTrace();
}
}
}
怎么理解输出语句?
System是类库中的工具类,out为该工具类中的静态属性,类型为标准输出流类型,print和println系列方法是该流中提供的写入方法,作用为向控制台写入一个内容