io流
27.1 file文件
概念:File对象是将平时所用到的关于文件相关的操作进行的封装,方便使用
用途:创建及删除文件、目录等,改文件名,查看文件、获取文件路径地址
演示1:创建文件对象
public static void createMethod() throws IOException {
//创建文件对象,需要指定文件所在的路径
File file = new File("F:\\cerateFile.txt");
//判断文件是否已存在
if(file.exists()) {
//如果已经有该文件,就会先删除文件
file.delete();
}
//创建文件
file.createNewFile();
}
此时在f盘中就会创建成功一个以cerateFile命名的txt类型文件
演示2:创建目录/文件夹
public static void creatFileMethod() {
//创建目录
File file = new File("F:/file/text");
//创建单级目录
//file.mkdir();
//创建多级目录
file.mkdirs();
演示3:判断文件类型及权限
/**
* 判断文件类型及权限
*/
public static void powerMethod() {
File file = new File("F:\\cerateFile.txt");
System.out.println("判断文件是否可读:"+file.canRead());
System.out.println("判断文件是否可写:"+file.canWrite());
System.out.println("判断是否是目录:"+file.isDirectory());
System.out.println("判断是否是文件:"+file.isFile());
演示4:获取指定目录下的第一级文件名列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jd1BDxWp-1606143288391)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201123194204194.png)]
public static void getFileList() {
File file = new File("D:\\java课件");
//获取指定目录下的所有文件的抽象路径名
String[] filelist = file.list();//返回的是一个字符串数组
for(int i=0 ; i<filelist.length;i++) {
System.out.println(filelist[i]);
}
}
递归: 获取c盘下的所有文件名称
public static void main(String[] args) throws IOException {
getFileListMethod("C:");
}
/**
* 需求:获取指定路径下所有文件的名字
* 递归:自己调用自己,要求必须要有结束的条件
* 递归一定要有出口
* @param path
*/
public static void getFileListMethod(String path) {
File file = new File(path);
File[] files = file.listFiles();
//因为可能存在某些文件夹是空的,此时获取到的文件列表对象就是null对象
//判断是否为空
if(files != null) {
for(int i=0;i<files.length;i++) {
//判断当前的文件对象是否是文件
if(files[i].isFile()) {
System.out.println(files[i].getName()); //出口
}else {//该文件是目录 获取到子目录的地址 重复之前的动作
String filePath = files[i].getPath();
getFileListMethod(filePath);
}
}
}
}
27.2 io流
1.概念:计算机识别的是二进制,在计算机中的操作都是以流的形式进行的
IO流分字节流和字符流,字符流是由字节流组成的,最小单位是b(字节)
2…常用流: InputStream 字节输入流 OutputStream字节输出流
FileInputStream 字节输入流的子类 FileOutputStream字节输出流的子类
Reader 读 Writer 写 FileReader FileWriter
/**
* 需求:向E:/stream.txt文件中写入内容--hello world
* 1、创建文件E:/stream.txt
* 2、使用流写内容
* 3、保存
* @throws IOException
*/
public static void writeMethod() throws IOException {
File file = new File("E:/stream.txt");
//创建OutputStream进行写动作,因为是要进行文件的流操作,所以要使用FileOutputStream对象
OutputStream os = new FileOutputStream(file);
//开始写 将字符串转换为字节数组
os.write("hello world".getBytes());
//换行要使用\r\n
os.write("\r\n".getBytes());
os.write(18);
//通常来讲,写完之后需要进行保存,但是字节流可以自动保存,强调:流的使用一定要关闭
os.close();
}
27.3 字节流
读取操作:
1.读取到缓冲区的总字节数,如果到达流末尾,就会返回-1
2.有两种方案可以给地址
2.1通过File给地址 可以再转换为流之前做相关的增删改查处理
2.2采用字符串形式直接给地址
3.一个字母活一个数字占一个字节,一个中文占两个字节
/**
* 需求:将指定文件的内容读取出来在控制台打印
*
* FileInputStream()
* @throws IOException
*/
public static void inputStreamMethod() throws IOException {
//将地址包装成流对象
InputStream is = new FileInputStream("E:/stream.txt");
int temp = 0; //定义一个temp来接收读取到的结果,不然循环调用read方法,会变成死循环
//读取内容
while((temp = is.read()) != -1) {//到结尾时报-1,代表运行结束
System.out.println((char)temp); // 接收的int类型强转为char类型,输出字符
}
//关闭流
is.close();
}
4.使用缓冲区读写: 提高效率
public static void inputStreamMethod2() throws IOException {
//将地址包装成流对象
InputStream is = new FileInputStream("E:/stream.txt");
//先定义一个缓冲区,流是先将内容读取到了缓冲区中
byte[] bcuf = new byte[1024];
//available()拿到整个文档的大小--这种方式不合适
//byte[] bcuf = new byte[is.available()];
//读内容
while(is.read(bcuf) != -1) {
System.out.println(new String(bcuf));
}
//关闭流
is.close();
}
27.4字符流
1.字符流中的两个超类:Reader Writer
2.跟文件相关的两个子类:FileReader FileWriter
3.字节流底层使用的是字节,字符流底层使用的是字符
4.字符流写功能,字符流在写的时候一定要进行刷新才会被保存,因为默认在每次写的时候都是从头开始写,会覆盖掉以前的内容
5.写完之后要调用flush刷新
/**
* @throws IOException
*/
public static void writeMethod() throws IOException {
//指定要写的位置,包装成字符流对象
Writer writer = new FileWriter("E:/writer.txt",true);
writer.write(5678);
writer.write("张三");
//writer.flush();
writer.write(1234);
writer.write("王麻子");
//writer.flush();
writer.close();
}
6.字符流的读取:
/**
* 单个字符读取
* @throws IOException
*/
public static void readMethod() throws IOException {
Reader reader = new FileReader("E:/writer.txt");
//System.out.println((char)reader.read());
//System.out.println((char)reader.read());
int temp = 0;//创建变量接收
while((temp=reader.read())!=-1) {
System.out.println((char)temp);//默认为int类型,强转为char类型
}
reader.close();
}
7.使用缓冲池读取
使用字符数组作为缓冲池进行读取时,会出现显示多余或不完整的情况
/**
* @throws IOException
*/
public static void readMethod2() throws IOException {
Reader reader = new FileReader("E:/writer.txt");
//定义一个缓冲区
char[] cbuf = new char[3];
while(reader.read(cbuf)!=-1) {
System.out.println(new String(cbuf));
}
reader.close();
}
27.5字符串缓冲池:
1. String是一个字符串对象,是一个常量
2. StringBuilder(线程不安全) StringBuffer(线程安全)
3.两个缓冲池只有在是否安全上有区别,其他都一样
-
String、StringBuilder 、StringBuffer之间的区别:
答:String是常量, StringBuilder和StringBuffer修饰的是变量
StringBuilder是线程不安全,但是效率高
StringBuffer是线程安全,但是效率相对较慢
字符串缓冲池;
Reader reader = new FileReader("E:/writer.txt");
//创建字符串缓冲池对象
StringBuilder sb = new StringBuilder();
char[] cbuf = new char[3];
while(reader.read(cbuf)!=-1) {
sb.append(cbuf);//append方法将参数附加到次序列中
}
System.out.println(sb);
reader.close();
}
27.6字符流缓冲对象
1.字符流缓冲对象读取
类:BufferedReader BufferedWriter
2.字符流写对象:
public static void bufferedWriterMethod(){
//创建字符流写的对象
Writer writer = new Writer("E:/writer.txt");
//创建字符流写的对象 -需要字符流写对象
BufferedWriter bw = new bufferedWriter(writer);
bw.writer("hahahahahaah");
bw.close();
writer.close();
}
3.字符流读对象:
public static void bufferedReaderMethod() throws IOException {
//创建字符流读取对象-需要文件路径
Reader reader = new FileReader("E:/writer.txt");
//创建字符流缓冲对象-需要一个字符流读对象
BufferedReader br = new BufferedReader(reader);
String result = null;//创建一个接收对象,默认为空
//按行读取
while((result = br.readLine()) != null) {//当result不为空时,输出result
System.out.println(result);
}
//关闭流对象--倒着关
br.close();
reader.close();
}
27.7字符串缓冲对象
1.持久化存储:就是将数据进行本地存储,可以多次使用
2.默认序列化机制只能写入类、类签名、非瞬态及非静态的字段
3.写对象:ObjectOutputStream
读对象:ObjectinputStream
4.实现Serializable的过程称为序列化,进行读取的过程称为反序列化
/**
* Serializable接口
* 在进行写的过程中虚拟机会随机生成一个序列化版本号用于唯一标识
* 但是,当类中的内容发生了改变时,再进行自写入时序列化版本号也会重新生成
*
* 想避免上述的问题,让序列号一致即可(手动添加一个)
*/
public class Item implements Serializable{
private static final long serialVersionUID = 1234879785L;
private String itemName;
private double price;
private String brand;
//private static String test;
//transient所修饰的变量称为瞬态变量
private transient String test;
public Item() {}
public Item(String itemName, double price, String brand) {
super();
this.itemName = itemName;
this.price = price;
this.brand = brand;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public String toString() {
return "Item [itemName=" + itemName + ", price=" + price + ", brand=" + brand + "]";
}
}
写对象:ObjectOutputStream
在进行写对象的时候,文件通常是以.object为结尾的,演示的过程中使用.txt方便查看
public static void writerMethod() throws IOException {
//指定写入的地址
File file = new File("E:/object.txt");
//创建一个用于写的流对象
OutputStream os = new FileOutputStream(file);
//创建写对象的对象流
ObjectOutputStream oos = new ObjectOutputStream(os);
//创建要存储的对象
Item item = new Item("咖啡",35,"星巴克");
Item item2 = new Item("奶茶",12.5,"coco");
//写对象
oos.writeObject(item);
oos.writeObject(item2);
//关闭流对象
oos.close();
os.close();
}
读对象:
/**
* @throws IOException
* @throws ClassNotFoundException
* 类找不到异常
*/
public static void readerMethod() throws IOException, ClassNotFoundException {
//指定读取的地址
File file = new File("E:/object.txt");
//创建一个用于读的流对象
InputStream is = new FileInputStream(file);
//创建读对象的对象流
ObjectInputStream ois = new ObjectInputStream(is);
/*//读对象
Object object = ois.readObject();
Item item = (Item)object;
System.out.println(item);
Object object2 = ois.readObject();
Item item2 = (Item)object2;
System.out.println(item2);*/
try { //添加try{}catch(){}捕获结尾
//Object obj = null; 定义一个object为空
while((obj=ois.readObject())!=null) {
System.out.println((Item)obj);//强制转换为item类型
}
//EOFException 当读取到文件或流的末尾时抛出该异常
}catch(EOFException e) {
System.out.println("读取完毕");
} finally {
//关闭流
ois.close();
is.close();
}
}
面试题:说一说序列化和反序列化的机制:
答:序列化就是讲对象通过流的形式写入到文件中进行持久化存储的过程
反序列化就是通过流的形式从文件中奖对象读取出来转换为实体类进行使用
27.8流转换
1.流转换就是字节流和字符流之间的转换
2.字节流在读取的过程中效率高,针对某些问题(中文乱码,空间浪费等)不好处理,此时就需要将其转换字符流
字符流在读取的过程中效率低且有局限性(音频、视频等),此时就需要将其转换为字节流
3.相关类:InputStreamReader 字节流转字符流
OutputStreamWriter 字符流转字节流
/**
* 获取控制台输入的内容,再将其输出到控制台
*/
public class IOChangeDemo {
public static void main(String[] args) throws IOException {
//拿到控制台的输入流对象
InputStream is = System.in;
//将字节流对象转换为字符流对象进行读取操作
InputStreamReader isr = new InputStreamReader(is);
//使用字符缓冲流对象按行读取
BufferedReader br = new BufferedReader(isr);
//将读取到的结果输出到控制台
OutputStream os = System.out;
//创建字节流对象进行写操作
OutputStreamWriter osw = new OutputStreamWriter(os);
while(true) {
//从控制台进行读取操作
String content = br.readLine();
if("over".equals(content)) {
break;
}
//向控制台写内容
osw.write(content);
osw.flush();
}
//关闭流
osw.close();
os.close();
br.close();
isr.close();
is.close();
}
}
流转换常用的方法
public class SystemDemo {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());//返回当前时间,用于计算程序的运行时间
System.out.println(new Date().getTime());
System.out.println(System.getProperties());//查看电脑系统配置
}
}