Java的输入输出与文件处理

一、学习目的

输人输出是指程序与外部设备或其他计算机进行交互的操作。几乎所有程序都具有输人与输出操作,比如从键盘上读取数据、从文件读取数据和向文件写人数据等。通过输人与输出操作可以从外界接收信息,或者是把信息传递给外界。Java 语言把这些输人与输出操作用流来实现,用统一的接口来表示,从而使程序设计简单明了。

二、学习内容

一、流

(1)流是计算机各部件之间的数据流动,按数据传输的方向可分为输入流与输出流,按流的内容可分为字符流与字节流,即流是由位或字符所构成的序列。统一管理数据的写入和读取 开发者只需要将内存里面的数据写到流里面或者从流里面读取数据

  • 输出流:从内存空间将数据写入外部存储设备(磁盘,硬盘,光盘);OutputStream 字节流 Writer字符流
  • 输入流:将外部存储设备的数据写到内存空间 ;InputStream 字节流 Reader字符流
  • 缓存流:为了提高数据传输效率,通常用缓存流,即一个流配有一个缓存区Buffer,这个就是专门用于传输数据的一块内存
输入输出流

(2)注意:OutputStream,InputString都是抽象类不能直接使用,只能使用它们的子类:
对文件操作:FileOutputStream/FileInputStream FileWriter/FileReader
对象操作:ObjectOutputStream/ObjectInputStream ObjectWriter/ObjectReader
I/O流对象不属于内存对象,需要自己关闭释放;
(3)创建一个文件

   //创建文件
 String path =
 "C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8";
    File file = new File(path.concat("\1.txt"));
    //判断文件是否存在
    if(file.exists() ==false){
        try{
           file.createNewFile(); }catch (IOException o){ System.out.println("IO异常");
       }
        file.createNewFile();
    }

注:其中的异常处理也可以直接抛出,在main 函数后面加throws IOException
(4)向文件写入数据:
1,创建文件输出流对象
2,调用write方法写入
3,操作完毕需要关闭文件输出流对象
字节流:

    // 创建文件输出流对象
    FileOutputStream fos = new FileOutputStream(file);
    //调用write方法写入
    byte[] text = {'1','2','3','4'};
    fos.write(text);
    //操作完毕需要关闭文件输出流对象
    fos.close();

字符流:

    //写入数据—字符流
    FileWriter fw = new FileWriter(file);
    char[] name = {'安','卓','开','发'};
    fw.write(name);
    fw.close();

**(5)读取数据:
字节流:

   //读取内容
    FileInputStream fis = new FileInputStream(file);
    byte[] name1 = new byte[12];
    int count  = fis.read(name1);
    fis.close();  
  System.out.println(count+" "+new String(name1));

字符流:

    FileReader fr = new FileReader(file);
    char[] book = new char[4];
    int count = fr.read(book);
    fr.close();
    System.out.println(count+" "+new String(book));

(6)向文件里保存一个对象
保存的对象必须是序列化 Serializable,即必须实现Serializable接口,若这个对象的属性里面引用了其他的对象,则引用的对象的那个类也要是实现Serializable接口
1,先定义一个类,实现Serializable接口

  package swu.xwj.day8;
  import java.io.Serializable;
  public class Person implements Serializable {
   public String name;
   public int age;
}

2,创建一个对象,并保存

 Person xw = new Person();
  xw.name = "小王";
   xw.age = 20;

  OutputStream os = new FileOutputStream(file);
   ObjectOutputStream oos = new ObjectOutputStream(os);
   oos.writeObject(xw);
   oos.close();

(7)读取对象

    //从文件里读取一个对象
    InputStream is = new FileInputStream(file);
    ObjectInputStream ois = new ObjectInputStream(is);
   Person xw =(Person) ois.readObject();
   System.out.println(xw.name+" "+xw.age);
    ois.close();

三、实例

将桌面上的图片拷贝到另一个文件中

    long start = System.currentTimeMillis();//用于测量此种方法所用的时间
    //将一个文件copy到另外一个位置
    // 1,源文件路径
    String sourcePath = "C:\Users\asus\Desktop\1.png";
    // 2,目标文件的路径
    String desPath = "C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8\1.png";
    // 3,图片,用字节流

    FileInputStream fileInputStream = new FileInputStream(sourcePath);//读
    FileOutputStream fileOutputStream = new FileOutputStream(desPath);//写
    byte[] in = new byte[1024];  //一次读取1024个字节,直到文件读取完

   while(true) {
       int count = fileInputStream.read(in);//count=-1是到文件末尾
       if(count != -1){
           //读取到数据,还未到末尾 ,将这次循环读取的内容写到目标文件
           fileOutputStream.write(in,0,count);//从数组的第一个元素写到第count个
       }else{
           break;
       }
   }
   fileInputStream.close();
   fileOutputStream.close();
   long end = System.currentTimeMillis();
  System.out.println(end-start+"毫秒");
}
输出结果

注意:这种方法一点一点读取效率较低,耗费时间长。下面用缓存流:

class Copy{
public static void main(String[] args)throws IOException,ClassCastException{
    long start = System.currentTimeMillis();

    String sourcePath = "C:\Users\asus\Desktop\1.png";
    String desPath = "C:\Users\asus\Desktop\Android\Java\day2\src\main\java\swu\xwj\day8\1.png";
    InputStream is = new FileInputStream(sourcePath);
    BufferedInputStream bis = new BufferedInputStream(is);

    OutputStream os = new FileOutputStream(desPath);
    BufferedOutputStream bos = new BufferedOutputStream(os);
    byte[] in = new byte[1024]; //暂时保存读取的数据
    int count = 0;

    while((count = bis.read(in)) != -1){
        bos.write(in,0,count);
    }
    bis.close();
    bos.close();
    long end = System.currentTimeMillis();
  System.out.println(end-start+"毫秒");
    }
}
输出结果

由此可见两次结果耗费时间相差很大。因此缓存流提高了内存与外部设备之间的数据传输效率。

四、学习感悟

文件操作虽然不算很难,但却非常重要,在以后的编程中处处都会用到,因此需要非常熟练的掌握输入输出流的使用。