十、IO输入输出流,装饰模式
IO
文章目录
InputStream :输入流
OutStream:输出流
1.方法
package IOProject;
import java.io.File;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) {
//file:文件、目录、不存在的文件或者目录
File file = new File("d:/abc.txt");
//文件分隔符自适应
// File file = new File("d:"+File.separator+"abc.txt");
System.out.println("相对路径"+file.getPath());
System.out.println("绝对路径"+file.getAbsolutePath());
System.out.println("文件名称"+file.getName());
System.out.println("文件的大小"+file.length());//单位字节
System.out.println( file.isFile()==true? "文件":"非文件");
System.out.println( file.isDirectory()==true? "目录":"非目录");
if(file.exists()){
彻底删除(不过回收站)
file.delete();
System.out.println("删除成功");
}else{
try {
file.createNewFile();
System.out.println("创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
相对路径/绝对路径
- 如果file new 的是(“绝对路径”)那么getPath()和getAbsolutePath()的结果一致,打印的都是绝对路径
- 如果file new 的是(“相对路径”)getPath()打印相对路径。getAbsolutePath()打印绝对路径(电脑中真实的存在路径)
流:是一种FIFO(First In First Out)的数据结构
2.各种流:
- 字节流
FileInputStream/FileOutputStream:字节流就是将内容转为了字节形式进行传输,字节->8二进制
二进制可以传输任何类型的数据,因此字节流也可以传输任何类型的数据(文件、图片、压缩包)
- 字符流
只能传输字符文件
- 其他流
说明:1.字节流就是 将内容转为了字节形式进行传输, 1 字节 ->8二进制 ,二进制可以传输任何类型的数据,因此字节流也可以传输任何类型的数据。
2.字节流是8位通用字节流( 1 字节 ->8二进制 ) (字节流可以处理任何类型,处理文本文件以外的其他文件) ;字符流是16位的unicode字符流 (只用于处理字符,处理文本文件)
3.在while循环中 分批次传输时,字节流使用的缓冲区是 byte[],字符流使用的缓冲区是 char[]
输入流:InputString(抽象类)
package IOProject;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoInputStream {
public static void main(String[] args) {
InputStream in = null;
try {
in = new FileInputStream(new File("d:/abc.txt"));
//文件的大小in.available()
System.out.println(in.available());
byte[] buf = new byte[in.available()];
//将文件内容读取到buf
in.read(buf);
//buf.byte[]-->String
//字节数组转换成字符串
System.out.println( new String(buf));
}catch (Exception e){
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
输出流:OutputString(抽象类)
package IOProject;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamDemo {
public static void main(String[] args) {
OutputStream out = null;
try {
out = new FileOutputStream("d:/xyz.txt");
try {
//内存-->往xvy.txt输出
//getBytes()方法把字符串转成字节
out.write("sdwrerewrwe231".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节流:文件复制
import java.io.*;
public class FileCopy {
//abc.txt->内存->xyz.txt
public static void main(String[] args) {
InputStream in = null ;
OutputStream out = null ;
try {
//abc.txt->内存
in = new FileInputStream("d:/abc.txt") ;
out = new FileOutputStream("d:/xyz.txt") ;
//开辟10字节的内存
byte []buf = new byte[10] ;
int len = -1 ;
;
while( (len= in.read(buf)) != -1){
//in ->buf
// (len= in.read(buf)) != -1这里搞错了很要命
out.write(buf,0,len);//buf->out
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(out !=null)out.close();
if(in !=null) in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
out.write(buf)和out.write(buf,0,len)的区别
out.wirte(buf)是一次分10字节,一次一次覆盖,如果最后余出来几字节就会覆盖不全,最后的结果会多出几个字节的文字
字符流:文件复制FileReader/FileWriter
package IOProject;
import java.io.*;
public class FileCopyCharactor {
public static void main(String[] args) {
//文件->内存
Reader reader =null;
Writer writer =null;
try {
reader = new FileReader("d:/说明.txt");
writer = new FileWriter("d:/说明完.txt");
//关键
char[] buf = new char[4];
//字符String不适合拼接专户成StringBuffer
StringBuffer sb = new StringBuffer();
int len = -1 ;
while((len = reader.read(buf))!=-1){
sb.append(buf,0,len);//将欸此读取到的字符 拼接起来
//String不适合拼接字符串所以用StringBuffer
}
System.out.println(sb);
//在内存中替换占位符
String content = sb.toString();
//StringSuffer中没有单个替换的replace,所以在转转换成String进行操作
content = content.replace("{name}", "赵鑫阳")
.replace("{age}","22").replace("{address}","黑龙江");
//链式写法
//将替换后的内容 输出到文件 内存->文件
writer.write(content);
System.out.println("输出成功");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(writer!= null) writer.close();
if(reader!= null) reader.close();
//write.close() 将管道中的流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
自带缓冲区的字符流BufferedReader/BufferedWriter
自带缓冲区的字符流:缓冲区大小,一行
BuffereReader/BuffereWriter
import java.io.*;
public class FileCopyCharactorBuffered {
public static void main(String[] args) {
//文件->内存(Reader)
Reader reader = null ;
Writer writer = null ;
BufferedReader br = null ;
BufferedWriter bw = null ;
try {
reader = new FileReader("d:/个人介绍.txt");
writer = new FileWriter("d:/个人完整介绍2.txt") ;
br = new BufferedReader( reader) ;
bw = new BufferedWriter( writer);
StringBuffer sb = new StringBuffer() ;
//一行一行存入,如果没有东西则停止
String line = null ;
while( (line= br.readLine()) != null ){
sb.append(line) ;
}
System.out.println(sb);
//在内存中 替换占位符
String content = sb.toString() ;
content= content.replace("{name}","颜群")
.replace("{enterprise}","蓝桥学院")
.replace("{weixin}","157468995");
//将替换后的内容 输出到文件 ,内存 ->文件(Writer)
bw.write(content);
System.out.println("成功...");
//writer.flush(); 将管道中的数据 刷出到 文件中
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
/* * 1先关出,再关入 * 2从外往内关 br外 = new BufferedReader( reader内) ; * */
try {
if(bw != null) bw.close();
if(br!=null ) br.close();
if(writer!=null) writer.close();
if(reader!=null) reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二进制流DataInputStream/DataInputStream
DataInputStream/DataOutputString
package IOProject;
import java.io.*;
//二进制流
public class FileCopyDate {
//abc.txt->内存->xyz.txt
public static void main(String[] args) {
InputStream in = null ;
OutputStream out = null ;
InputStream dataInput = null;
OutputStream dataOutput = null;
try {
//abc.txt->内存A
in = new FileInputStream("d:/abc.txt") ;
//字节流转二进制流
dataInput = new DataInputStream(in) ;
out = new FileOutputStream("d:/xyz.txt") ;
dataOutput = new DataOutputStream(out);
//开辟10字节的内存
byte []buf = new byte[10] ;
int len = -1 ;
while( (len= dataInput.read(buf)) != -1){
//in ->buf
// (len= in.read(buf)) != -1这里搞错了很要命
dataOutput.write(buf,0,len);//buf->out
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(dataOutput !=null)dataOutput.close();
if(dataInput !=null)dataInput.close();
if(out !=null)out.close();
if(in !=null) in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
装饰模式:IO设计的核心思想
在不影响原有对象的前提下,无侵入的给一个对象增加一些额外的功能。
new InputStreamReader(new FileInputStream(new File(“d:/abc.txt”)));
装饰者:需要持有主题(被装饰者的引用)