首页 > 编程语言 > 详细

Java 文件IO

时间:2015-11-30 15:58:49      阅读:225      评论:0      收藏:0      [点我收藏+]

文件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();
  }
}

 

Java 文件IO

原文:http://www.cnblogs.com/huanyi0723/p/5007423.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!