【零】JavaIO

和自甴很熟 提交于 2020-01-14 01:52:20

一、IO原理及流的分类

  1. IO流用来处理设备之间的数据传输
  2. Java程序中,对于数据的输入/输出操作以”流(stream)” 的方式进行。是指从源节点到目标节点的数据流动
  3. 源节点和目标节点可以是文件、网络、内存、键盘、显示器等等。

1.1 原理

输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

1.2 流的分类

按操作数据单位不同:

字节流(8 bit)
字符流(16 bit)

按照数据流的流向:

输入流
输出流

二、文件流

2.1 步骤

读文件:

  1. 使用文件输入流打开指定文件:
    对于文本文件,应使用字符输入流FileReader流
    对于二进制文件,应使用字节输入流FileInputStream流
  2. 读取文件数据
  3. 关闭输入流

写文件:

  1. 使用文件输出流打开指定文件:
    对于文本文件,应使用字符输出流FileWriter流
    对于二进制文件,应使用字节输出流FileOutputStream流
  2. 将数据写入文件
  3. 关闭输出流

2.2 输入流

Reader(FileReader):

int read() // 读取一个字符
int read(char [] c) //一次性读多个字符到缓冲区数组
int read(char [] c, int off, int len)

InputStream(FileInputStream):

int read() //读取一个字节
int read(byte[] b) //一次性读多个字节到缓冲区数组
int read(byte[] b, int off, int len)

2.3 输出流

Writer:

void write(int b/int c);
void write(byte[] b/char[] cbuf);
void write(byte[] b/char[] buff, int offset, int length);
void flush();
void close(); 需要先刷新,再关闭此流

OutputStream

同上

2.4 示例

@Test
	public void test3() {
		// 1) 声明引用, 初始化为null
		FileReader fileReader = null;
		// 2) try catch finally 
		try {
			// 5) 创建流对象, 建立通道
			fileReader = new FileReader("一个文件");
			//char[] buf = new char[100];
			//int realCount = fileReader.read(buf); // 一次性读多个字符到数组中
			// 6) 处理数据 
			int ch = fileReader.read();
			while (ch != -1) {
				/*
				for (int i = 0; i < realCount; i++) { // 只处理实际读到的字符数.
					System.out.print(buf[i]);
				}
				// 2) 继续读后面的数据
				realCount = fileReader.read(buf);
				*/
				// 处理已经读的数据
				System.out.print((char)ch);
				// 继续读后面的字符, 直至-1为止
				ch = fileReader.read();
			}
		} catch (Exception e) {
			// 4) 处理异常, 打印栈踪迹
			e.printStackTrace();
		} finally {
			// 3) 关闭流
			if (fileReader != null) {
				try {
					fileReader.close();
				} catch (Exception e2) {
				}
			}
		}
		
	}

三、缓冲流

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组

3.1 按照数据操作单位

BufferedReader 和 BufferedWriter
BufferedInputStream 和 BufferedOutputStream

3.2 示例

@Test
	public void test3() {
		// 使用缓冲流(处理流)
		FileReader fileReader = null;
		BufferedReader bufferedReader = null;
		try {
			// 包装流, 使用对象关联, 包装流把节点流对象关联为属性.
			fileReader = new FileReader("HashMap.java");
			bufferedReader = new BufferedReader(fileReader);
			// 最有价值方法
			String line = bufferedReader.readLine(); // 读到的字符串没有换行
			int num = 1;
			while (line != null) {
				// 处理读到的行
				System.out.println(num++ + " " + line);
				// 继续读后面的行, 直到null
				line = bufferedReader.readLine();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 只需要关闭高级流, 因为低级流被关联, 并且会在关闭高级流时自动关闭
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (Exception e2) {
				}
			}
		}
	}

四、对象流

用于存储和读取对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

4.1 分类

ObjectInputStream
OjbectOutputSteam

4.2 序列化

  1. 序列化(Serialize):用ObjectOutputStream类将一个Java对象写入IO流中
  2. 反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
  3. 机制 : 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

4.3 示例

@Test
	public void serialize() {
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream oos = null;
		try {
			fos = new FileOutputStream("对象序列化");
			bos = new BufferedOutputStream(fos);
			oos = new ObjectOutputStream(bos);
			
			Student s1 = new Student(1, "小明", 3, 90);
			Student s2 = new Student(2, "小花", 1, 80);
			Student s3 = new Student(3, "小丽", 4, 20);
			
			s1.school = "atguigu";
			
			//oos.writeObject(s1);
			//oos.writeObject(s2);
			//oos.writeObject(s3);
			
			//Student[] arr = {s1, s2, s3};
			//oos.writeObject(arr);
			
			List<Student> list = new ArrayList<Student>();
			list.add(s1);
			list.add(s2);
			list.add(s3);
			oos.writeObject(list);
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (oos != null) {
				try {
					oos.close();
				} catch (Exception e2) {
				}
			}
		}
	}

五、数据流

DataInputStream(套接在InputStream)
DataOutputStream(套接在OutpuStream)

5.1 示例

DataOutputStream dos = null;
	try {	//创建连接到指定文件的数据输出流对象
		dos = new DataOutputStream(new FileOutputStream(
					"d:\\IOTest\\destData.dat"));
			dos.writeUTF("ab中国");  //写UTF字符串
			dos.writeBoolean(false);  //写入布尔值
			dos.writeLong(1234567890L);  //写入长整数
			System.out.println("写文件成功!");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {	//关闭流对象
			try {
			if (dos != null) {
			// 关闭过滤流时,会自动关闭它包装的底层节点流
			dos.close(); 
			}
		} catch (IOException e) {
			e.printStackTrace();
		}	}

六、转换流

InputStreamReader:

用于将字节流中读取到的字节按指定字符集解码成字符。需要和InputStream“套接”。
构造方法:
------public InputStreamReader(InputStream in)
------public InputSreamReader(InputStream in,String charsetName)

OutputStreamWriter:

用于将要写入到字节流中的字符按指定字符集编码成字节。需要和OutputStream“套接”
构造方法:
------public OutputStreamWriter(OutputStream out)
------public OutputSreamWriter(OutputStream out,String charsetName)

在这里插入图片描述

6.1 示例

public void testMyInput() throws Exception{
    FileInputStream fis = new FileInputStream("dbcp.txt");
    FileOutputStream fos = new FileOutputStream("dbcp5.txt");

    InputStreamReader isr = new InputStreamReader(fis,"GBK");
    OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");

    BufferedReader br = new BufferedReader(isr);
    BufferedWriter bw = new BufferedWriter(osw);

    String str = null;
    while((str = br.readLine()) != null){
        bw.write(str);
        bw.newLine();
        bw.flush();
}    bw.close();  br.close();}

七、输入/输出流

System.in
System.out

7.1 示例

// 从键盘输入一些内容, 把内容保存成UTF8格式的文本文件content.txt
	// 直到键盘输入over命令, 或ctrl+z 
	@Test
	public void test13() {
		InputStream is = System.in; // 以键盘为数据源
		InputStreamReader isr = null;
		BufferedReader bufferedReader = null;
		try {
			isr = new InputStreamReader(is);
			bufferedReader = new BufferedReader(isr);
			String line = bufferedReader.readLine();
			while (line != null) {
				// 1) 处理数据 
				if (line.equals("exit")) {
					break;
				}
				System.out.println(line);
				// 2) 继续读
				line = bufferedReader.readLine(); // ctrl+z 提醒流数据已经结束
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (Exception e2) {
				}
			}
		}
	}

八、打印流

PrintStream(字节打印流)
PrintWriter(字符打印流)

8.1 特点

  1. PrintStream和PrintWriter的输出不会抛出异常
  2. PrintStream和PrintWriter有自动flush功能
  3. System.out返回的是PrintStream的实例

8.2 示例

FileOutputStream fos = null;
	try {
		fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}//创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
	PrintStream ps = new PrintStream(fos,true);
	if (ps != null) {	// 把标准输出流(控制台输出)改成文件
		System.setOut(ps);}
	for (int i = 0; i <= 255; i++) {  //输出ASCII字符
		System.out.print((char)i);
		if (i % 50 == 0) {   //每50个数据一行
			System.out.println(); // 换行
		}  }
	ps.close();

九、File类

public class FileTest {

	public static void main(String[] args) {
		// 使用File对象 模拟dir命令
		File file = new File("C:\\Windows");
		
		File[] listFiles = file.listFiles(); // 列出目录下的所有子文件和子目录
		
		for (int i = 0; i < listFiles.length; i++) {
			
			SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			String dateTime = df.format(new Date(listFiles[i].lastModified()));
			
			if(listFiles[i].isDirectory()) {
				System.out.println(dateTime + "\tDIR\t\t" + listFiles[i].getName());
			}else {
				System.out.println(dateTime + "\t\t" + listFiles[i].length() + "\t" + listFiles[i].getName());
			}
			
		}
	}
	
}

十、小结

字节流-缓冲流(重点):

输入流InputStream-FileInputStream-BufferedInputStream
输出流OutputStream-FileOutputStream-BufferedOutputStream

字符流-缓冲流(重点):

输入流Reader-FileReader-BufferedReader
输出流Writer-FileWriter-BufferedWriter-PrintWriter

转换流:

InputSteamReader和OutputStreamWriter

对象流:

ObjectInputStream和ObjectOutputStream(重点)

在这里插入图片描述

十一、Life

最难熬的状态就是,眼里操心着不再年轻的父母,脑子里想着乱七八糟的事业,心里还藏着一个不可能的姑娘,胸膛里还撑起着一个遥远的远方,像我们这种恶人,怎说得了动听得话

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!