--------------android培训、java培训、学习型技术博客、期待与您交流! --------------
IO流的四个基类
A:字节流
输入流
InputStream
|--FileInputStream
输出流
OutputStream
|--FileOutputStream
B:字符流
输入流
Reader
|--FileReader
输出流
Writer
|--FileWriter为了提高读写效率,加入了缓冲技术字符流:(BufferedReader和BufferedWriter)字节流:(BufferedInputStream和BufferedOutputStream)
复制文本代码
package Demo;
/*需求:复制文本文件
分析:源:用Reader或者InputStream
操作的是硬盘上的纯文本数据用Reader
加入缓冲技术用BufferedReader
目的:用Writer或者OutputStream
操作的是硬盘上的纯文本数据用Writer
加入缓冲技术用BufferedWriter
*/
import java.io.*;
public class CopyTxt {
public static void main(String[] args) {
BufferedReader bur = null;
BufferedWriter buw = null;
try {
bur = new BufferedReader(new FileReader("D:\\work.txt")); // 提高效率,定义读取流缓冲区
buw = new BufferedWriter(new FileWriter("C:\\123.txt")); // 提高效率,定义写入流缓冲区
String line = null;
while ((line = bur.readLine()) != null) { // 读取一行数据
buw.write(line);
buw.newLine(); // 换行
buw.flush(); // 刷新,将缓冲区的数据保存到文件里。使用缓冲区一定记着刷新
}
System.out.println("复制成功");
} catch (Exception e) {
throw new RuntimeException("复制失败");
} finally {
try {
if (bur != null)
bur.close(); // 关闭读取流
} catch (Exception e) {
throw new RuntimeException("读取流关闭失败");
}
try {
if (buw != null)
buw.close(); // 关闭写入流
} catch (Exception e) {
throw new RuntimeException("写入流关闭失败");
}
}
}
}
需求:复制一张图片
分析:
源:用Reader或者InputStream
操作的是硬盘上的非纯文本数据用InputStream
加入缓冲技术用BufferedInputStream
目的:用Writer或者OutputStream
操作的是硬盘上的纯文本数据用OutputStream
加入缓冲技术用BufferedOutputStream
package Demo;
import java.io.*;
public class CopyPic {
public static void main(String[] args) {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
bw = new BufferedOutputStream(new FileOutputStream("D:\\123.jpg"));
br = new BufferedInputStream(new FileInputStream("C:\\abc.jpg"));
int len = 0;
while ((len = br.read()) != -1) { // 从输入流中读取下一个字节
bw.write(len);
bw.flush();
}
} catch (Exception e) {
throw new RuntimeException("复制失败");
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
throw new RuntimeException("读取流关闭失败");
}
try {
if (bw != null) {
bw.close();
}
} catch (Exception e) {
throw new RuntimeException("写入流关闭失败");
}
}
System.out.println("复制成功");
}
}
装饰模式
装饰模式比继承要灵活,而且降低了类于类之间的关系。避免了继承体系臃肿。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常是都属于一个体系中的。
给已有的对象提供增强额外的功能。还不用对原有对象进行修改。
装饰模式在IO中的应用,写入文件用的FileWriter,发现这个类的功能不够强大装饰类出现了BufferedWriter,增强原有FileWriter的功能,在原有FileWriter的基础上,增加了一个新的方法newLine(),但是BufferedWriter写一行的方法,底层用的还是FileWriter的方法BufferedWriter构造方法 BufferedWriter(Writer out)
Writer
|--TestWriter
|--MediaWriter
现有一个体系用于各种数据的写入。
但是,防线写入效率有点低。想要对其进行效率的提高。
可以使用缓冲技术来完成的。
以后对象的写入方法,不够高效,可以通过派生子类的形式对齐进行复写,定义高效的写入动作。
Writer
|--TestWriter
|--BufferTextWriter
|--MediaWriter
|--BufferMediaWriter
通过继承的方式提高了效率。
但是对于扩展性是一个问题。而且所需的功能越多,子类就越多。
一旦加入新类,就需要为它提供高效。麻烦!
如何解决这个问题呢?优化!
既然都需要缓冲,对数据写入的效率进行提高。
可以转变一下思想,这样来做,将缓冲技术单独进行封装。
哪个对象需要缓冲,就把哪个对象传递给缓冲对象即可。
class Buffer {
Buffer(TestWriter w) {
}
Buffer(MediaWriter w) {
}
}
为了便于扩展,可以对一组对象进行缓冲。
class BufferWriter extends Writer{
Buffer(Writer w){
}
Public void write(){
}
}
体系就变成了这样:
Writer
|--TextWriter
|--MediaWriter
|--BufferWriter
BufferWriter的出现,增强了Writer体系中的功能。
这种设计方式比原来更为灵活,避免了继承的臃肿。
将这样解决方式就定义了一个名称方便于后人使用:装饰设计模式。
装饰设计代码
/*
模拟一下BufferedReader
*/
import java.io.*;
class MyBufferedReader extends Reader {
private Reader r;
MyBufferedReader(Reader r) {
this.r = r;
}
// 可以一次读一行数据的方法。
public String myReadLine() throws IOException {
// 定义一个临时容器。原BufferReader封装的是字符数组。
// 为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
while ((ch = r.read()) != -1) {
if (ch == '\r')
continue;
if (ch == '\n')
return sb.toString();
else
sb.append((char) ch);
}
if (sb.length() != 0)
return sb.toString();
return null;
}
/*
* 覆盖Reader类中的抽象方法。
*/
public int read(char[] cbuf, int off, int len) throws IOException {
return r.read(cbuf, off, len);
}
public void close() throws IOException {
r.close();
}
public void myClose() throws IOException {
r.close();
}
}
class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBuf = new MyBufferedReader(fr);
String line = null;
while ((line = myBuf.myReadLine()) != null) {
System.out.println(line);
}
myBuf.myClose();
}
}
需求:读取键盘录入,将键盘录入转换成大写存放在文件中
分析:
源:用InputStream或Reader
操作的数据是纯文本用Reader 加入缓冲技术BufferedReader
设备:键盘,对应的对象是System.in 所以要用转换流 InputStreamReader
目的:用Writer或OutputStream
操作的数据是文本数据用Writer
加入缓冲技术BufferedWriter
设备:硬盘 硬盘上的一个文本文件
package Demo;
import java.io.*;
public class ReadSystemIn {
public static void main(String[] args) throws Exception {
BufferedReader bur = null;
BufferedWriter buw = null;
try {
bur = new BufferedReader(new InputStreamReader(System.in));
buw = new BufferedWriter(new FileWriter("D:\\abc.java"));
String line = null;
while ((line = bur.readLine()) != null) { // 一次读一行的数据
if (line.equals("over"))
break;
buw.write(line.toUpperCase()); // 把读取的字符串转换成大写并写入
buw.newLine(); // 换行
buw.flush();
}
} catch (Exception e) {
throw new RuntimeException("失败");
} finally {
try {
if (bur != null)
bur.close(); // 关闭读取流
} catch (Exception e) {
throw new RuntimeException("读取流关闭失败");
}
try {
if (buw != null)
buw.close(); // 关闭写入流
} catch (Exception e) {
throw new RuntimeException("写入流关闭失败");
}
}
}
}
File类
1)创建功能:
A:创建文件
public boolean createNewFile():如果文件不存在,就会创建一个文件。
B:创建文件夹(目录)
public boolean mkdir():创建单级文件夹,要求父文件夹先存在
2)删除功能:public boolean mkdirs():直接创建多级文件夹
public boolean delete() 不管的是删除文件还是文件夹,都是采用同一种功能。
注意事项:如果是删除文件夹,请保证文件夹内没有内容。 如果有内容,必须把内容删除完毕才能删除文件夹。
3)判断功能:
boolean exists() :文件是否存在.
boolean isFile(): 判断是否是文件
boolean isDirectory();是否是文件夹
boolean isHidden(); 是否隐藏
boolean isAbsolute(); 是否是绝对路径,文件不存在的情况也能判断。4)获取信息:
String getAbsolutePath(): 获取抽象路径
需求: 将一个指定目录下的class文件的绝对路径,存储到一个文本文件中。
分析:列出指定目录下文件的绝对路径,就是包含子目录中的内容,也就是列出指定目录下所有class文件的绝对路径。 在列出过程中因为是目录中还有目录,所以还可以调用本功能,也就是递归。
在使用递归的时候要注意:(1)递归一定要有出口,否则就是死递归。(2)递归的次数不能过多,否则内存溢出。
import java.io.*; import java.util.ArrayList; import java.util.List; public class ListDir { public static void main(String[] args) { File dir = new File("C:\\work2"); List<File> list = new ArrayList<File>(); getPath(dir, list); // System.out.println(list); writeToFile(list, "D:\\abc.txt"); } // 定义一个获取文件绝对路径,把绝对路径对象存入到集合中的方法 public static void getPath(File dir, List<File> list) { File[] file = dir.listFiles(); for (File f : file) { if (f.isDirectory()) { // 遍历到的f,如果是目录就进行递归 getPath(f, list); } else { if (f.getName().endsWith(".class")) list.add(f); } } } // 定义一个得到集合里面的绝对路径,把绝对路径存储到指定的文本文件的方法 public static void writeToFile(List<File> list, String javaListFile) { BufferedWriter buw = null; try { buw = new BufferedWriter(new FileWriter(javaListFile)); for (File file : list) { buw.write(file.getAbsolutePath()); // 得到绝对路径,并且写入到流中 buw.newLine(); buw.flush(); } } catch (IOException e) { throw new RuntimeException(); } finally { try { if (buw != null) buw.close(); } catch (IOException e) { throw new RuntimeException("写入流关闭失败"); } } } }