文件IO
Java IO
IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中
按操作数据分为 字节流和字符流
字符流的由来:
其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。
再对这个文字进行操作。简单说:字节流+编码表
按流向分为 输入流和输出流
输入流和输出流相对于内存设备而言
将外设中的数据读取到内存中:输入
将内存的数写入到外设中:输出。
字节流的两个顶层父类:
1,InputStream 2,OutputStream
字符流的两个顶层父类:
1,Reader 2,Writer
Demo1 将一些文字存储到硬盘一个文件中
public class FileWriterDemo { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException { // 创建一个可以往文件中写入字符数据的字符输出流对象。 /* * 既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)。 * 如果文件不存在,则会自动创建。 如果文件存在,则会被覆盖。 * 如果构造函数中加入true,可以实现对文件进行续写! */ FileWriter fw = new FileWriter("demo.txt", true); /* * 调用Writer对象中的write(string)方法,写入数据。 * 其实数据写入到临时存储缓冲区中。 */ fw.write("abcde" + LINE_SEPARATOR + "hahaha"); // fw.write("xixi"); // fw.flush(); 进行刷新,将数据直接写到目的地中。 fw.close(); //关闭流,关闭资源。在关闭前会先调用flush刷新缓冲中的数据到目的地。 // fw.write("haha");// java.io.IOException: Stream closed } }
Demo2 读取一个文本文件。将读取到的字符打印到控制台
public class FileReaderDemo { public static void main(String[] args) throws IOException { // 1,创建读取字符数据的流对象。 //在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。 //用一个读取流关联一个已存在文件。 FileReader fr = new FileReader("F:\\demo.txt"); int ch = 0; while ((ch = fr.read()) != -1) { System.out.println((char) ch); } /* * //用Reader中的read方法读取字符。 int ch = fr.read(); System.out.println((char)ch); * int ch1 = fr.read(); System.out.println(ch1); int ch2 = fr.read(); * System.out.println(ch2); */ fr.close(); } }
Demo3 读取一个文本文件 采用字符数组的方法
public class FileReaderDemo2 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("F:\\demo.txt"); //使用read(char[])读取文本文件数据。先创建字符数组。 char[] buf = new char[1024]; int len = 0; while((len=fr.read(buf))!=-1){ System.out.println(new String(buf,0,len)); } /* int num = fr.read(buf);//将读取到的字符存储到数组中。 System.out.println(num+":"+new String(buf,0,num)); int num1 = fr.read(buf);//将读取到的字符存储到数组中。 System.out.println(num1+":"+new String(buf,0,num1)); int num2 = fr.read(buf);//将读取到的字符存储到数组中。 System.out.println(num2+":"+new String(buf)); */ fr.close(); } }
Demo4 文本文件复制
public class CopyTextTest { public static void main(String[] args) throws IOException { // 1,读取一个已有的文本文件,使用字符读取流和文件相关联。 FileReader fr = new FileReader("F:\\demo.txt"); // 2,创建一个目的,用于存储读到数据。 FileWriter fw = new FileWriter("F:\\copydemo.txt"); // 3,频繁的读写操作。 int ch = 0; while ((ch = fr.read()) != -1) { fw.write(ch); } // 4,关闭流资源。 fw.close(); fr.close(); } }
Demo5 文本文件复制加缓存
public class CopyTextTest_2 { private static final int BUFFER_SIZE = 1024; public static void main(String[] args) { FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("F:\\demo.txt"); fw = new FileWriter("F:\\democopy2.txt"); // 创建一个临时容器,用于缓存读取到的字符。 char[] buf = new char[BUFFER_SIZE];// 这就是缓冲区。 // 定义一个变量记录读取到的字符数,(其实就是往数组里装的字符个数 ) int len = 0; while ((len = fr.read(buf)) != -1) { fw.write(buf, 0, len); } } catch (Exception e) { // System.out.println("读写失败"); throw new RuntimeException("读写失败"); } finally { if (fw != null) try { fw.close(); } catch (IOException e) { e.printStackTrace(); } if (fr != null) try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
字符流的缓存区
缓存区的出现提高了对数据的读写效率
对应类 BufferedReader BufferedWriter
缓存区要结合流才可以使用 在流的基础上对流的功能进行了增强
Demo6 缓存写
public class BufferedWriterDemo { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("F:\\buf.txt"); // 为了提高写入的效率。使用了字符流的缓冲区。 // 创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联 BufferedWriter bufw = new BufferedWriter(fw); // 使用缓冲区的写入方法将数据先写入到缓冲区中。 // bufw.write("abcdefq"+LINE_SEPARATOR+"hahahha"); // bufw.write("xixiixii"); // bufw.newLine(); // bufw.write("heheheheh"); for (int x = 1; x <= 4; x++) { bufw.write("abcdef" + x); bufw.newLine(); bufw.flush(); } // 使用缓冲区的刷新方法将数据刷目的地中。 // bufw.flush(); // 关闭缓冲区。其实关闭的就是被缓冲的流对象。 bufw.close(); // fw.write("hehe"); // fw.close(); } }
Demo7 缓存读
public class BufferedReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("F:\\buf.txt"); BufferedReader bufr = new BufferedReader(fr); String line = null; while ((line = bufr.readLine()) != null) { System.out.println(line); } /* * String line1 = bufr.readLine(); System.out.println(line1); String line2 = * bufr.readLine(); System.out.println(line2); String line3 = * bufr.readLine(); System.out.println(line3); String line4 = * bufr.readLine(); System.out.println(line4); String line5 = * bufr.readLine(); System.out.println(line5); */ bufr.close(); } }
Demo8 缓存复制
public class CopyTextByBufTest { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("F:\\buf.txt"); BufferedReader bufr = new BufferedReader(fr); FileWriter fw = new FileWriter("F:\\buf_copy.txt"); BufferedWriter bufw = new BufferedWriter(fw); String line = null; while ((line = bufr.readLine()) != null) { bufw.write(line); bufw.newLine(); bufw.flush(); } /* * int ch = 0; * * while((ch=bufr.read())!=-1){ * * bufw.write(ch); } */ bufw.close(); bufr.close(); } }
Demo9 自定义缓存区
public class MyBufferedReader extends Reader { private Reader r; // 定义一个数组作为缓冲区。 private char[] buf = new char[1024]; // 定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。 private int pos = 0; // 定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。 private int count = 0; MyBufferedReader(Reader r) { this.r = r; } //该方法从缓冲区中一次取一个字符。 public int myRead() throws IOException { if (count == 0) { count = r.read(buf); pos = 0; } if (count < 0) return -1; char ch = buf[pos++]; count--; return ch; } public String myReadLine() throws IOException { StringBuilder sb = new StringBuilder(); int ch = 0; while ((ch = myRead()) != -1) { if (ch == ‘\r‘) continue; if (ch == ‘\n‘) return sb.toString(); // 将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。 sb.append((char) ch); } if (sb.length() != 0) return sb.toString(); return null; } public void myClose() throws IOException { r.close(); } @Override public int read(char[] cbuf, int off, int len) throws IOException { return 0; } @Override public void close() throws IOException { } }
public class MyBufferedReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("F:\\buf.txt"); MyBufferedReader bufr = new MyBufferedReader(fr); String line = null; while ((line = bufr.myReadLine()) != null) { System.out.println(line); } bufr.myClose(); } }
装饰设计模式
对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
装饰和继承都能实现一样的特点:进行功能的扩展增强。
有什么区别呢?
首先有一个继承体系。
Writer
|--TextWriter:用于操作文本
|--MediaWriter:用于操作媒体。
想要对操作的动作进行效率的提高。
按照面向对象,可以通过继承对具体的进行功能的扩展。
效率提高需要加入缓冲技术。
Writer
|--TextWriter:用于操作文本
|--BufferTextWriter:加入了缓冲技术的操作文本的对象。
|--MediaWriter:用于操作媒体。
|--BufferMediaWriter:
但是这样做好像并不理想 如果这个体系进行功能扩展,又多了流对象。
那么这个流要提高效率,是不是也要产生子类呢?是。这时就会发现只为提高功能,进行的继承,
导致继承体系越来越臃肿。不够灵活。
重新思考这个问题?
既然加入的都是同一种技术--缓冲。
前一种是让缓冲和具体的对象相结合。
可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。
class Buffer{ Buffer(TextWriter w) {} Buffer(MediaWirter w) { } } class BufferWriter extends Writer{ BufferWriter(Writer w) { } }
Writer
|--TextWriter:用于操作文本
|--MediaWriter:用于操作媒体。
|--BufferWriter:用于提高效率。
装饰比继承灵活。
特点:装饰类和被装饰类都必须所属同一个接口或者父类。
Demo10 装饰设计模式例子
public class PersonDemo { public static void main(String[] args) { Person p = new Person(); // p.chifan(); NewPerson p1 = new NewPerson(p); p1.chifan(); NewPerson2 p2 = new NewPerson2(); p2.chifan(); } } class Person{ void chifan(){ System.out.println("吃饭"); } } //这个类的出现是为了增强Person而出现的。 class NewPerson{ private Person p ; NewPerson(Person p){ this.p = p; } public void chifan(){ System.out.println("开胃酒"); p.chifan(); System.out.println("甜点"); } } class NewPerson2 extends Person{ public void chifan(){ System.out.println("开胃酒"); super.chifan(); System.out.println("甜点"); } }
Demo11 LineNumberReaderDemo
public class LineNumberReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("F:\\demo.txt"); LineNumberReader lnr = new LineNumberReader(fr); String line = null; lnr.setLineNumber(100); while((line=lnr.readLine())!=null){ System.out.println(lnr.getLineNumber()+":"+line); } lnr.close(); } }
字节流
基本操作与字符流类相同 但它不仅可以操作字符 还可以操作其它媒体文件
Demo12 写文件
public class ByteStreamDemo { public static void main(String[] args) throws IOException { // 1,创建字节输出流对象。用于操作文件. FileOutputStream fos = new FileOutputStream("F:\\bytedemo.txt"); // 2,写数据。直接写入到了目的地中。 fos.write("abcdefg".getBytes()); // fos.flush(); fos.close();// 关闭资源动作要完成。 } }
Demo13 拷贝文件
public class CopyMp3Test { public static void main(String[] args) throws IOException { copy_1(); copy_2(); copy_3(); // copy_4(); } // 千万不要用,效率没有! public static void copy_4() throws IOException { FileInputStream fis = new FileInputStream("F:\\0.zip"); FileOutputStream fos = new FileOutputStream("F:\\4.zip"); long start = System.currentTimeMillis(); int ch = 0; while ((ch = fis.read()) != -1) { fos.write(ch); } long end = System.currentTimeMillis(); System.out.println("拷贝完成4---" + (start - end)); fos.close(); fis.close(); } // 不建议。 测试速度还可以 public static void copy_3() throws IOException { FileInputStream fis = new FileInputStream("F:\\0.zip"); FileOutputStream fos = new FileOutputStream("F:\\3.zip"); long start = System.currentTimeMillis(); byte[] buf = new byte[fis.available()]; fis.read(buf); fos.write(buf); long end = System.currentTimeMillis(); System.out.println("拷贝完成3---" + (start - end)); fos.close(); fis.close(); } // 速度一般 public static void copy_2() throws IOException { FileInputStream fis = new FileInputStream("F:\\0.zip"); BufferedInputStream bufis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("F:\\2.zip"); BufferedOutputStream bufos = new BufferedOutputStream(fos); long start = System.currentTimeMillis(); int ch = 0; while ((ch = bufis.read()) != -1) { bufos.write(ch); } long end = System.currentTimeMillis(); System.out.println("拷贝完成2---" + (start - end)); bufos.close(); bufis.close(); } // 速度最快 public static void copy_1() throws IOException { FileInputStream fis = new FileInputStream("F:\\0.zip"); FileOutputStream fos = new FileOutputStream("F:\\1.zip"); byte[] buf = new byte[1024]; int len = 0; long start = System.currentTimeMillis(); while ((len = fis.read(buf)) != -1) { fos.write(buf, 0, len); } long end = System.currentTimeMillis(); System.out.println("拷贝完成1---" + (start - end)); fos.close(); fis.close(); } }
原文:http://www.cnblogs.com/huanyi0723/p/5007423.html