zoukankan      html  css  js  c++  java
  • java——IO流

    一. File

    • File类可以使用文件路径字符串来创建File实例,该文件路径可以是绝对路径或相对路径
    • File类的list()方法中可以接收一个FilenameFilter参数,通过该参数可以只列出符合条件的文件

    二. 流(Stream)

    • Stream是从起源(source)到接收(sink)的有序数据
    • 按照流向分可以分为输入流和输出流 
      • 输入流:只能从中读取数据,不能写入数据(基类是InputStream和Reader)
      • 输出流:只能向其中写入数据,不能读取数据(基类是OutputStream和Writer)
    • 按照操作的数据单元分为字节流和字符流 
      • 字节流:操作的数据单元是8位的字节(基类是InputStream和OutputStream)
      • 字符流:操作的数据单元是16位的字节(基类时Reader和Writer)
    • 按照角色可以分为节点流和处理流 
      • 节点流:可以从/向一个特定的IO设备中读/写数据的流,也被称为低级流
      • 处理流:用于对一个已存在的流进行连接或封装来实现读/写功能,也称为高级流或包装流

    三、   数据流的基本概念

    1.数据流

    在Java中把不同的数据源与程序之间的数据传输都抽象表述为“流”(stream),以实现相对统一和简单的输入/输出操作方式。传输中的数据就像流水一样,也称为数据流。

    2 .I/O数据流的分类方式

    数据流分为输入流和输出流两类。输入流只能读取不能写。而输出流只能写不能读。(这里站在程序的角度来确定出入方向,即将数据从程序外部传送到程序中谓之“输入”数据,将程序中的数据传送到外部谓之“输出”数据。

    3.缓冲流(Buffered Stream)

    对数据流的每次操作都是以字节为单位进行的,既可以向输出流写入一个字节,也可从输入流中读取一个字节。显然效率太低,通常使用缓冲流,即为一个流配置一个缓冲区,一个缓冲区就是专门传送数据的一块内存。

    4.数据源(Data Sourcc):是指那些能够提供数据的地方,包括键盘、磁盘文件、网络接口等。

    5.数据宿(Data Sink):指能够接收数据的地方,可以是磁盘文件、网络接口以及显示器、打印机等外部设备。(数据宿也可认为是数据传输的目的地)

    二、节点流和处理流

    根据数据流所关联的是数据源还是其他数据流,可分为节点流(Node Stream)和处理流(Processing Stream)

    节点流可以从/向一个特定的地方读/写数据。

    处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现增强的数据读/写功能,处理流并不直接连接到数据源。

    二、   字符流

    1.字符输入流Reader

    Reader类为所有面向字符的输入流的超类,声明为java.io中的抽象类。

    public int read():读取一个字符,返回的是读到的那个字符。如果读到流的末尾,返回-1。

    public int read(char[] cbuf):将读到的字符存入指定的数组中,返回的是实际读取的字符数。如果读到流的末尾,返回-1。

    public abstract int read(char[] cbuf,int off,int len):将读到的字符存入数组的指定位置(off),每次最多读len个字符,返回实际读取的字符数。如果读到流的末尾,返回-1。

    close():读取字符其实用的是window系统的功能,使用完毕后,进行资源的释放。

     

    2.字符输出流writer

    Weiter类为所有面向字符的输出流的超类,声明为java.io中的抽象类。

    public void write(int c):将一个字符写入到流中。

    public void write(char[]):将数组中的字符依次写出。

    public abstract void write(char[] bcbuf,int off,int len):将数组中下标off开始的len个字符写出。

    public void write(String):将一个字符串写入到流中。

    public abstract void flush():刷新流,将流中的数据刷新到目的地中,流还存在。

    public abstreact void close():关闭资源,关闭前会先调用flush,刷新流中的数据去目的地,然后流关闭。

    3. FileWriter的使用

    该类没有特有的方法。只有自己的构造数。

    该类特点:

    1.用于处理文本文件。

    2.该类中有默认的编码表,

    3.该类中有临时缓冲。

    构造函数

    publicFileWriter(Stringfilename);//调用系统资源,在指定位置,创建一个文件。注意:如果该文件已存在,将会被覆盖。

    IO流的几个相关联系题:

    eg1:编写Java程序:删除指定的文件或文件夹,如果文件夹中有文件或子文件夹也一并删除。

    public void deleteFile(File file){
            //分析:
            //1.首先判断该路径file是否存在,如果不存在,即终止删除程序,如果存在,进行第2步:
            //2.判断路径file是文件还是文件夹,若为文件,则直接删除,若为文件夹,则进入第3布:
            //3.判断文件夹是否为空,若为空,直接删除该文件夹
            //4.若不为空,则记录文件夹下所有文件列表,利用for-each与递归算法删除所有内容,最后删除该文件夹本身
            if(!file.exists()){
                return;
            }
            if(file.isFile()){
                file.delete();
                System.out.println("正在删除文件:"+file.getAbsolutePath());
                return;
            }
            if(file.isDirectory()){
                if(file.list().length==0){
                    file.delete();
                    System.out.println("正在删除文件夹:"+file.getAbsolutePath());
                    return;
                }
                File[] file1 = file.listFiles();
                for(File f:file1){
                    deleteFile(f);
                }
                file.delete();
            }
        }

    eg2:编写一个Java程序,要求每次运行该程序时打印出当前是第几次运行,即使计算机重启也能正常计数。
     

     1 public void getCountTest() throws IOException{
     2         //注意:两个流不能同时访问同一个文件!
     3         //DataOutputStream data1 = new DataOutputStream(new FileOutputStream(file));
     4         //该数据输出流每执行一次都会将原file路径下文件内容刷新一次(即覆盖)
     5         File file = new File("E:/count");
     6         if(!file.exists()){//判断file路径是否存在
     7             file.createNewFile();//创建file路径指定的文件count
     8         }
     9         DataInputStream data = new DataInputStream(new FileInputStream(file));
    10         int x;
    11         try {
    12             x=data.readInt();
    13             data.close();
    14         } catch (EOFException e) { //若x=data.readInt();读不到数据(如果此输入流在读取这四个字节之前到达末尾),则会抛出EOFException异常
    15             data.close();//在使用输出对象data1之前关闭输入管道,避免同时操作
    16             DataOutputStream data1 = new DataOutputStream(new FileOutputStream(file));
    17             data1.writeInt(1);
    18             data1.flush();
    19             data1.close();
    20             System.out.println("程序第"+1+"次运行");
    21             return;
    22         }
    23         DataOutputStream data1 = new DataOutputStream(new FileOutputStream(file));
    24         data1.writeInt(++x);
    25         System.out.println("程序第"+x+"次运行");
    26         data1.flush();
    27         data1.close();
    28     }

     eg3:编写Java程序:实现文件夹的复制:

      |--该方法实现了将路径file2下文件拷贝至路径file1下文件

     1 @Test
     2     public void testCopy() throws IOException {
     3         File file1 = new File("E:\");
     4         File file2 = new File("E:\Desktop\饮水机项目_20161221_4");
     5         copyOne(file1,file2);
     6     }
     7     public void copyOne(File file1,File file2) throws IOException{
     8         if(!file2.exists()){
     9             return;
    10         }
    11         if(file2.isFile()){
    12             InputStream in = new FileInputStream(file2);
    13             OutputStream out = new FileOutputStream(new File(file1,file2.getName()));
    14             byte[] b = new byte[1024*1024];
    15             int len=-1;
    18         while((len=in.read(b))!=-1){
    19                 out.write(b,0,len);
    20             }
    21             in.close();
    22             out.flush();
    23             out.close();
    24             return;
    25         }
    26         if(file2.isDirectory()){
    27             File temp = new File(file1,file2.getName());
    28             temp.mkdir();
    29             if(file2.list().length==0){
    30                 return;
    31             }
    32             File[] fi = file2.listFiles();
    33             for(File f:fi){
    34                 copyOne(temp,f);
    35             }
    36         }
    37     }

     eg4:开发一个Java程序,实现将一个GBK编码的文件转为UTF-8编码的文件。

     1 @Test
     2     public void codeChange() throws Exception{
     3         //桥接流:字节流通向字符流的桥接流
     4         InputStreamReader in = new InputStreamReader(
     5                 new FileInputStream("E:/my.java"),"GBK");    //解码
     6         //桥接流:字符流通向字节流的桥接流
     7         OutputStreamWriter out = new OutputStreamWriter(
     8                 new FileOutputStream("E:/your.java"),"UTF-8");    //编码
     9         int k = -1;
    10         while((k=in.read())!=-1){
    11             out.write(k);
    12         }
    13         in.close();
    14         out.flush();
    15         out.close();
    16     }
    17     @Test //通过桥接字符流的便捷流(子类流)FileReader和FileWriter来快速实现
    18     public void codeChange2() throws Exception{
    19         FileReader in = new FileReader("E:/my.txt");    //解码
    20         FileWriter out = new FileWriter("E:/your.txt");    //编码
    21         int k = -1;
    22         while((k=in.read())!=-1){
    23             out.write(k);
    24         }
    25         in.close();
    26         out.flush();
    27         out.close();
    28     }

     eg5:将从控制台输入的信息保存到一个文件中去。(中文不能乱码,建议使用System.in、Scanner和InputStreamReader等)
     

     1 //方法一:
     2     @Test
     3     public void scannerTest() throws Exception{
     4         Scanner scanner = new Scanner(System.in);
     5         PrintWriter out = new PrintWriter("E:/myWrite");
     6         String line = null;
     7         while(!(line=scanner.nextLine()).equals("exit")){
     8             out.println(line);
     9         }
    10         scanner.close();
    11         out.flush();
    12         out.close();
    13     }
    14     //方法二:
    15     @Test
    16     public void bufferedReaderTest() throws Exception{
    17         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    18         PrintWriter out = new PrintWriter("E:/myWrite");
    19         String line = null;
    20         while(!(line=in.readLine()).equals("exit")){
    21             out.println(line);
    22         }
    23         in.close();
    24         out.flush();
    25         out.close();
    26     }

     eg6:开发一个Java程序,统计每个java源文件的代码行数和所有java源文件的总行数(不含空行)

     1 private static int count;
     2     @Test
     3     public void testGetAllCount() throws Exception{
     4         File file = new File("D:/workspace/Test");
     5         getAllCount(file);
     6         System.out.println(count);
     7     }
     8     public void getAllCount(File file) throws Exception{
     9         if(!file.exists()){
    10             return;
    11         }
    12         if(file.isFile()){
    13             BufferedReader buffer = new BufferedReader(
    14                     new InputStreamReader(new FileInputStream(file)));
    15             String line=null;
    16             while((line=buffer.readLine())!=null){
    17                 if(line.trim().length()!=0){
    18                     count++;
    19                 }
    20             }
    21             buffer.close();
    22         }
    23         if(file.isDirectory()){
    24             for(File f:file.listFiles()){
    25                 getAllCount(f);
    26             }
    27         }
    28     }
  • 相关阅读:
    PHPStorm下XDebug配置
    HDU 4633 Who's Aunt Zhang (Polya定理+快速幂)
    VC++深入详解-第五章学习心得
    nginx access log logrotate配置
    判断变量是否存在(python)
    一步一步学android之布局管理器——LinearLayout
    向前辈致敬 strspn
    poj 1087 (最大流)
    cocos2d-x Touch 事件应用的一个例子
    [置顶] C#扩展方法 扩你所需
  • 原文地址:https://www.cnblogs.com/FrankLei/p/6244915.html
Copyright © 2011-2022 走看看