Java_IO流

基础知识

文件在java程序中是以流的形式来操作的。

文件

获取文件信息

file.getName()//文件名
    .getAbsolutePath()//绝对目录
    .getParent()//父目录
    .length()//大小(字节)
    .exists()//存在
    .isFile()//是不是一个文件
    .isDirectory();//是不是一个目录

目录操作

在java中,目录也被当做文件

file.delete()//删除
    .mkdirs()//创建多级目录
    .mkdir()//创建磁盘下一级目录

IO流原理

java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据。

输入:读取外部(很多种形式)数据

输出:输出数据到外部

流的分类

按操作数据单位不同分为:字节流(8bit)——二进制文件(无损),字符流——文本文件

都是抽象类,使用时需要创建实现子类。

节点流处理流

节点流:直接针对某个数据源(文件或数组、字符串等)读写数据。如FileInputStream、FileReader

处理流(包装流):封装了一个任意的节点流,拓宽了操作对象。如BufferedInputStream、BufferedReader

处理流使用了装饰模式

//抽象类
public abstract class Reader_: {
    public void readFile() {
    }
    public void readString() {
    }
}
//节点流
public class FileReader_ extends Reader_ {
    public void readFile() {
    	system.out.println("对文件进行读取...");
    }
}
//节点流
public class StringReader_ extends Reader_ {
    public void readString() {
    	system.out.println("读取字符串..");
    }
}

//包装流
public class BufferedReader_ extends Reader_{
    private Reader_ reader_;//属性是Reader_类型
    
    public BufferedReader_(Reader_ reader_) {
    	this.reader_ = reader_;
    }
    
    //让方法更加灵活,多次读取文件
    public void readFiles(int num) {
        for(int i = 0; i < num; i++) {
            reader_.readFile();
        }
    }
    //扩展readString,批量处理字符串数据
    public void readStrings(int num) {
        for(int i = 0; i < num; i++) {
        	reader_.readString();
        }
    }
}

main() {
    BufferedReader_ bufferReader_ = new BufferedReader_(new FileReader_);
    bufferReader_.readFiles(10);
}

输入流

字符流Reader

BufferedReader

BufferedReader bufferedReader = new BufferedReader
    (new FileReader(filePath));
//读取
string line;//按行读取,效率高
//1.bufferedReader.readLine()是按行读取文件
//2.当返回null时,表示文件读取完毕
while ((line = bufferedReader.readLine()) != null) {
	system.out.println(line);
}
//关闭流,这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭节点流
//FileReader.close
bufferedReader.close();

字节流InputStream

FileInputStream:

//int readData = 0;
byte[] buf = new byte[8];//一次读取8个字节
int readLen = 0;
FileInputstream fileInputStream = null;
try {
    //创建FileInputstream对象,用于读取文件
    fileInputStream = new FileInputStream(filepath);
    //从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止。
    //如果返回-1,表示读取完毕
    //如果读取正常,返回实际读取的字节数
    //while ((readData = fileInputStream.read()) != -1) {
    while ((readLen = fileInputStream.read(buf)) != -1) {
    	//System.out.print((char)readData);//转成char显示
        System.out.print(new String(buf , 0, readLen));//根据字节构建字符串
    }
}catch (IOException e) {
	e.printStackTrace();
}finally {
    try {
    	fileInputstream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

BufferedInputStream:

ObjectInputStream:

读取数据时同时读取值和数据类型,即将数据反序列化。

读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致,否则类型不匹配

System.out.println(ois.readInt());
System.out.println(ois.readBoolean();
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
system.out.println(ois.readUTF());
Dog dog = (Dog)ois.read0bject();//编译类型为Object,运行类型为Dog
System.out.println("运行类型=" + dog.getclass());
system.out.println("dog名=" + dog.getName());
//关闭流,关闭外层流即可,底层会关闭 FileInputstream流
ois.close();

输出流

字符流Writer

BufferedWriter

//创建BufferedWriter
BufferedWriter bufferedWriter = new BufferedWriter
    (new FileWriter(filePath, true));//true表示追加,而不是覆盖
bufferedWriter.write("hello!");
bufferedWriter.newLine();//插入一个和系统相关的换行
bufferedWriter.write("hello2!");
bufferedWriter.newLine();
bufferedWriter.write("hello3!");
bufferedWriter.newLine();
//说明:关闭外层流即可,传入的 new FileWriter(filePath),会在底层关闭
bufferedWriter.close();

字节流OutputStream

FileOutputStream

文件不存在会创建文件(前提是目录已经存在)

FileOutputStream fileOutputStream = null;
try {
    //得到FileOutputStream对象
    file0utputStream = new File0utputStream(filePath);
    //file0utputStream = new File0utputStream(filePath, true);//追加方式写入
    //写入一个字节
    file0utputStream.write('H');
    //写入字符串
    String str = "hello";
    file0utputStream.write(str.getBytes(), 0 ,str.length);//从索引0开始,写入长度
} catch (IOException e) {
	e.printStackTrace();
} finally {
    try {
		fileOutputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

BufferedOutputStream

ObjectOutputStream

保存数据时将数据类型也保存起来,即能够将数据序列化。需要将对象实现标记接口Serializable

//序列化后,保存的文件格式,不是存文本,而是按照他的格式来保存
String filePath = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到e:\data.dat
oos.writeInt(100);//int -> Integer(实现了 Serializable)
oos.writeBoolean(true);// boolean -> Boolean(实现了Serializable)
oos.writeChar('a');// char -> Character(实现了Serializable)
oos.writeDouble(9.5);// double -> Double(实现了Serializable)
oos.writeUTF("韩顺平教育");//String
oos.writeObject(new Dog());//需要序列化

oos.close();

综合实践

拷贝文件——文本

String srcFilePath = "e:\\a.java";
String destFilePath = "e:\\a2.java" ;
BufferedReader br = null;
BufferedWriter bw = null;
String line = "";
try {
    br = new BufferedReader(new FileReader(srcFilePath));
    bw = new BufferedWriter(new FileWriter(destFilePath));
    while((line = br.readLine()) != null) {
        //每读取一行,就写入
		bw.write(line);//插入一个换行
        bw.newLine();
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    br.close();
    bw.close();
}

拷贝文件——视频

BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
    //因为 FileInputStream是 InputStream子类
	bis = new BufferedInputStream(new FileInputStream(srcFilePath));
    bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
	//循环的读取文件,并写入到destFilePath
	byte[] buff = new byte[1024];
	int readLen = 0;
	while ((readLen = bis.read(buff)) != -1) {//读取不到数据
        bos.write(buff, 0, readLen);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (bis != null) {
        	bis.close();
        }
        if (bos != null) {
            bos.close();
        }
    } catch (IOException e) {
    	e.printStackTrace();
	}
}

细节

static和transient属性不能被序列化。

类的属性都需要实现序列化。

标准输入输出流

// System.in编译类型 InputStream
// system.in运行类型 BufferedInputStream
// 表示的是标准输入流——键盘
System.out.println(System.in.getClass());

//编译类型 PrintStream
//运行类型 PrintStream
//表示标准输出流——显示器
System.out.println(System.out.getClass());

Properties类

读文件:

//使用Properties类来读取mysql.properties文件
//1.创建Properties对象
Properties properties = new Properties();
//2. 加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3.把k-v显示控制台
properties.list(System.out);
//4.根据key获取对应的值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名=" + user);
System.out.println("密码是=" + pwd);
posted @ 2023-09-15 10:15  上瘾了  阅读(35)  评论(0)    收藏  举报