遇到file这样来

File

用于封装文件或者目录,提供一些获取相关属性的方法
mkdirs()用于创建文件夹
典型题目:例如获取c:\windows文件夹的大小【后代文件大小之和】和其中的文件个数等 – 递归
流模型
File file = new File(“out/”);
if(!file.exists())file.mkdirs();
典型题目:例如获取c:\windows文件夹的大小【后代文件大小之和】和其中的文件个数等 – 递归

public class Test1 {
public static long number = 0; // 统计文件个数
public static long size = 0;// 统计所有文件大小之和
public static void main(String[] args) {
// File.pathSeparator 根据操作系统不同可以有:(Linux)和;(windows)两个,用于分割
多个路径
// File.separator用于分割路径的不同部分。路径中所使用分隔符有\\和/两种写法
File file=new File("c:/windows");
list(file);
System.out.println("总共文件个数为:"+number);
System.out.println(file.getAbsolutePath()+"总大小为:"+size);
}
public static void list(File file) {
if (file != null) {
if (file.isFile()) { //如果是文件
number++;
size += file.length();
}else if(file.isDirectory()){ //如果是文件夹
File[] children=file.listFiles();
if(children!=null && children.length>0)
for(File tmp:children)
list(tmp);
}
}
}
}

流模型

流是用于隐藏数据传输细节的操作模型,是数据传输的抽象表达,Java程序可以通过流来完成输入/输出
操作
根据操作方式的区别BIO阻塞同步、NIO非阻塞同步、AIO非阻塞异步
根据流的方向分为输入流和输出流
根据传输单位分为字节流和字符流
根据功能范围节点流和过滤流
装饰模式

装饰模式

Decorate允许向一个现有对象动态添加新功能,同时不改变结构,属于JavaSE 23种设计模式中的结构
型设计模型
用途:动态扩展功能
优点:装饰类和被装饰类可以独立发展,不会相互耦合
缺点:多层装饰比较复杂
要求:抽象
编码实现:4种角色
被装饰方抽象角色
public interface IShape{
void draw(); //public abstract,不是默认package
}
具体的装饰方实现,可以有多个不同实现类
装饰抽象角色
具体装饰角色

public class Circle implemenets IShape{
public void draw(){
System.out.println("画了一个圆圈");
}
}
public abstract class DecorateShape implements IShape{
private IShape target;//被装饰方对象,就是需要动态追加功能的对象
public DecodateShape(IShape target){
this.target=target;
}
public void draw(){
target.draw(); //具体的操作需要通过被装饰方提供实现
}

测试类

public class RedDecorateShape extends DecorateShape{
public RedDecorateShape(IShape target){
super(target);
}
public void draw(){
System.out.println("使用红色");
super.draw(); //调用父类中的被覆盖的方法
System.out.println("恢复默认的颜色");
}
}

//调用时进行组装
IShape circle=new Circle(); //节点流
IShape decorate=new RedDecorateShape(circle); //过滤流
decorate.draw();
//也允许这样使用
IShape decorate2=new BlueDecorateShape(decorate);

BIO编程

使用统一接口进行操作,具体实现细节无关
字节流
InputStream和OutputStream,都实现了Closeable接口,所以支持try-resources
InputStream操作用于实现数据的读取操作
read():int 注意这里只是读取一个字节,0-255之间,-1表示流结束
read(byte[]):int 返回值表示读取的具体字节个数,-1流结束
close():void 关闭流
另外不重要的方法 read(byte[],int,int) available() skip(long)

//调用时进行组装

IShape circle=new Circle(); //节点流
IShape decorate=new RedDecorateShape(circle); //过滤流
decorate.draw();
//也允许这样使用
IShape decorate2=new BlueDecorateShape(decorate);

public class Test2 {
public static void main(String[] args) {
InputStream is = null;
try {
is = new FileInputStream("data/a1.txt");
int kk = 0;
while (true) {
kk = is.read();
if (kk == -1)
break;
System.out.print((char) kk);
}
} catch (FileNotFoundException e) {
System.out.println("文件不存在");
} catch (IOException e) {
System.out.println("读取出错");

一次一字节读取数据效率太低,所以引入缓冲数组的方式进行读取
OutputStream操作方法用于实现数据的写出操作
write(int):void 写出一个字节,int的低8位
write(byte[]具体数据,int起始下标,int长度):void
close():void 关闭流
不重要的方法write(byte[])、flush()
样例:使用字节流进行文件的拷贝

public class Test3 {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("data/a1.txt")) {
byte[] buffer=new byte[8192];
int len=0;
while((len=is.read(buffer))>0) {
String ss=new String(buffer,0,len);
System.out.println(ss);

public class Test4 {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream("data/a1.txt");
File file = new File("out/");
if(!file.exists())
file.mkdirs();
os=new FileOutputStream("out/a1.bak");//自动创建文件,如果文件已存在
则采用覆盖
int data=0;
while((data=is.read())!=-1) {
os.write(data);
}
} catch (Exception e) {
System.out.println(e);
} finally {
try {
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}}}}

}
}
}
}

引入缓冲区避免一次一字节的操作,提高执行效率
字符流
顶级父抽象类Reader和Writer,一次一字符的操作,实现了Closeable接口。如果涉及中文信息,则需
要考虑编码字符集的问题,如果编码字符集错误,则显示乱码
Reader用于封装字符读取操作
read():int 返回读取到的字符数据,0-65535 2B,返回-1 表示流末尾
read(char[]):int 返回读取的字符个数,流结束返回-1
close():void 关闭流
Writer用于封装字符写出操作
write(int):void 写出低16位
write(char[]数据,int起始下标,int写出的字符数):void

public class Test5 {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
File dict = new File("out/");
if (!dict.exists())
dict.mkdirs();
try (InputStream is = new FileInputStream("data/a1.txt");
OutputStream os = new FileOutputStream("out/a2.bak");) {
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
}
long end = System.currentTimeMillis();
System.out.println("执行用时:" + (end - start) + "ms");
}
}

类型 字符流 字节流
文件 FileReader和FileWriter FileInputStream和FileOutputStream
数组 CharArrayReader和
CharArrayWriter
ByteArrayInputStream和
ByteArrayOutputStream
字符串 StringReader和StringWriter
线程通讯使用的
管道 PipedReader和PipeWriter PipedInputStream和PipeOutputStream
close():void 关闭流,释放资源
write(String):void 写出一个字符串内容到输出流中
样例:从一个txt文件中读取数据,在控制台上显示输出,并写入到指定文件中
节点流
文件流
FileInputStream和FileReader用于从一个文件中读取数据;FileOutputStream和FileWriter用于向一个
文件中写出数据
FileInputStream文件输入字节流,FileReader文件输入字符流,用法类似
FileInputStream(“文件名称”),如果文件不存在则FileNotFoundException
FileInputStream(File)
FileOutputStreram文件输出字节流,FileWriter文件输出字符流,用法类似
FileOutputStream(“文件名称”);如果文件不存在,则自动创建;如果文件存在则执行覆盖原文件
内容
FileOutputStream(“文件名称”,boolean是否采用追加方式);如果文件不存在,则自动创建;如果
文件存在并且Boolean参数为true则表示采用追加的方式处理
public class Test6 {
public static void main(String[] args) throws IOException {
try (Reader in = new FileReader(“out/a1.bak”);
Writer out = new FileWriter(“out/aaa.txt”)😉 {
char[] buffer = new char[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
String ss = new String(buffer, 0, len);
System.out.println(ss);
out.write(buffer,0,len);
//out.write(ss);
}
}
}
}

注意:文件流属于节点流,输入流的源端和输出流的目标端都是磁盘文件,沟通方法允许通过文件的路
径名称或者文件对象的方式进行构建
样例:拷贝out目录到d:/bbb目录—目前还不追求合适的写法,而是要求实现功能
//从键盘上读取数据,并写入到一个文件中。保留过去的历史数据

public class Test1 {
public static void main(String[] args) throws IOException {
// 键盘的应用对象,系统标准输入设备默认为键盘System.in
InputStream is = System.in;
byte[] buffer = new byte[1024];
int len = is.read(buffer); //遇到回车则自动进行读取操作
if (len > 0) {
OutputStream os = new FileOutputStream("out/key.txt",true);//不带
参数则默认为false
os.write(buffer,0,len);
os.close();
}
is.close();
}
}
public class Test2 {
private static String source = "out";
private static String target = "d:/bbb";
public static void main(String[] args) {
File file = new File(source);
iterate(file);
System.out.println("拷贝完毕");
}
//如果理解困难可以拆分为多个方法,每个方法功能尽量单一
public static void iterate(File file) {
if (file != null) {
if (file.isFile()) {
// 使用输入输出流进行文件内容拷贝
String oldPath = file.getAbsolutePath();
int pos = oldPath.indexOf(source);
String substring = target + oldPath.substring(pos +
source.length());
byte[] buffer = new byte[1024];
int len = 0;
try (InputStream is = new FileInputStream(file);
OutputStream os = new FileOutputStream(substring);) {
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
} else if (file.isDirectory()) { //创建目录
// 将原始路径转换为新路径,例如out/cc1--->d:/bbb/cc1
String path = file.getAbsolutePath();
int pos = path.indexOf(source);
String substring = target + path.substring(pos +
source.length());

// 判定新路径对应的目录是否存在,如果不存在则自动创建

内存数组节点
如果是文本字符则使用char[],如果二进制数据则使用byte[]
CharArrayReader和CharArrayWriter、ByteArrayInputStream和ByteArrayOutputStream数据来源或
者输出目标为数组,CharArray对应char[],ByteArray对应byte[]
输入流
CharArrayReader(char[]) 其中char[]就是数据的来源,也就是说Reader是从char[]中读取数据
不常用 CharArrayReader(char[]数据,int起始下标,int最大长度)
输出流
CharArrayWriter用于实现向一个字符数组中写入数据,这个数组大小可以自动调整
CharArrayWriter()自动创建一个关联了char[]的输出流
CharArrayWriter(int)自动创建一个关联了char[]的输出流,这里的参数就是char[]的初始化大小
File tmp = new File(substring);
if (!tmp.exists())
tmp.mkdirs();
// 查看当前目录下的所有子文件对象

File[] children = file.listFiles();
for (File tmp1 : children) {
iterate(tmp1);
}
}
}
}
}
// 从char[]中读取数据并在控制台打印显示
String ss = "abc中国人民解放军1234";
char[] arr = ss.toCharArray(); // 将字符串转换为字符数组,实际上Java中提供了字串流
Reader r = new CharArrayReader(arr);
int cc=0;
while((cc=r.read())!=-1) {
System.out.println((char)cc);
}
//从键盘读取数据,并写入到char[]中,如果键盘录入quit则退出并显示char[]中的所有内容
Writer w=new CharArrayWriter();
Scanner sc=new Scanner(System.in);
String line=sc.nextLine();
while(!"quit".equals(line)) {
w.write(line.toCharArray());
line=sc.nextLine();
}
sc.close();
//CharArrayWriter中提供了一个方法可以获取关联的char[]
CharArrayWriter cw=(CharArrayWriter)w;
String inputContent=new String(cw.toCharArray());//获取关联的char[]
System.out.println(inputContent);

总结
读写文件使用文件流,如果操作文本文件建议使用FileReader和FileWriter,如果操作二进制文件
则建议使用FileInputStream和FileOutputStream
需要建立缓冲区,可以考虑建立临时文件,这种方式效率低下。所以一般建议考虑使用
CharArrayReader / CharArrayWriter和ByteArrayInputStream / ByteArrayOutputStream或者
StringReader / StringWriter充当内存缓冲区
如果需要二进制缓冲可以ByteArrayInputStream / ByteArrayOutputStream,如果需要一个字符
缓冲区可以使用CharArrayReader / CharArrayWriter、StringReader / StringWriter
如果数据量不是特别大使用CharArrayReader / CharArrayWriter更为方便一些,如果数据量大可
能需要直接操作缓冲区可以使用StringReader / StringWriter
StringWriter中提供了一个方法getBuffer()可以获取到StringBuffer
过滤流
过滤流的作用就是在节点流的基础上提供额外功能。装饰器模式
StringWriter sw=new StringWriter();
Writer w=new FileWriter(“d:/console.txt”);
){
String tmp=sc.nextLine();
while(!“quit”.equals(tmp)){
if(tmp!=null && tmp.trim().length()>0){
sw.write(tmp+"\n");
}
tmp=sc.nextLine();
}
System.out.println(sw.toString());
w.write(sw.toString());//通过toString方法获取变长字符串内容
}
sc.close();

处理类型

字符流 字节流
缓存 BufferedReader/BufferedWriter BufferedInputStream /
BufferedOutputStream
过滤处理
FilterReader / FilterWriter FilterInputStream / FilterOutputStream
桥接处理
InputStreamReader /
OutputStreamWriter
对象处理
ObjectInputStream /
ObjectOutputStream
数据转换
DataInputStream / DataOutputStream
打印功能
PrintWriter PrintOutputStream
行数统计
LineNumberReader LineNumberInputStream
回滚处理
PushbackReader PushbackInputStream
过滤处理
就是装饰器模式中的抽象装饰角色

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值