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

学习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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值