乐趣区

Java中的IO流IO-StreamCheryl

IO 流

在 java 中流可类比为一个个数据的序列,所以在流中常用 byte[]char[]用作传输数据的小车,推荐使用 4096(就是 4k 大小)作为传输一个流大小,当流的大小特别大时应使用 BufferedReader / BufferedWriter 做流的传输小车以提高效率,输入流表示从源读取数据(例如从硬盘文件读数据到内存中),输出流表示向一个目标写入数据(例如将内存中的数据写入到硬盘中)
IO 流又可分为 字节流 字符流

IO 流中的关系 - 图片来源菜鸟教程

字节流


字节流主要包括 FileInputStreamFileOutputStream

FileInputStream

下面演示 FileInputStream

package java0713.ioDemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * 演示字节流
 * @author Administrator
 *
 */
public class FileInputStreamDemo {public static void main(String[] args) {File file = new File("e:\\2.txt");
        
        // 连接文件源建立输入流
        // 这条语句也可用 InputStream is = new FileInputStream("FileAddress_StringPath")代替
        try(InputStream is = new FileInputStream(file);) {byte[] buffer = new byte[4096];
            int len = 0;
            StringBuilder sb = new StringBuilder();
//            // 错误示范,慎重使用 available
//            int size = is.available();
//            for (int i = 0; i < size; i++) {//                System.out.print((char)is.read());
//            }
            do {// InputStream 字节流公有方法 read()
                // 读取 buffer 个单位字节数据,返回单个流可读取最大长度,返回下一字节数据,结尾返回 -1,对 buffer 数组赋值
                len = is.read(buffer);
                if(len>0) {
                    // 为防止多出来的字节数组空间因未赋值而在转成字符串时变成空格,所以要限制它的长度为有效长度 len,当 len 为 - 1 时会报异常
                    sb.append(new String(buffer,0,len));
                } else {break;}
            } while(true);
            
//            // 错误示范代码,条件写里面会报错
//            do {//                len = is.read(buffer);
//                sb.append(new String(buffer,0,len));
//            } while(len>0);
            
            System.out.println(sb);
            
        } catch (FileNotFoundException e) {e.printStackTrace();
        } catch (IOException e) {e.printStackTrace();
        }

    }
}

在这里 is 流从源 file 指向 buffer(buffer 再流向至 sb)

FileOutputStream

FileOutputStreamFileInputStream 用法类似,但是用数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了 close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先 flush(),先清空数据。

package java0713.ioDemo;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 演示输出流
 * @author Administrator
 *
 */
public class FileOutputStreamDemo {public static void main(String[] args) {
        
        // 输出流连接目的地 target
        try(OutputStream os = new FileOutputStream("e:\\3.txt");) {for (int i = 0; i < 255; i++) {os.write((char)i);
                os.write('\r');
                os.write('\n');
            }
            // flush 方法,刷新缓冲区,强制写入
            os.flush();} catch (FileNotFoundException e) {e.printStackTrace();
        } catch (IOException e) {e.printStackTrace();
        }
        System.out.println("FileOutputSteam writes file successfully!");
    }
}

其它流则有对象流(如输入输出集合框架对象)和二进制流(如输入输出基础数据类型)
内存流可以用于在流中的类型转换

字符流


字符流包括 InputStreamReaderOutputStreamWriter
字节流一次 read 返回一个字节,而字符流正如名字所示,一次 read 返回一个字符,所以字符流非常擅长输入输出有中文文本的流,而且用字符流输入输出对选择用何种方式的编码也非常方便

package java0713.ioDemo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 演示字符流 Reader/Writer
 * @author Administrator
 *
 */
public class InputStreamReaderDemo {public static void main(String[] args) {try(InputStream fis = new FileInputStream("e:\\2.txt");) {InputStreamReader reader = new InputStreamReader(fis,"gbk");
            StringBuilder sb = new StringBuilder();
            
            while(reader.ready()) {// 字符流一次 read()读取一个字符即两个字节
                sb.append((char)reader.read());
            }
            System.out.println(sb);
        } catch (FileNotFoundException e) {e.printStackTrace();
        } catch (IOException e) {e.printStackTrace();
        }
    }
}

OutputStreamWriter 方法与输入流类似,不再赘述

退出移动版