Java二次复习笔记(3)
IO流
字节流中:(将内容转换为字节形式进行传输,可以传输任何类型的数据,8位通用字节流)
输入流:java.io.InputStream 抽象类
输出流:java.io.OutputStream 抽象类
File中常用方法:Demo01.java
package io;
import java.io.File;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
boolean newFile = file.createNewFile(); //创建文件
boolean exists = file.exists(); //文件是否存在
boolean delete = file.delete(); //删除文件
boolean isFile = file.isFile(); //判断是否为文件
boolean isDirectory = file.isDirectory(); //判断是否为目录
System.out.println("相对路径:"+file.getPath());
System.out.println("绝对路径:"+file.getAbsoluteFile());
System.out.println("文件名:"+file.getName());
System.out.println("文件大小(单位:字节):"+file.length());
System.out.println("文件目录分隔符:"+File.separator);
}
}
运行结果:
相对路径:test.txt
绝对路径:F:\Idea-workspace\studyrecord\test.txt
文件名:test.txt
文件大小(单位:字节):0
文件目录分隔符:\
输入流:InputStreamDemo.java
package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/*输入流*/
public class InputStreamDemo {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(new File("test.txt"));
//上面代码等同于 -> InputStream in = new FileInputStream("test.txt");
byte[] buf = new byte[in.available()]; //定义缓冲区,大小为输入流文件大小
//缓冲区大小设为文件大小存在弊端,当文件过大时,会占用很大的内存
in.read(buf); //将文件内容读取到buf中
System.out.println(new String(buf)); //字节数组转字符串
in.close();
}
}
输出流:OutputStreamDemo.java
package io;
import java.io.*;
/*输出流*/
public class OutputStreamDemo {
public static void main(String[] args) throws IOException {
OutputStream out = new FileOutputStream(new File("abc.txt"));
String str = "hello world!";
//将内存中的内容写入
out.write(str.getBytes()); //字符串转字节数组
out.close();
}
}
文件复制:FileCopy.java
package io;
import java.io.*;
public class FileCopy {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream("file01.txt");
OutputStream out = new FileOutputStream("file_copy.txt");
byte[] buf = new byte[10];
int len;
while ( (len=in.read(buf)) != -1) { //读不到东西时,返回-1
out.write(buf,0,len); //将当前缓冲区长度【0,len)的内容写入
}
//关闭流,if防止空指针
if(out!=null)out.close();
if(in!=null)in.close();
}
}
字符流中:(只用于处理字符,16位unicode字符流)
输入流:java.io.Reader 抽象类
输出流:java.io.Writer 抽象类
字符流:FileCopyCharactor.java
package io;
import java.io.*;
/*字符流*/
public class FileCopyCharactor {
public static void main(String[] args) throws IOException {
Reader reader = new FileReader("个人说明模板.txt");
StringBuffer sb = new StringBuffer();
char[] ch = new char[5];
int len;
while ( (len=reader.read(ch)) != -1 ){
sb.append(ch,0,len);
}
String s = sb.toString().replace("{name}","小辰").replace("{age}","23").replace("{height}","182");
System.out.println(sb);
System.out.println(s);
Writer writer = new FileWriter("个人说明.txt");
writer.write(s);
//writer.flush(); //将管道中数据刷出到文件中
//字符流中,如果不关闭流,文件内容不显示(也具有flush的功能)
writer.close();
reader.close();
}
}
运行结果:
你好,我叫{name},年龄{age},身高{height}。
你好,我叫小辰,年龄23,身高182。
自带缓冲区的字符流(缓冲区大小默认为一行)
BufferedReader/BufferedWriter
FileCopyCharactorBuffer.java
package io;
import java.io.*;
/*自带缓冲区的字符流*/
public class FileCopyCharactorBuffer {
public static void main(String[] args) throws IOException {
Reader reader = new FileReader("个人说明模板.txt");
BufferedReader br = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
String line;
while ( (line=br.readLine()) != null ){
sb.append(line);
}
String s = sb.toString().replace("{name}","小辰").replace("{age}","23").replace("{height}","182");
System.out.println(sb);
System.out.println(s);
Writer writer = new FileWriter("你的说明.txt");
BufferedWriter bw = new BufferedWriter(writer);
bw.write(s);
/**关闭流的原则:
* 1.先关输出,后关输入
* 2.先关外,再关内 比如BufferedWriter bw = new BufferedWriter(writer);中,bw为外,writer为内
*/
bw.close();
br.close();
writer.close();
reader.close();
}
}
运行结果:
你好,我叫{name},年龄{age},身高{height}。
你好,我叫小辰,年龄23,身高182。
二进制流(将内容转换为二进制形式进行传输,可以传输任何类型的数据)
DataInputStream/DataOutputStream
用二进制流复制文件:FileCopyData.java
package io;
import java.io.*;
/*二进制流*/
public class FileCopyData {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream("data.txt");
InputStream dataInput = new DataInputStream(in); //字节流->二进制流
OutputStream out = new FileOutputStream("dataCopy.txt");
OutputStream dataOutput = new DataOutputStream(out);
byte[] bytes = new byte[10];
int len;
while ( (len=dataInput.read(bytes)) != -1 ){
dataOutput.write(bytes,0,len);
}
dataOutput.close();
dataInput.close();
out.close();
in.close();
}
}
其他IO流
ObjectInputStream/ObjectOutputStream
程序运行时,会在内存中创建多个对象,程序结束后这些对象都会被当作垃圾回收。如果想永久保存这些对象,可以将对象转为字节数据写入到硬盘上,这个过程称为对象序列化。ObjectOutputStream(对象输出流)来实现序列化。
对象被序列化后会生成二进制数据保存在“Object.txt”文件中,通过这些二进制数据可以恢复序列化之前的Java对象,此过程称为反序列化。ObjectInputStream类(对象输入流),可以实现对象的反序列化。
注:当对象序列化时,必须保证该对象实现Serializable接口,否则会异常。
package io;
import java.io.*;
public class ObjectDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
People people = new People("小辰",24,1.82);
OutputStream out = new FileOutputStream("Object.txt");
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(people);
InputStream in = new FileInputStream("Object.txt");
ObjectInputStream ois = new ObjectInputStream(in);
People p = (People) ois.readObject();
System.out.println(p);
oos.close();
ois.close();
out.close();
in.close();
}
}
class People implements Serializable{
private String name;
private int age;
private double height;
public People() {
}
public People(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
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 double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
创建目录和文件、删除目录和文件
Test.java
import java.io.File;
import java.io.IOException;
/*创建、删除 目录和文件*/
public class Test {
public static void main(String[] args) throws IOException {
new File("aa").mkdirs(); //创建目录
new File("aa/bb").mkdirs();
new File("aa/a.txt").createNewFile(); //创建文件
new File("aa/bb/b.txt").createNewFile();
File file = new File("cc");
boolean delete = file.delete(); //目录不为空,返回false
System.out.println(delete);
delDir(file); //删除目录所有内容
}
//采用递归删除目录以及文件
public static void delDir(File file){
if (file.isDirectory()){ //如果是目录
File[] files = file.listFiles(); //该目录下的文件与目录数组
for (File f:files){
if (f.isDirectory()){ //如果是目录,递归
delDir(f);
}else{ //如果不是目录,删除
f.delete();
}
}
file.delete(); //最后删除该目录或者文件
}
}
}
装饰模式:IO设计的核心思想
在不影响原有对象的前提下,无侵入的给对象增一些额外的功能。
设计主题(被装饰的对象):Phone.java
package decorator;
/*主题(被装饰的对象)*/
public interface Phone {
void call();
}
实现主题:PhoneImp.java
package decorator;
/*实现主题*/
public class PhoneImp implements Phone{
@Override
public void call() {
System.out.println("只能打电话!");
}
}
设计装饰者:PhoneDecorator.java
package decorator;
/*装饰者*/
public abstract class PhoneDecorator implements Phone{
private Phone phone; //装饰者 需持有 主题 的一个引用
public PhoneDecorator(){}
public PhoneDecorator(Phone phone){
this.phone = phone;
}
//装饰者包含 原主题 的所有功能
@Override
public void call() {
phone.call();
}
}
装饰者1新增功能:ConcretePhone01.java
package decorator;
public class ConcretePhone01 extends PhoneDecorator {
public ConcretePhone01() {
}
public ConcretePhone01(Phone phone){
super(phone);
}
@Override
public void call(){
super.call();
//额外新功能
sendMessage();
}
public void sendMessage(){
System.out.println("增加发短信功能!");
}
}
装饰者1新增功能:ConcretePhone02.java
package decorator;
public class ConcretePhone02 extends PhoneDecorator{
public ConcretePhone02() {
}
public ConcretePhone02(Phone phone){
super(phone);
}
@Override
public void call() {
super.call();
//新增额外功能
surfInternet();
}
public void surfInternet(){
System.out.println("增加网上冲浪功能!");
}
}
测试:DecoratorTest.java
package decorator;
public class DecoratorTest {
public static void main(String[] args) {
Phone phone = new PhoneImp();
phone.call();
System.out.println("***");
Phone phone1 = new ConcretePhone01(phone);
phone1.call();
System.out.println("***");
Phone phone2 = new ConcretePhone02(phone1);
phone2.call();
//new ConcretePhone02(new ConcretePhone01(new PhoneImp())).call();
}
}
运行结果:
只能打电话!
***
只能打电话!
增加发短信功能!
***
只能打电话!
增加发短信功能!
增加网上冲浪功能!