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

    xiaoxiao2026-09-29  13

    学习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(); } }
    转载请注明原文地址: https://ju.6miu.com/read-1312462.html
    最新回复(0)