IO流
一,文件
文件可认为是相关记录或放在一起的数据的集合
File类访问文件属性
public class FileTest {
public static void main(String[] args) throws IOException {
//声明对象 File.separator系统分隔符
File file=new File("D:"+File.separator+"Download"+
File.separator+"c.png");
//判断文件是否存在
boolean flag= file.exists();
System.out.println("文件存在?"+flag);
//创建名称的空文件,不创建文件夹
file.createNewFile();
//删除
file.delete();
}
}
public class FileTest02 {
public static void main(String[] args) {
File file=new File("b.png");
//创建文件夹,必须有父目录
//file.mkdir();
//创建文件夹,不管有没有父目录,会自动创建父目录
//file.mkdirs();
//相对路径:相对于当前文件的路径
System.out.println("相对路径:"+file.getPath());
//绝对路径:文件在硬盘中的位置
System.out.println("绝对路径:"+file.getAbsolutePath());
System.out.println("名称:"+file.getName());
System.out.println("是否是文件?"+file.isFile());
System.out.println("是否是目录?"+file.isDirectory());
System.out.println("文件长度(所占字节数):"+file.length());
//重命名
//file.renameTo(new File("a.png"));
}
}
文件过滤器
package com.sk.test;
import java.io.File;
import java.io.FilenameFilter;
/**
* ClassName: FileFTest <br/>
* Description: <br/>
* date: 2021/12/20 9:23<br/>
* 图片过滤
* @author 斑马<br />
*/
public class FileFTest {
public static void main(String[] args) {
File f=new File("C:\\Users\\斑马\\Desktop");
File[] files= f.listFiles(new A());
for (File ff:files){
System.out.println(ff.getAbsolutePath());
}
}
}
/**过滤规则*/
class A implements FilenameFilter{
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".png")||name.endsWith(".jpg");
}
}
二,IO流
1.流的分类![](https://img-blog.csdnimg.cn/4d0bb675fd7d4d59a450cbc62d5c30be.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5paR6ams5LiN556M552h,size_20,color_FFFFFF,t_70,g_se,x_16)
2.IO流的操作步骤
1.使用File找到一个文件 2.使用字节流或字符流的子类为OutputStream、InputStream、Writer、Reader进行实例化操作 3.进行读或写的操作 4.关闭流:close().在流的操作中最终必须关闭
3.FileInputStream和FileOutputStream
package com.sk.test;
import java.io.*;
/**
* ClassName: FileOut <br/>
* Description: <br/>
* date: 2021/12/20 10:20<br/>
*
* @author 斑马<br />
*/
public class FileOut {
/**写入*/
public static void out(){
//1.使用File找到一个文件
File file=new File("D:\\Download\\a.txt");
//2.使用字节流或字符流的子类为OutputStream、InputStream、Writer、Reader进行实例化操作
OutputStream out=null;
try {
out=new FileOutputStream(file);
//3.进行读或写的操作
String str="hello word!";
out.write(str.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭流:close().在流的操作中最终必须关闭
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**读取*/
public static void in(){
File f=new File("D:\\Download\\a.txt");
InputStream in=null;
try {
in=new FileInputStream(f);
//byte数组
byte[] b=new byte[(int) f.length()];
in.read(b);
String str=new String(b);//把数组转换成字符串
System.out.println(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//out();
in();
}
}
4.自动关闭文件
JDK8增加了一个新特性 ,该特性提供了另外 一种管理资源(例如文件流)的方式,这种 方式能自动关闭文件 。这个特性有时被称为自动资源管理( Automatic Resource Management , ARM),该特性以try语句的扩展版为基础。自动资源管理的主要优点是:当不再需要文件(或 其他资源)时 ,可以防止无意中忘记释放它们 。正如前面所解释的,忘记关闭文件可能导致内 存泄露 ,并且可能导致其他问题
package com.sk.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* ClassName: TryTest <br/>
* Description: <br/>
* date: 2021/12/20 14:16<br/>
*
* @author 斑马<br />
*/
public class TryTest {
public static void main(String[] args) {
//1.读取
File file=new File("D:\\Download\\a.txt");
byte[] b=new byte[(int) file.length()];
//(需要自动关闭的资源)
try (FileInputStream in=new FileInputStream(file);){
in.read(b);
System.out.println(new String(b));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.字符流读写文件
package com.sk.test;
import java.io.*;
/**
* ClassName: FileReaderTest <br/>
* Description: <br/>
* date: 2021/12/20 14:29<br/>
*格式模版保存在文本文件pet.template中,内容如下:
您好!
我的名字是{name},我是一只{type}。
我的主人是{master}。
其中{name}、{type}、{master}是需要替换的内容,现在要求按照模板格式保存宠物数据到文本文件,即把{name}、{type}、{master}替换为具体的宠物信息,该如何实现呢?
* @author 斑马<br />
*/
public class FileReaderTest {
/**写入*/
public static void out(String str){
try (FileWriter out=new FileWriter("D:\\Download\\c.txt");){
out.write(str);
} catch (IOException e) {
e.printStackTrace();
}
}
/**读取*/
public static char[] in(){
File f=new File("D:\\Download\\c.txt");
char[] c=null;
try (FileReader in=new FileReader(f)){
c=new char[(int) f.length()/2];
in.read(c);
System.out.println(c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return c;
}
public static void main(String[] args) {
char[] c=in();
String str="";
for (int i=0;i<c.length;i++){
str+=c[i];
}
out(str);
}
}
6.BufferedReader和BufferedWriter
package com.sk.test;
import java.io.*;
/**
* ClassName: BufferTest <br/>
* Description: <br/>
* date: 2021/12/20 15:12<br/>
*
* @author 斑马<br />
*/
public class BufferTest {
/**读取*/
public static void in(){
try (Reader reader = new FileReader("D:\\Download\\c.txt");
BufferedReader in=new BufferedReader(reader);) {
//读取一整行
//System.out.println(in.readLine());
for(;;){
String str=in.readLine();
if(str==null){
break;
}
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void out(){
try (Writer writer = new FileWriter("D:\\Download\\c.txt");
BufferedWriter out=new BufferedWriter(writer);) {
out.write("你好,张三!\n");
//out.newLine();
out.write("你好,李四!");
out.newLine();//另起一行(换行)和\n效果一样
out.write("你好,李四2!");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
out();
in();
}
}
7.读写二进制文件
package com.sk.test;
import java.io.*;
/**
* ClassName: DateTest <br/>
* Description: <br/>
* date: 2021/12/20 15:55<br/>
*
* @author 斑马<br />
*/
public class DateTest {
/**写*/
public static void out(){
try (OutputStream os=new FileOutputStream("D:\\Download\\a.class");
DataOutputStream out=new DataOutputStream(os);){
out.writeInt(1233);
out.writeFloat(12.3f);
out.writeUTF("张三");
} catch (Exception e) {
e.printStackTrace();
}
}
/**读取*/
public static void in(){
try (InputStream is = new FileInputStream("D:\\Download\\a.class");
DataInputStream in = new DataInputStream(is);) {
System.out.println(in.readInt());
System.out.println(in.readFloat());
System.out.println(in.readUTF());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
out();
in();
}
}
总结:流的分类
输入流/输出流 按流与程序的关系分。 字节流/字符流 按流中处理的数据是以字节(8位)为单位还是以字符(16位)为单位分为字节流和字符流。 Java中字节流和字符流分属两个不同的体系。 节点流/过滤流 按流与原始数据载体(文件,设备)的关系分为节点流和过滤流。
节点流(Node Stream) :直接与原始数据存在的特定介质(如磁盘文件或其他外部设备、内存某区域或其他程序)打交道的流,在流的序列中离程序最远。 过滤流 (Filter Stream):使用其它的流作为输入源或输出目的地,对流中的数据提供进一步处理的流。其他的流可以是节点流,也可以是另一种过滤流。过滤流不能单独使用。 一个输入流链或输出流链中一定有且只有一个节点流;可以没有,也可以有多个过滤流。
8.对象流
ObjectInputStream ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。 只能将支持 java.io.Serializable 接口的对象写入流中。 ObjectOutputSteam ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化
1.序列化
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
public class Pet implements Serializable {
//Serializable代表可以被序列化 ,没有方法需要实现
private String name;
private int age;
@Override
public String toString() {
return "Pet{" +
"name='" + name + '\'' +
", 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;
}
public Pet(String name, int age) {
this.name = name;
this.age = age;
}
}
2.通过对象流实现对象的存取
public class PetTest {
/**写入*/
public static void write(){
Pet p=new Pet("张三",12);
try (OutputStream os = new FileOutputStream("D:\\Download\\pet.data");
ObjectOutputStream out=new ObjectOutputStream(os);) {
//把对象写入
out.writeObject(p);
} catch (Exception e) {
e.printStackTrace();
}
}
/**读取*/
public static void read(){
try (InputStream is = new FileInputStream("D:\\Download\\pet.data");
ObjectInputStream in = new ObjectInputStream(is);) {
//返回值类型是Object
Object o=in.readObject();
Pet p= (Pet) o;
System.out.println(p);
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
write();
read();
}
}
3.存取集合
/**写入*/
public static void write(){
Pet p=new Pet("张三",12);
Pet p1=new Pet("张三1",12);
Pet p2=new Pet("张三2",12);
List<Pet> list=new ArrayList<>();
list.add(p);
list.add(p1);
list.add(p2);
try (OutputStream os = new FileOutputStream("D:\\Download\\pet.data");
ObjectOutputStream out=new ObjectOutputStream(os);) {
//写入对象的集合
out.writeObject(list);
} catch (Exception e) {
e.printStackTrace();
}
}
/**读取*/
public static void read(){
List<Pet> list=null;
try (InputStream is = new FileInputStream("D:\\Download\\pet.data");
ObjectInputStream in = new ObjectInputStream(is);) {
//返回值类型是Object
list= (List<Pet>) in.readObject();
for (Pet p:list){
System.out.println(p);
}
}catch (Exception e){
e.printStackTrace();
}
}
4.完成集合的增删改查
package com.sk.tentity;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* ClassName: PetTest <br/>
* Description: <br/>
* date: 2021/12/21 8:14<br/>
*
* @author 斑马<br />
*/
public class PetTest02 {
/**写入*/
public static void write(List<Pet> list){
try (OutputStream os = new FileOutputStream("D:\\Download\\pet.data");
ObjectOutputStream out=new ObjectOutputStream(os);) {
//写入对象的集合
out.writeObject(list);
} catch (Exception e) {
e.printStackTrace();
}
}
/**读取*/
public static List<Pet> read(){
List<Pet> list=null;
try (InputStream is = new FileInputStream("D:\\Download\\pet.data");
ObjectInputStream in = new ObjectInputStream(is);) {
//返回值类型是Object
list= (List<Pet>) in.readObject();
for (Pet p:list){
System.out.println(p);
}
}catch (Exception e){
e.printStackTrace();
}
return list;
}
/**添加一条数据*/
public static void add(){
List<Pet> list=read();//获取list
Pet p=new Pet("一百号",12);
list.add(p);
//写入数据
write(list);
System.out.println("************************");
read();
}
/**删除*/
public static void delete(){
List<Pet> list=read();//获取list
for (int i=0;i<list.size();i++){
Pet p=list.get(i);
if(p.getName().equals("一百号")){
list.remove(i);
break;
}
}
write(list);//把更新后的list重新写入
}
/**修改*/
public static void update(){
List<Pet> list=read();//获取list
for (int i=0;i<list.size();i++){
Pet p=list.get(i);
if(p.getName().equals("张三")){
p.setName("李四");
break;
}
}
write(list);//把更新后的list重新写入
}
public static void main(String[] args) {
// add();
//delete();
update();
System.out.println("***********************");
read();
}
}