File类--输入流和输出流

创建文件对象:可以是物理文件或目录,操作文件或目录的属性(路径、权限、日期和时间等)

通过流来读写文件,流是一组有序的数据序列,以先进先出方式发送信息的通道

很多的信息,都是通过文件来读取的,文件是数据源

对于程序来说,把文件读入到程序中,这是输入,把资料读出去是是输出。

在Java中流的分类:

按流向区分:        1、输出流---->OutputStream和Writer作为基类

              2、输入流---->InputputStream和Reader作为基类                    输入输出流是相对于计算机内存来说的

按照处理数据单元划分:    1、字节流---->字节输入流InputputStream  字节输出流OutputStream这两个作为基类  字节流是8位通过字节流,字符流是16位Unicode字符流

               2、字符流---->字符输入流Reader       字符输出流Writer这两个作为基类 

通常使用按处理数据单元划分的多一点。

字节流:  InputStream

            read()            从输入流一个字节一个字节的读,返回的是该字节的整数表示形式,如果到了输入流的末尾,返回-1

            read(byte[ ] a)         从输入流读取若干字节,把这些字节保存到数组a中,返回的是读取到字节数,如果到了输入流的末尾,返回-1

            read(byte[ ] a,int off,int len)    从输入流读取若干字节,把这些字节保存到数组a中,off指的是字节数组中开始保存数据的起始下标,len指读取的字节数                                                                                                     目。返回的是读取到的字节数,如果到了输入流的末尾,返回-1

            close()

            available()  可以从输入流中读取的字节数目

      FileInputStream(子类FileInputStream常用的构造方法)

            new FileInputStream(File file)    这是一个文件类

            new FileInputStream(String path)   这是路径

      OutputStream

            write(int a)

            write(byte [ ] a)

            write(byte [ ] a,int off ,int len)

            close()

            flush()              强制将缓冲区清空

      FileOutputStream

            new FileOutputStream(File file)

            new FileOutputStream(String path)

            new FileOutputStream(String path,boolean append)可以指定覆盖或追加文件内容,设置为true的时候,就是追加

       Reader

            read()            从输入流一个字节一个字节的读,返回的是该字节的整数表示形式,如果到了输入流的末尾,返回-1

            read(byte[ ] a)         从输入流读取若干字节,把这些字节保存到数组a中,返回的是读取到字节数,如果到了输入流的末尾,返回-1

            read(byte[ ] a,int off,int len)    从输入流读取若干字节,把这些字节保存到数组a中,off指的是字节数组中开始保存数据的起始下标,len指读取的字节数                                                                                                     目。返回的是读取到的字节数,如果到了输入流的末尾,返回-1

            close()

       InputStreamReader(是Reader的子类)可以指定字符编码格式

            new InputStreamReader(InputStream in)

            new InputStreamReader(InputStream in, String charsetName)  String charsetName这就是想要的编码格式,流和文件是编码格式化要一致,比如文件                                                                                                                                                       格式是GBK,然后设置的也要是GBK

      FileInputStreamReader(是InputStreamReader的子类,该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型)

            new FileReader(File file)

            new FileReader(String name)

中文乱码:  原因:文件编码格式  和程序环境的编码格式不一致谢

       解决方案:FileReader是无法指定编码格式的,会按照程序的编码格式打印的。可以使用InputStreamReader字符输入流 

BufferedReader      缓冲区输入流类,再将Reader类包装成BufferedReader类,为了提高效率,把文件内容都读到了缓冲区中,然后读取数据的时候,就直接在缓冲区区读取

        readLine()  这个方法,一次将一行的内容读取出来    

        System.getProperty("file.encoding");获得本地平台的字符编码类型

        Writer

            writer(String str)        将str字符串里包含的字符输出到指定的输出流中

            writer(String str,int off,int len)   将str字符串里从off位置开始,长度为len的多个字符输出到输出流中

            close()

            flush()            刷新输出流,清空缓存

     OutputStreamWriter(是Writer的子类)

            OutputStreamWriter(OutputStream out)

            OutputStreamWriter(OutputStream out,String charsetName)

     BufferedWriter

Writer中也有输出的字符的缓冲区输出流,注意缓冲区的内容是字符串了,不再是字节了

缓冲区其实就是一个字节数组,它要积累的一定的数量,才会输入或输出

注意:所有的流都要关了,输出流不仅要关流,还要清空缓冲区的数据

二进制流:就是进行图片、音乐等这样的文件,就是使用二进制流进行读写的

    DataInputStream:是FileInputStream的子类,与FileInputStream结合使用,使用的方法跟InputStream方法一样

            new DataInputStream (InputStream in)

    DataOutputStream:是FileOutputStream的子类,与FileOutputStream结合使用

            new DataOutputStream(OutputStream in)

序列化与反序列化:序列化就是将对象(Java中创建的对象)的状态写入到特定的流中的位置,记得对象所属的类可以完成序列化,要完成序列化的对象,要记得去实现序列化的接口Serializable,才可以进行序列化的操作,对象中的某一个状态不想被序列化,可以在相应的属性中加一个关键字transient。

         序列化,就是把对象放进到流中,这个使用的是ObjectOutputStream,反之则使用ObjectInputStream

    ObjectInputStream

            new ObjectInputStream(FileInputStream fis)     注意:因为是Object对象,所以使用的方法跟InputStream一样,只是是readObject()方法

    ObjectOutputStream

            new ObjectOutputStream(FileOutputStream fis)  注意:反序列化接收到的是Object对象,所以要进行类型转换,使用的方法也是writerObject()方法

使用io的步骤:

  1、引入相关的类

  2、构造文件输入流或输出流或字符输入流或字符输出流

  3、读取或写出文本文件的数据

  4、关闭流对象

案例1:普通的输入和输出

import java.io.File;

import java.io.IOException;

public class TestClass {

   /**  

  * 创建一个文件或者目录  

  * @param file  

   */  

  public void creatFile(File file){  

     if(file.exists()){//判断文件或目录是否存在,存在为true    

      System.out.println("此文件已存在!");   

    }else{   

      try {    

         file.createNewFile();//创建文件     

        System.out.println("文件创建成功!");    

      } catch (IOException e) {     

        e.printStackTrace();   

       }   

    }

   }  

  /**  

  * 获得文件的信息  

  * @param file  

  */ 

  public void getFileInfo(File file){   

    if(file.exists()){//先判断是否有此文件或者目录   

       if(file.isFile()){//判断是否是文件    

         //获得文件的绝对路径     

        String string=file.getPath();//相对路径     

        String a=file.getAbsolutePath();//绝对路径     

        String name=file.getName();//获得文件名     

        System.out.println("相对路径: "+string);     

        System.out.println("绝对路径: "+a);     

        System.out.println("文件名为:"+name);    

        System.out.println("文件大小为:"+file.length());   

     }    

      if(file.isDirectory()){//判断是否是目录     

        System.out.println("此文件是目录");    

      }   

    }else {    

      System.out.println("此文件不存在!");   

    }  

  }  

  /**  

  * 删除文件  

  * @param file  

  */  

  public void del(File file){   

    if(file.exists()){//先要判断是否有此文件才可以进行删除工作    

      file.delete();    

      System.out.println("删除文件成功!");   

    }else{    

      System.out.println("此文件不存在");   

    }  

  }  

}

public static void main(String[] args) {
    //要去判断是否有这个文件或者目录,如果没有,那么就去创建一个文件
    TestClass testClass=new TestClass();
    File file=new File("E:/练习/text.txt");//这里是要创建的文件
  //  testClass.creatFile(file);//通过调用方法去检查是否有该文件或目录,没有就创建
  //  testClass.getFileInfo(file);
    testClass.del(file);
 }

案例2:输入流和输出流的结合使用

public static void main(String[] args) {

  //出现的问题:1:前面有一堆的字符,然后输入的中文有乱码的问题,解决的方法是FileOutputStream的write方法中,结束的位置是data,不是数组的长度
  //先把要复制的文件输入出来,然后再输出文件出来
  //创建输入流
  FileOutputStream fos=null;
  //创建输出流
  FileInputStream fis=null;
  try {
   //需要复制的原文件
   fis=new FileInputStream("E:/练习/test.txt");
   //复制到的文件,内容进行追加
   fos=new FileOutputStream("E:/练习/text.txt",true);
   //读取的长度
   int data=-1;
   //创建一个数组,去接收文件
   byte [] b=new byte[1024];
   try {
    //通过读取去获得文件内容
    while ((data=fis.read(b))!=-1) {
     //通过输出流将文件写到目标文件中去,长度是读取到的文件内容的长度
     fos.write(b, 0, data);
    }

  /*//这里在循环条件中读取了一次,然后在循环体中又读取了一次,所以读取出来的文件内容是没有第一个字节的
    while((fis.read())!=-1){
     fis.read(b);
     //这里结束的尾部是数组的长度,如果数组没有读取出那么多,就会在文件中尾部输出很多的空格,所以这里要是文件的长度
     fos.write(b,0,b.length);
    }*/
    System.out.println("复制成功!");
   } catch (IOException e) {
    e.printStackTrace();
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
 }

案例3:所有文件的输入和输出流的结合使用

public static void main(String[] args) {
  InputStream is=null;//输入流
  InputStreamReader isr=null;
  BufferedInputStream bis=null;
  
  OutputStream os=null;//输出流
  OutputStreamWriter osw=null;
  BufferedOutputStream bos=null;
  try {
   //创建出输入流
   is=new FileInputStream("F:/刘楠梅/hello.txt");
   bis=new BufferedInputStream(is);
   isr=new InputStreamReader(is,"GBK");//因为txt文件默认的编码格式是GBK,所以输入流设置的编码格式也要是GBK
   
   //创建输出流
   os=new FileOutputStream("G:/测试/你好.txt",true);
   bos=new BufferedOutputStream(os);
   osw=new OutputStreamWriter(os,"GBK");
   //设置接收读取的长度
   int len=-1;
   //读取的字符数组
   byte [] b=new byte[1024];
   //循环遍历文件的内容,当内容为-1的时候,跳出循环
   while((len=bis.read(b))!=-1){
    //将文件输出
    bos.write(b);
   }
   //要将输出流强制清空,不然文件不会有内容
   bos.flush();
   System.out.println("完成复制!");
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
   try {
    //最后关闭所有使用的流,记得后的先关闭,最先的最后关闭
    osw.close();
    bos.close();
    os.close();
    isr.close();
    bis.close();
    is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

案例4:这是一个字符流的输入

public static void main(String[] args) {
  Reader reader=null;
  try {
   reader=new FileReader("E:/练习/text.txt");
   int data=-1;
   //读取的不再是字节了,而是字符了,所以使用char数组去接收读取出来的内容
   char []b=new char[1024];
   //可以使用StringBuffer类去添加字符串,会比较灵活
   StringBuffer stringBuffer=new StringBuffer();
   try {
    //data是实际读取到的字符数
    while ((data=reader.read(b))!=-1) {
     stringBuffer.append(b);
    }
    System.out.println(stringBuffer);
   } catch (IOException e) {
    e.printStackTrace();
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }finally{

//记得一定要关闭流
   try {
    reader.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

案例5:二进制输入流和输了流的结合使用

public static void main(String[] args) {
  DataInputStream dis=null;
  FileInputStream fis=null;
  DataOutputStream dos=null;
  FileOutputStream fos=null;
  BufferedInputStream bis=null;
  BufferedOutputStream bos=null;
  try {
   fis=new FileInputStream("G:/图/IMG_0054.JPG");//地址
   dis=new DataInputStream(fis);
   bis=new BufferedInputStream(fis);
   fos=new FileOutputStream("E:/视频/myphote.JPG");
   dos=new DataOutputStream(fos);
   bos=new BufferedOutputStream(fos);
   byte [] b=new byte[1024];
   int len=-1;
   while((len=bis.read(b))!=-1){
    bos.write(b);
   }
   System.out.println("写完");
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   try {
    bos.close();
    dos.close();
    fos.close();
    bis.close();
    dis.close();
    fis.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

案例6:序列化与反序列化

public static void main(String[] args) {
  Student stu=new Student("小红",18,"123456");
  InputStream is=null;
  ObjectInputStream ois=null;
  //这是序列化,是把对象写进流中,是输出
  OutputStream os=null;
  ObjectOutputStream oos=null;
  try {
   //序列化
   os=new FileOutputStream("G:/测试/hello.txt");//输出流
   oos=new ObjectOutputStream(os);
   oos.writeObject(stu);//传入的参数是Object类型
   os.flush();
   is=new FileInputStream("G:/测试/hello.txt");//输入流
   ois=new ObjectInputStream(is);
   Student s=(Student)ois.readObject();
   System.out.println(s.getName()+" "+s.getAge()+" "+s.getPassword());
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }finally{
   try {
    ois.close();
    is.close();
    oos.close();
    os.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  
 }

原文地址:https://www.cnblogs.com/shmilynanmei/p/8883621.html