JAVA学习笔记Day22——详细介绍IO流

来源:互联网 发布:阿里云虚拟机 编辑:程序博客网 时间:2024/05/17 22:04

学习JAVA的已经22天了,这不是第一次接触流的概念,但这之后还是有很多的混淆,今天的这篇博客,希望和大家有有些更近一步的交流。

简单介绍:

1、流机制在java和C++中是一种重要的机制,通过流,我们可以很方便地操作文件,内存,IO设备等。流都包含与java.io包中。
2、流来源与UNIX中管道的概念,管道就是传递的源源不断的字节流,进而可以在不同的两端传递数据。所以,流一般都是有一个源端和目的端,一般是从外部设备中读取然后传到内存中,等到需要时,再从内存中取出来。

1、流的分类:(从内存的角度来讲)

按照流向:输入流、输出流
操作单元:字节流、字符流
设计模式:基础流、包装流
来源分类:文件流、内存流、网络流、控制台流(System.out System.in)
内存流:内存与内存之间传递数据,内存流。

2、字节流

1、 在内存当中,都是以字节的方式传递的,常用的类:
InputStream OutputStream
一般是对文件的操作:

FileInputStream(输入流,从文件或外部设备到内存)、FileOutputStream(输出流,从内存到其他地方),一般都是对文件的操作。FileInputStream infile = new FileInputStream("myfile.txt");FileOutputStream outfile = new FileOutputStream("results.txt");

注意:FileInputStream操作的文件必须是存在并且可读的,FileOutputStream操作的文件如果不存在,会自动创建,如果存在,则文件必须是可覆盖的。

涉及到的一个重定向:

static void setIn(InputStream in)static void setOut(PrintStream out) 

3、字符流

字符流主要是用来处理字符的。Java采用16位的Unicode来表示字符串和字符,对应的字符流按输入和输出分别称为readers和writers。
一般是对文件的操作:

对文件操作的字符流有FileReader/FileWriter

4、转换流

转换流:java提供将字节流转化为字符流读写方式的

仅有字符流InputStreamReader/OutputStreamWriter。其中,InputStreamReader需要与InputStream“套接”,OutputStreamWriter需要与OutputStream“套接”。(装饰者设计模式)

5、缓冲流

缓冲流:缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写效率,同时增加了一些新的方法。

  字节缓冲流有BufferedInputStream/BufferedOutputStream,字符缓冲流有BufferedReader/BufferedWriter,字符缓冲流分别提供了读取和写入一行的方法ReadLine和NewLine方法。

  对于输出地缓冲流,写出的数据,会先写入到内存中,再使用flush方法将内存中的数据刷到硬盘。所以,在使用字符缓冲流的时候,一定要先flush,然后再close,避免数据丢失。

6、内存流

在之前讲解FileInputStream 和 FileOutputStream 的时候所有的操作的目标是文件,那么如果现在假设有一些临时的信息要求通过IO操作的话,那么如果将这些临时的信息保存在文件之中则肯定很不合理,因为操作的最后还要把文件再删除掉,所以此时的IO中就提供了一个内存的操作流,通过内存操作流输入和输出的目标是内存。

使用ByteArrayOutputStream 和 ByteArrayInputStream 完成内存的操作流。其使用方法和InputStream 、OutputStream类似,一个个的读取数据。

 public static void main(String[] args) {        byte[] bytes = {0,0,1,2};        try (DataInputStream dis = new DataInputStream(new FileInputStream("aaa"));){            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int length;            byte[] temp = new  byte[1024];            while ((length = dis.read(temp)) != -1) {                baos.write(temp,0,length);            }            System.out.println(baos.toString("GBK"));        } catch (Exception e) {            e.printStackTrace();        }    }

7、控制台流

System.in System.out

8、常用的

1、还有一个关键字比较重要,transient,由于修饰实现了Serializable接口的类内的属性,被该修饰符修饰的属性,在以对象流的方式输出的时候,该字段会被忽略。

9、打印流:

  public static void main(String[] args) throws FileNotFoundException {          // TODO Auto-generated method stub          File file = new File ("D:"+File.separator+"demo.txt");          PrintStream output = new PrintStream(new FileOutputStream(file));          output.print("Hello");          output.print(" World");          output.println("abco");          output.println(1.0);          output.close();      }  

10、RandomAccessFile

RandomAccessFile它不属于IO流
只有RandomAccessFile才有seek方法,而这个方法也只适用于文件。
具体用法:

11、数据流DataInputStream

DataInputStream和DataOutputStream分别继承自InputStream和OutputStream,需要“套接”在InputStream和OutputStream类型的节点流之上。

它可以保证“无论数据来自何种机器,只要使用一个DataInputStream收取这些数据,就可用本机正确的格式保存它们.

简单案例:

对文件的简单读写:

 public static void main(String[] args) {        try(FileInputStream fos = new FileInputStream("res/test")) {            InputStreamReader isr = new InputStreamReader(fos);            BufferedReader br = new BufferedReader(isr);            PrintStream out = new PrintStream(System.out);            String str;            while ((str = br.readLine()) != null) {              out.println(str);            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

另附案例:阿拉伯数字转化为中文数字

package org.xiaohong.work;import java.io.*;public class Test02 {    public static void main(String[] args) {        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("res/test"), "UTF-8"));             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("res/trans.txt"), "UTF-8"))        ) {            String str;            int percent = 0;            while ((str = br.readLine()) != null) {                bw.write(trans_wan(Integer.parseInt(str)));                bw.newLine();                Thread.sleep(100);                percent++;                System.out.print("\r[");                for (int i = 0; i < 20; i++) {                    if (i < percent / 5) {                        System.out.print("=");                    } else if (i == percent / 5) {                        System.out.print(">");                    } else {                        System.out.print(" ");                    }                }                System.out.print("]");                System.out.printf("\t%.2f%%", (float) percent);            }        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    private static String trans_wan(int num) {        StringBuilder builder = new StringBuilder();        if (num / 10000 > 0) {            builder.append(trans(num / 10000)).append("万");        }        boolean flag = true;        if (num % 1000 > 0) {            String trans = trans(num % 10000);            // 判断前四位末尾是否是0            if (num / 10000 % 10 == 0) {                builder.append("零");                flag = false;            }            if (builder.length() > 0) {                // 判断后四位是否需要添加零                if (trans.indexOf("千") == 2 && flag) {                        builder.append("零");                }            }            builder.append(trans);        }        if (builder.length() == 0) {            builder.append("零");        }        return builder.toString();    }    private static String trans(int num) {        // 中文大写数字数组        String[] numeric = new String[]{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};        StringBuilder builder = new StringBuilder();        builder.append(numeric[num / 1000]).append("千")                .append(numeric[num / 100 % 10]).append("百")                .append(numeric[num / 10 % 10]).append("十")                .append(numeric[num % 10]);        int index = -1;        while ((index = builder.indexOf(numeric[0], index + 1)) != -1) {            if (index < builder.length() - 1) {                builder.deleteCharAt(index + 1);            }        }        index = 0;        while ((index = builder.indexOf("零零", index)) != -1) {            builder.deleteCharAt(index);        }        if (builder.length() > 1) {            if (builder.indexOf(numeric[0]) == 0) {                builder.deleteCharAt(0);            }            if (builder.lastIndexOf(numeric[0]) == builder.length() - 1) {                builder.deleteCharAt(builder.length() - 1);            }        }        if (builder.indexOf("一十") == 0) {            builder.deleteCharAt(0);        }        return builder.toString();    }}
1 0