zoukankan      html  css  js  c++  java
  • I/O操作

    JavaIO 类和接口存在于java.IO包中

     

    总结:重点掌控:

    1):   文件流 :字节/字符,读取/写入流. File开头的四个类

    2):   缓冲流: 字节/字符,缓冲读取/写入流.Buffered开头的四个类

    3):   对象流-序列化和反序列化(重点了解):  ObjectOutputStream  /  ObjectInputStream

    4):   打印流:       printStream  /  printWriter

    5):   转换流(字节转换成字符)InputStreamReader/OutputStreamWriter

    Java1.7开始使用Files.copy(Path source, OutputStream out);将文件中的所有字节复制到目标文件

     

    File类(文件)

     

    介绍和路径分隔符:

    File类是IO包中唯一表示磁盘文件磁盘目录的对象的路径

    该类包含了创建、删除文件、重命名文件、判断文件读写权限以及文件是否存在,查询等功能方法。

    只能设置和获取文件本身的信息,不能设置和获取文件的内容。

    路径分隔符、属性分隔符

    Unix:     使用“/”来分割目录路径。  使用“:”来分割属性
    windows:使用“”来分割目录路径。也支持“/”。  使用“;”来分割属性
    ---------------------------------------------

    File提供了两类常亮分别来提供路径分割符、属性分隔符。

    1):路径分隔符

    2):属性分隔符

    表示文件路径:

    操作File的路径和名称

     

     

          File getAbsoluteFile()  返回绝对路径名。

          String getAbsolutePath()  返回绝对路径名。

          String getPath() 返回文件路径。

          String getName() 返回由文件的名称。

          String getParent() 返回上级目录文件。

          File getParentFile() 返回此上级目录路径。

     

      

    public static void test1(){

          // 创建对象

          File file = new File("F:/Eclipse/eclipse/tset.java");

       System.out.println(file.getAbsoluteFile());//F:Eclipseeclipse set.java

       System.out.println(file.getAbsolutePath());//F:Eclipseeclipse set.java

          System.out.println(file.getName());//tset.java

          System.out.println(file.getPath());//F:Eclipseeclipse set.java

          System.out.println(file.getParent());//F:Eclipseeclipse

          System.out.println(file.getParentFile());////F:Eclipseeclipse

       }

    检测File状态的方法

     

          boolean canExecute() 测试应用程序是否可以执行的文件。

          boolean canRead() 测试应用程序是否可以读取的文件。

          boolean canWrite() 测试应用程序是否可以修改的文件。

          boolean isHidden() 测试文件是否是一个隐藏文件。

           long lastModified()  返回此文件最后一次被修改的时间(单位:毫秒)。

          long length() 返回文件的长度大小(单位:字节)。

        

       private static void test2() {

          File file = new File("F:/Eclipse/eclipse/eclipse.exe");

          System.out.println(file.canExecute());//true

          System.out.println(file.canRead());//true

          System.out.println(file.canWrite());//true

          System.out.println(file.isHidden());//false

          System.out.println(file.lastModified());//1475816570000

          System.out.println(new Date(file.lastModified()).toLocaleString());

          System.out.println(file.length());//319984

       }

     

    File类中方法:文件操作

    boolean isFile() 是否是文件。

    boolean createNewFile() 创建一个新的空文件。

    static File createTempFile(String prefix, String suffix,File directory)  创建临时文件.

    boolean delete() 删除文件 .

    void deleteOnExit() 在JVM终止时,删除文件。

    boolean exists() 判断文件是否存在。

    boolean renameTo(File dest)  重新命名文件。 

       private static void test3() {

          File file = new File("D:/搜狗高速下载/123456.txt");

          System.out.println(file.isFile());//true

          try {

              new File("D:/搜狗高速下载/123456.java").createNewFile();//创建一个新的文件

          } catch (IOException e) {

              e.printStackTrace();

          }

          //file.renameTo(new File("D:/搜狗高速下载/456.txt"));

          file.delete();

         

          //创建临时文件static File createTempFile(String prefix, String suffix,File directory)

          //(perfix临时文件前缀)( suffix临时文件后缀)(directory临时文件保存位置)

          try {

              File.createTempFile("apple", ".rar", new File("D:/搜狗高速下载"));

          } catch (IOException e) {

             

              e.printStackTrace();

          }

       }

    File类中方法:目录操作

    boolean isDirectory(); 判断是否是目录。
    boolean mkdir();  创建目录。 
    boolean mkdirs()  创建当前目录和上级目录.
    String [] list(); 列出所有的文件名
    File [] listFiles(); 列出所有文件对象
    Static File[] listRoots();列出系统盘符.
    boolean delete() 删除目录/文件 .
    oid deleteOnExit() 在JVM终止时,删除目录/文件。 
    boolean exists() 判断文件/目录是否存在。
    boolean renameTo(File dest)  重新命名目录/文件名。

    public static void test4(){

          File file = new File("D:");

          File file1 = new File("D:/搜狗高速下载");

          System.out.println(file.isDirectory());//false

          System.out.println(file1.isDirectory());//true

          file1.delete(); // 删除目录

          file1.mkdir();//创建多级目录建议使用mkdirs();

          String str[] = file1.list();//列出所有文件名

          for (String string : str) {

              System.out.println(string + " ");

          }

          File file2[];

          file2 = File.listRoots();//列出系统盘符

          for (File string : file2) {

              System.out.println(string + " ");

          }

          file2 = file.listFiles();//列出虽有文件夹名和文件名

          for (File string : file2) {

              System.out.println(string + " ");

          }

    }
     

    输入和输出(IO)

     

    为什么程序需要IO?

     

    案例一: 打游戏操作,得分比较高,储存游戏的信息(XXX-888分).

    此时需要把游戏中的数据储存起来,只能储存在文件中.

    案例二:打游戏操作,查看游戏排行榜.排行榜的数据储存在一个文件中的.

    此时游戏程序需要去读取文件中的数据,并显示在游戏中.

    案例三:上传和下载操作.

    -----------------------------

    IO操作是一个相对的过程.一般的我们站在程序角度思考(程序的内存)

    程序需要数据:把数据流入到程序中,输入

    程序需要保存数据,在把数据传递

    O流的分类和操作模板:

    IO流的分类:站在不同的角度,分流方式是不一样的

    1):根据流向划分:  输入流和输出流.

    2):根据数据的单位划分:      字节流和字符流.

    3):根据功能不同的划分:      节点流和包装流.

    ---------------------------------------------------------------

    四大基流(字节输出流(Writer),字节输入流(Reader),字符输出流(OutputStream).字符输入流(InputStream))

    四大基流都是抽象类:其他流都是继承与这四大基流.

    我们不能创建四大基流的对象,只能创建其子类对象

    无论是什么流,都有close方法,用来关闭资源

    如果操作文件,就得开通一个流对象关联我们的磁盘文件,如果不关闭资源,那么磁盘的文件一直被程序所引用.

     

    操作IO流的模板:

    1):创建源或者目标对象(挖井)

    拿文件流距离

    输入操作:把文件中的数据流向到程序中,此时文件是源,程序是目标

    输出操作:把程序中的数据流向到文件中,此时程序是源,文件是目标.

    2):创建IO流对象(接水管)

    输入操作:创建输入流对象

    输出操作:创建输出流对象;

    3):具体的IO操作(传输):

    输入操作:输入流对象的read 方法

    输出操作:输出流对象的write方法

    4):关闭资源(关闭):

    输入操作:输入流对象的close方法

    输出操作:输出流对象的close方法

    操作IO流的六字箴言:

    读进来,写出去.

    读进来:进来强调的是输入,说明是read()方法

    写出去:出去强调的是输出,说明是write方法

    文件流

    程序跟文件打交道

     

    此时的文件指的是纯文本文件.txt(笔记本那种,不要使用Word Excel)

    -----------------------------------------------

    FileInputStream 文件的字节读取流:

    import java.io.File;

    import java.io.FileOutputStream;

    /**
    * 文件的写入流
    * @author Mr.Bai
    *
    */
    public class FileOutputStreamDemo {

    public static void main(String[] args) throws Exception {
    //1:创建目标对象
    File file = new File("Ceshi/abc.txt");
    //创建文件字节输出流对象
    FileOutputStream stream = new FileOutputStream(file,true);
    /*具体的输出操作
    void write(int b) 将指定字节写入此文件输出流。
    void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
    (常用)void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
    */
    stream.write(68);
    byte [] a = "ABCDEFGHIJKLMN".getBytes();
    stream.write(a);//添加一个char字符的数组.
    stream.write(a, 3, 6);//添加字符串的指定位置(不含)开始一定长度的字符

    //关闭资源对象
    stream.close();
    }

    }

    FileOutputStream  文件的字节写入流

    import java.io.File;
    import java.io.FileOutputStream;

    /**
    * 文件的写入流
    * @author Mr.Bai
    *
    */
    public class FileOutputStreamDemo {

    public static void main(String[] args) throws Exception {
    //1:创建目标对象
    File file = new File("Ceshi/abc.txt");
    //创建文件字节输出流对象
    FileOutputStream stream = new FileOutputStream(file,true);
    /*具体的输出操作
    void write(int b) 将指定字节写入此文件输出流。
    void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
    (常用)void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
    */
    stream.write(68);
    byte [] a = "ABCDEFGHIJKLMN".getBytes();
    stream.write(a);//添加一个char字符的数组.
    stream.write(a, 3, 6);//添加字符串的指定位置(不含)开始一定长度的字符

    //关闭资源对象
    stream.close();
    }

    }

    利用字节流完成文件的拷贝操作:

    正确关闭资源和处理异常的代码:

     

    Java 1.7以前:

    java1.7(含)以后  自动资源关闭(推荐)

    获取进程数据,编译和运行java代码

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;

    /**
    * 获取进程数据,编译和运行java代码
    * @author Mr.Bai
    *
    */
    public class Precessemo {
    public static void main(String[] args) {
    String arr = "System.out.println("我的世界我做主!")";
    //System.out.println(arr);
    try {
    eval(arr);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    //运行该方法后,要求控制台输出--我的世界我做主!
    private static void eval(String arr) throws Exception {
    //1: 使用StringBuider拼接出一个完整的Word程序的字符串
    StringBuilder str = new StringBuilder(50);
    str.append("public class Word{");
    str.append("public static void main(String [] args){");
    str.append(arr+";");
    str.append("}");
    str.append("}");
    //System.out.println(str);
    //2:添加到Word.java的文件中去
    FileOutputStream out = new FileOutputStream("F:Word.java");
    out.write((str.toString().getBytes()));
    out.close();
    //3:调用javac进程来编译Word.java
    Process ard =Runtime.getRuntime().exec("javac Word.java");
    //读取javac进程中的错误信息
    InputStream err = ard.getInputStream();
    //读取流中的数据
    byte [] buf = new byte[1024];
    int len = 0;
    while((len = err.read(buf)) > 0){
    String string = new String(buf, 0, len);
    System.out.println(string);
    }
    err.close();
    //调用java进程来运行Word.class
    ard =Runtime.getRuntime().exec("javac Word");
    //读取进行中的流信息
    InputStream io = ard.getInputStream();
    //读取流中的数据
    byte [] buy = new byte[1024];
    while((len = io.read(buy)) > 0){
    String string = new String(buf, 0, len);
    System.out.println(string);
    }
    io.close();
    //删除java和class文件
    new File("Word.java").delete();
    new File("Word.class").delete();
    }
    }

    文件字符流

    FileReader       文件的字符读取流

    import java.io.File;
    import java.io.FileReader;

    /**
    * 文件字符读取流
    * @author Mr.Bai
    * 实例 java 1.7后 资源自动关闭
    */
    public class FileReaderDemo {

    public static void main(String[] args) {
    File file = new File("Ceshi/abcdef.txt");

    try ( //创建读取流对象
    FileReader read = new FileReader(file);) {
    //读取操作
    //int read(char[] cbuf);将字符读入数组。读取的字符数,如果已到达流的末尾,则返回 -1
    char[] sd = new char[5];
    int len = 0;
    while ((len = read.read(sd)) > 0) {
    String str = new String(sd, 0, len);
    System.out.println(str);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    //资源自动关闭
    }

    }

    FileWriter         文件的字符写入流

    import java.io.File;
    import java.io.FileWriter;

    /**
    * 文件字符流写入操作
    * @author Mr.Bai
    *
    */
    public class FileStreamDemo {

    public static void main(String[] args) {
    //创建目录
    File file = new File("Ceshi/新写入的文件.txt");
    try (//创建写入源对象
    FileWriter out = new FileWriter(file,true);){
    //写入操作
    /* 创建需要写入的字符String类型
    * 第一种: 通过 void write(String str)写入字符串。
    * 第二种: 讲写好的字符串转换成char数组(char [] toCharArray()方法),再将char数组录入到指定目录中
    */
    String str = "我爱中国!我爱我家!";
    out.write(str);
    out.write(str.toCharArray());
    }catch (Exception e) {
    e.printStackTrace();
    }
    }

    }

    文件拷贝

    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;

    /**
    * 文件字符流的拷贝操作
    * @author Mr.Bai
    *
    */
    public class DocumentCopyDome {
    public static void main(String[] args) {
    //创建源
    File file = new File("Ceshi/新写入的文件.txt");
    //创建目标
    File outFile = new File("Ceshi/复制的文件.txt");
    try( //创建流对象
    //创建源读取流
    FileReader reader = new FileReader(file);
    //创建目录写入流
    FileWriter writer = new FileWriter(outFile);
    ){
    //读取操作
    char [] sd = new char[1024];
    int len = -1;
    //循环读取到char数组中
    while((len = reader.read(sd)) > 0){
    //循环录入到char数组中
    writer.write(sd);
    }
    }catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    使用字节流操作汉子或特殊符号的时候,容易乱码,建议使用字符流

    先有字节流,后又字符流,字符流是对字节流的补充

    二进制文件:使用记事本打开某个文件,可以看到内容的就是文本文件,否则可以理解为二进制.

    一般的操作,二进制文件必须使用字节流.

    一般的,操作文本文件,使用字符流.

    字符的解码和编码操作

    编码: 把字符串转换成byte数组

     

    解码: byte数组转换成字符串

     

    一定要保证编码和解码的字符相同,否则乱码

    包装流和缓冲流

    处理流/包装流(相对于节点流更高级):

    1:隐藏了底层的节点流的差异,并对外提供了更方便的输入/输出功能,让我们只关心高级流的操作.

    2:使用处理流包装了节点流,程序直接操作处理流,让节点流雨底层的设备做IO操作.

    3.只需要关闭处理流即可.

    包装流如何区分:写代码的时候,发现创建对象的时候,需要创建另一个流对象.

    new 包装流(流对象);

    --------------------------------------------

    缓冲流:

    定义:是一个包装流,目的是起缓冲作用.

    Sun提供的缓冲区:大小是:8192(1024*8),我们一般不用提升大小,使用默认.

    BufferedInputStream:

    BufferedOutputStream;

    BufferedReader;

    BufferedWriter;

    目的:

    操作流的时候,习惯定义一个byte/char数组,该数组其实就是一个缓冲区.

    Int read();每次都从磁盘文件中读取一个字节,直接操作磁盘文件,性能极低.

    解决方案:定义一个数组作为缓冲区.

    Byte/char [] a = new byte/char[1024];该数组其实就是一个缓冲区,一次性从磁盘文件中读取1024个字节,如此一来,操作磁盘文件的次数少了,性能得以提升.

     

    实际操作:

     

    使用缓冲流跟未使用缓冲流的比较

    转换流

    转换流:把字节流转换成字符流

    InputStreamReader : 把字节输入流转换成字符输入流

    OutputStreamWriter : 把字节读取流转成字符读取流

    内存流(储存数据)

     

    字节内存流(安卓会用到):

    字符内存流(基本不用)

    字符串流

    StringWriter 字符串的写入流

    StringReader 字符串的读取流

    对象流(序列化和反序列化)-服务器做的

    以后对于我们需要共享数据的类也必须实现Serializable接口.

    一些属性出于安全考虑,不应该被序列化,如:密码 解决的办法是该属性使用transient修饰.

    使用对象流来完成序列化和反序列化操作:

    ObjectOutputStream 通过writeObject方法做序列化操作.

    ObjectInputStream 通过readObject方法做反序列化操作.

     序列化的细节,序列化的版本:

    1);如果某些数据不需要做序列化,那么此时该怎么做?

    理论上说:静态的字段和瞬态的字段是不能做序列化操作的.

    transient 修饰的成员.

    2):序列化的版本问题:

    反序列化java对象时,必须提供该对象的class文件,现在问题是:随着项目的升级,系统的class文件也会升级(增加/删除一个字段).

    如何保证两个class文件的兼容性? java通过seriaIversionUID(序列版本号)

    打印流(写入)

    PrintStream  字节打印流

    PrintWrite       字符打印流

    -对于PrintWrite来说,

     PrintWriter writer = new PrintWriter(new FileOutputStream("add.txt"),true);

    启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时便会立马刷新操作.

    如果没有开启自动刷新,则需要手动刷新,或者当缓存区满的时候,在自动刷新.

    使用打印流作为输出流,此时的输出操作会特别简单,因为在打印流中:

    提供了print方法,打印不换行

    提供了println方法,打印在换行.

    这两个方法支持打印各种数据类型的数据.因为参数为(Object t);

    打印流中的格式化输出(printf方法):

    二进制文件的读取操作

    DataInputStream  读取二进制文件

    DataOutputStream 写入二进制文件

     

     

    标准的输入输出:

     

    在system类中,有两个常量:

    InputStream in = System.in; “标准”输入流.

    PrintStream out = System.out;

    标准流的重定向操作:

    重新定制输入的方向不再是键盘,而是一个文件.

     static void setIn(InputStream in)重新分配“标准”输入流。

    此后,System.in的=数据的来源就是通过setIn指定的源.

     

    Properties类加载文件

    配置文件:资源文件(properties作为拓展名的文件)/属性文件:

     

    做项目开发,为何要使用配置文件?

    把所有的数据储存在代码中,写死了,”硬性编码”;

    比如:在java中需要连接数据库,必须拥有数据的账号和密码.

    此时我们就得在java代码中编写类似的代码:

    String ID = “Admin”;

    String password = “asdfghjkl@16,#5”;

    代码程序运行OK

    但是,以后我们把项目部署在别人电脑/服务器中,别人电脑中的数据库的账号密码可以不再是Admin和asdfghjkl@16,#5,此时我们就得去项目中导出去找使用了行号密码的地方.

    部署项目的是实施人员,为了安全操作,不能让其直接修改代码.

    此时,我们专门为数据库提供了一个配置文件,里面专门储存数据库连接相关的信息

    -------------------------------------------------------------

    Db.properties

    -------------------------------------------------------

    #key = value;

    ID = Admin

    Password = asdfghjkl@16,#5

    ..........

    ---------------------------------------------------------

    现在数据库的连接信息在db.properties文件中,java代码需要获取该文件中的信息

     

    重心转移:java代码如何加载properties文件,如何获取该文件中的数据

    必须使用properties类 Hastable 的子类,Map借口的实现类.

    随机访问文件

    随机访问文件(RandomAccessFile):表示看在该文件的任何位置写入和读取数据.

    管道流(了解)

  • 相关阅读:
    【HDOJ】2267 How Many People Can Survive
    【HDOJ】2268 How To Use The Car
    【HDOJ】2266 How Many Equations Can You Find
    【POJ】2278 DNA Sequence
    【ZOJ】3430 Detect the Virus
    【HDOJ】2896 病毒侵袭
    求奇数的乘积
    平方和与立方和
    求数列的和
    水仙花数
  • 原文地址:https://www.cnblogs.com/it-xiaoBai/p/8081312.html
Copyright © 2011-2022 走看看