• Java学习笔记---IO操作


    一、文件的创建
    -------------------------------------------------------
    File类,表示磁盘上的文件或目录,可对文件或目录进行操作. 
      * 常用方法
        File.separator  separator用于表示目录间的分隔符
        creatNewFile() 创建一个新文件
      mkdir() 创建一个目录
        delete() 可以将文件删除
      deleteonExit() 当程序终止后删除文件
        createTempFile() 创建临时文件
        list() 反回当前目录下的所有文件名和子目录的名字
        isDirectory() 判断是不是目录
        isFile 判是不是文件
        FilenameFilter() 文件名的过滤器,它是个接口,
            它有个方法accept(File dir,String name)返回企为值为boolean型,判断每个文件名是不是,符合要求  

    1. 创建一个文件
       File f=new File("1.txt");
       f.creatNewFile(); //创建一个名为1.txt的文件
      f.mkdir(); //创建一个名为1.txt的目录

    2. File f=new File("E://java//abc//1.text"); //在windows下可以这么做,在linux下则不行,linux下没有盘符
       f.createNewFile(); 在e:/java/abc下创建1.text文件
     -----------------------------------------------------
    3. File fDir=new File(File.separator);  //separator用于表示目录间的分隔符,这里是表示在系统根目录下
                                              也可以 File fDir=new File(/); Windows可以这样表示跟目录
       String strFile="java"+File.separator+"abc"+file.separator+"1.txt"; //  java/abc/1.txt
      File f=new File(fDir,strFile); //fDir是创建文件的父目录,strFile是文件位置
       f.createNewfile();
       f.delete() //可以将文件删除
      
      f.deleteonExit() //当程序终止后删除文件  
       Thread.sleep(3000); //3秒后程序会结束,这样这个文件创建3秒后,程序结束,然后执deleteonExit删除文件
     --------------------------------
    4. for (int i=0;i<5;i++)
     { File f=File.createTempFile("winsun",".tmp"); //创建5个临时文件,文件名是winsun,后缀名是tmp,文件位置在环境

    变量的temp所指定的临时文件的目录下   createTempFile是一个静态变量,可以直接调用
       f.deleteOnExit();
     }
     Thread.sleep(3000);


      for (int i=0;i<5;i++)
     { File.createTempFile("winsun",".tmp"); } //可以这样直接创建5个临时文件
     ---------------------------------
    5. File fDir=new File(File.separator); 
      String strFile="java"+File.separator+"abc"+file.separator+"aa"; //因为list()显示的目录是从当
                                      前文件所在盘开始的,所以必须
                                                                        从跟目录一直找到要用到的文件目录 
     File f=new File(fDir,strFile);
     if (f.isDirectory()) //判断是不是目录
     {   String[] names=f.list(); //list返回的是一个String类型的静态数组
         for (int i;i<names.length;i++)
        { System.out.println(names[i]); }
     } 
     else
     { System.out.println("没有该目录"); 
     } 
    ------------------------------------------
    6. 文件名的过滤器的用法
    File fDir=new File(File.separator);
     String strFile="java"+File.separator+"abc"; 
     File f=new File(fDir,strFile);
     String[] names=f.list(new FilenameFilter()      //在list()中建个文件过滤器
     { public boolean accept(File dir,String name)
     { return name.indexOf(".java")!=-1; }  // 显示扩展名为.java的文件,如果不等于-1返回true,否则返回flase
     }); //匿名内部类,在查看java原文件中看到,File的list(FilenameFilter filter)方法中,自已调用了accept方法,
           
     for (int i;i<names.length;i++)
     { System.out.println(names[i]); } 
    ---------------------------------------------
    *********************************************
    ---------------------------------------------
    二、文件的读写
    流的分类:1、节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
         2、过滤流:使用节点流作为输入输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。
    * InputStream 
         三个基本的读方法
     abstract int read() : 读取一个字节的数据,但是按整型返回的,如果返回-1表示读到了文件流的末尾。
                            整型占四个字节,它的第一个字节才是有效的数据(注意)
     int read(byte[] b)  :  将数据读入一个字节数组,同时返回实际读取的字节数   
     int read(byte[]b,int off,int len) 
       其它方法
     long skip(long n): 在输入流中跳过n个字节,并返回实际跳过的字节数。
     int available(): 返回可读取的字节数。
     void close():关闭输入流,释放和这个流相关的系统资源。
     void mark(),void reset(),booleanmarkSupported(),在这个流中都是空实现的方法


    * ouputStream
        三个基本的写方法
     abstract void write(int b): 往输出流中写入一个字节,但传进去一个整型的数据,它只写整型的第一个字节 
     void write(byte[] b)
     void write(byte[]b,int off,int len)
        其它方法
     void flush(): 刷新输出流,强制缓冲区中的输出字节被写出。(它只对使用了缓冲的流类起作用)
     void close():关闭输出流 

    --------------------------------
    System.in 和 System.out 的 in 和out 都是PrintStream类型的

    import java.io.*;
    class StreamTest
    { public static void main(String[] args)throws Exception
      { int data;
        while((data=System.in.read())!=-1)  //read它可以读取一个字节的数据,但它的返回值是一个整型,如果返回-1说明

    已经到了流的结尾
        { System.out.write(data);}    //write方法的参数也是整型
     }
    }
        
    ---------------------------------------------------
    ***文件输入输出流 FileInputStream FileOutputStream (节点流)***
    FileOutputStream fos=new FileOutputStream("1.txt")
    fos.write("http://hongxuan.ful.cn".getBytes());  //write只能写入一个字节或是一个字节数组,不能写入字符串,但它的getBytes能获取一个字节数组
    fos.close();

     FileOutputStream fos=new FileOutputStream("1.txt",true)  //后面加true是在文件后面追加
    fos.write("http://hongxuan.ful.cn".getBytes()); 
    fos.close();

     

    FileInputStream fis=new FileInputStream("1.txt");
    byte[] buf=new byte[100];
    int len=fis.read(buf);
    System.out.println(new String(buf,0,len));
    fis.close();


    StringBuffer s=new StringBuffer();
    FileInputSteam fis=new FileInputStream();
    int c;
    while ((c=fis.read())!=-1)
      s.append((char)c);
    System.out.println(s.toString);


     ----------------------------------------
    **BufferedInputStream  BufferedOutputStream () (过滤流)使用已经存在的节点来构造,提供带缓冲的读写,提高了读写效


     BufferedInputStream 真正实现了mark()和reset()方法
     BufferedOutputStream 实现了flush()方法

    FileOutputStream fos=new FileOutputStream("1.txt");
    BufferedOutputstream bos=new BufferedOutputStream(fos);
    bos.write("http://hongxuan.ful.cn",getBytes());   //这时1.txt中并没有数据,数据在缓充区中,因为缓充区中还没有满
    // bos.flush();  //刷新缓充区,执行这条语句,就会把缓冲区中的内容写到1.txt文件中
    bos.close();    //如果不加bos.flush()的话bos.close()后,也会把数据写到1.txt中了

    FileInputStream fis=new FileInputStream("1.txt");
    BufferedInputStream bis=new BufferedInputStream(fis);
    byte[] buf=new byte[100];
    int len=bis.read(buf);
    System.out.println(new String(buf,0,len));
    bis.close();

    -------------------------------
    **DataInputStream 和 DataOutputStream (过滤流) 提供了读写java中的基本数据类型的功能
     
    FileOutputStream fos=new FileOutputStream("1.txt");
    BufferedOutputstream bos=new BufferedOutputStream(fos);
    DataOutputStream dos=new DataOutputStream(bos);   //将3个流连到一起

    byte b=3; int i=78; char ch='a';  float f=4.5f;
    dos.writeByte(b);
    dos.writeint(b);
    dos.writeChar(b);
    dos.writeFloat(b);
    dos.close();


    FileInputStream fis=new FileInputStream("1.txt");
    BufferedInputStream bis=new BufferedInputStream(fis);
    DataInputStream dis=new DataInputStream(bis);
    System.out.println(dis.readByte());
    System.out.println(dis.readInt());
    System.out.println(dis.readChar());
    System.out.println(dis.readFloat());
    dis.close();

    ------------------------------------------------------
    ** PipedInputStream 和 PipedOutputStream  (管道流,用于线程间的通信,必须同时构造管道输入流和管道输出流)

    *PipedInputStream的两个构造方法
     PipedInputStream()  
     PipedInputStream(PipedOutputStream src) 
     
     PipedInputStream 的方法connect(PipedOutputStream src) 使此传送输入流连接到传送输出流 src。

     

    import java.io.*;
     class PipedStreamTest
     {  public static void main(String[] args)
        { PipedOutputStream pos=new PipedOutputStream();
          PipedInputStream pis=new PipedInputStream();
                                   
                                 //在连接时会抛出个异常
          try{ pos.connect(pis); //可以用管道输出流连管道输入流,也可用管道输入流连管理输出流
                                   可定成 pis.connect(pos);   
               new Produer(pos).start();
               new Consumer(pis).start();
             }
          catch(Exception e)
         { e.printStackTrace(); }
        }
     }
     class Producer extends Thread
     { private PipedOutputStream pos;
       public Producer(PipedOutputStream pos)
       { this.pos=pos;  }
       public void run()
       { try
         { pos.write("Hello,welcome you!",getBytes());
           pos.close();
         }
         catch(Exception e)
         { e.printStackTrace();
         }
       }

     
     Class Consumer extends Thread
     { private PipedInputStream pis;
       public Consumer(PipedInputStream pis)
       { this.pis=pis; 
       }
       public void run()
      { try{ byte[] buf=new byte[100];
             int len=pis.read(buf);
             System.out.println(new String(buf,0,len));
             pis.close();
           }
        catch(Exception e) 
        { e.printStackTrace(); }
     }
    }

    --------------------------------------------------------------
    --------------------------------------------------------------
    --------------------------------------------------------------
    --------------------------------------------------------------
    reader  writer (两个抽象类)
    InputStreamReader 从字节流到字符流的转换
    OutputStreamWriter 从字符流到字节流的转换
     // 带缓冲的字符流
     BufferedWriter 
     BufferedReader

     //用字符流向文本文件中写入数据
     FileOutputStream fos=new FileOutputStream("1.txt");
     OutputStreamWriter osw=new OutputStreamWriter(fos);//将字符流转为字节流的输出
     BufferedWriter bw=new BufferedWriter(osw);
     bw.write("http://hongxuan.ful.cn");
     bw.close();
     
     //从文本文件中读入数据 
     FileInputStream fis=new FileInputStream("1.txt");
     InputStreamReader isr=new InputStreamReader(fis);//将字节流转为字符流读出
     BufferedReader br=new BufferedReader(isr);
     System.out.println(br.readLine());
     br.close();
     ---------------------------

    //在命令行中读入数据然后显示数据
     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br=new BufferedReader(isr);
     String StrLine;
     while((StrLine=br.readLine())!=null)
     { System.out.println(strLine);  }
     br.close();


    ----------------------------------------------------------
    ----------------------------------------------------------
    ----------------------------------------------------------
    ****RandomAccessFile类同时实现了DataInput和DataOutput接口,可以对文件随机存取,在文件任何位置
                        读取或写入数据。
                        它有一个指针,用来进行读写操作的下一数据的位置。
    写入一个字符串的方法
    writeBytes(String s); 将一个字符的两个字节的第一个字节写入到文件中,第二个字节舍弃(最好不用)
    writeChars(String s); 将两个字节表示的一个数据,全都写入到文件中
    writeUTF(String str); 英文件一般占一个字节,中文是三个字节,它会在写入数据的前面两个字节处,记录
               写入数据的长度,比如写入"myblog"这样6个字符,它会在"myblog"前记录个6。表明
                          "myblog"占六个字节长度,对应的有一个readUTF()   (最好用这个)  
    getFilePointer: 文件指针,获取文件当前位置 
    seek(long pos): 设置文件指针的偏移量,将pos设为0,文件指针就指向文件起始位置。 
        
    import java.io.*;
    class RandomFileTest
    { public static void main(String[] args) throws Exception 
      { Student s1=new Student(1,"zhangsan",98,5);
        Student s2=new Student(2,"lisi",96.5);
        Student s3=new Student(3,"wangwu",78.5);
        RandomAccessFile raf=new RandomAccessFile("student.txt","rw");
        s1.writeStudent(raf);
        s2.writeStudent(raf);
        s3.writeStudent(raf);
        
        Student s=new Student();
        raf.seek(0);
        for (long i=0;i<raf.length();i=raf.getFilePointer()) //获取一个文件的长度,它的返回值是一个long型
        { s.readStudent(raf);
          System.out.println(s.num+":"+s.name+":"+s.score);
        }
        raf.close();
      }
    }

    class Student
    { int num;
      String name;
      double score;
      public Student()
      { 
      }
      public Student(int num,String name,double score)
      {  this.num=num;
         this.name=name;
         this.score=score;
      }
      public void writeStudent(RandomAccessFile raf) throws IOException
      { raf.writeInt(num);
        raf.writeUTF(name);
        raf.writeDouble(score);
      }
      pubic void readStudent(RandomAccessFile raf) throws IOException
      { num=raf.readInt();
        name=raf.readUTF();
        score=raf.readDouble();
      }
    }
    --------------------------------------------------
    --------------------------------------------------
    --------------------------------------------------
    *****对象序列化
     * 将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。
     * 将一个对象保存到永久存储设备上称为持续性。
     * 一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。
      
      Serializable接口中没有任何方法,是个空接口,是个标识接口,对象去实现这个接口,表明这个对象,可以进行
                  序列化了。
      Externalizable接口它继承自Serializable接口
      
    ---实现对象的序列化,可利用io包中的两个类,
       ObjectOutputStream,它实现了DataOutput接口,它提供了往输出流中写入java基本数据类型的功能,
             ObjectOutputStream()    
             ObjectOutputStream(OutputStream out)
         它的方法,writeObject(Object obj)可以写入指定的对象,到对象的输出流中,它可以完成对象的序列化。

       ObjectInputStream,它实现了DataInput接口,它也提供了java基本数据类型读写的功能,
         它的方法,readObject()从对象输入流中读取一个对象。可实现对象的反序列化操作。


     *当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
     *如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
     *如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个 

    NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。

    import java.io.*;

    class ObjectSerialTest
    { public static void main(String[] args) throws Exception
      { Employee e1=new Employee("zhangsan",25,3000.50);
        Employee e1=new Employee("lisi",24,3200.40);
        Employee e1=new Employee("wangwu",27,3800.55);
        
        FileOutputStream fos=new FileOutputStream("employee.txt");
        ObjectOutputStream oos=new ObjectOutputStream(fos);
        oos.writeObject(e1);
        oos.writeObject(e2);
        oos.writeObject(e3);
        oos.close();

        FileInputStream fis=new FileInputStream("employee.txt"); 
        ObjectInputStream ois=new ObjectInputStream(fis);
        Employee e;
        for (int i=0;i<3;i++)
        { e=(Employee)ois.readObject(); //它返回的是一个Object类型,所以得转换成Employee类型
          System.out.println(e.name":"+e.age+":"+e.salary);
        }
      }
    }
    class Employee implements Serializable
    { String name;
      int age;
      double salary;   //如果在salary前加上transient,salary这个变量也不会保存
      
      transient Thread t=new Thread(); 这里的线程对象t是个不可序列化的对象,但前面要是加个transient,
                                       t这个对象就不会参与到序列化当中.
       
      public Employee(String name,int age,double salary)
      { this.name=name;
        this.age=age;
        this.salary=salary;
      }
      
      //下面的两个方法比较特殊,private的方法,一般不可以被外部调用,但下面的两个方法,可以被调用
        如果想对 对象进行控制,可以用下面的两个方法,按自已的想法去读写对象信息, 下面的这两方法就是
      在读和写的时候都没有加salary这个变量
      private void writeObject(ObjectOutputStream oos) throws IOException
      { oos.writeInt(age);
        oos.writeUTF(name);
        System.out.println("Write Object");
      }

      private void readObject(ObjectInputStream ois) throws IOException
      { oos.writeInt(age);
        oos.writeUTF(name);
        System.out.println("Read Object");
      }
    }

  • 相关阅读:
    C#用递归求阶乘 n!
    视图与表的区别和联系(小结)
    ref 和 out 的异同
    什么是重载?(最文艺的理解)
    [windows c]关于winsock2.h的recv函数的记录
    [windows c]关于指针函数和参数可变函数同时应用情况的疑问
    [windows c]CreateProcess
    c++ boost asio库初学习
    c#中ObservableCollection<T>排序方法
    安装opensuse时遇到的一些问题
  • 原文地址:https://www.cnblogs.com/toge/p/6114698.html
Copyright © 2020-2023  润新知