java IO流

IO流

1、什么是IO流?
通过IO流可以完成硬盘文件的读和写
在这里插入图片描述

2、IO流的分类?

  • (1)、按照流的方向进行分类:

     	【以内存作为参照物】
     	往内存中去,叫做输入。或者叫做读。
     	从内存中出来,叫做输出。或者叫做写。
    
  • (2)、按读取数据方式不同进行分类:

  1. 字节流:

    按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位,这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频等。
    假设文件file。TXT,采用字节流的方式:
    a中国bc张三f
    第一次读:一个字节,正好读到‘a’
    第二次读:一个字节,正好读到‘中’字符的一半
    第三次读:一个字节,正好读到‘中’字符的另一半。

  2. 字符流:

    按照字符的方式读取数据,一次读取一个字符,这种流是为了方便读取普通文本而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连Word文件都无法读取
    假设文件file。TXT,采用字节流的方式:
    a中国bc张三fe
    第一次读:‘a’字符(‘a’字符在Windows系统中占用1个字节)
    第二次读:‘中’字符(‘中’字符在Windows系统中占用2个字节)

综上所述:流的分类:

  		输入流、输出流
  		字节流、字符流

3、java中的IO流都已经写好,程序员不需要关心,最主要的还是掌握,在java中已经提供了哪些流,每个流的特点是什么?每个流对象上的常用方法有哪些?

java中所有的流都是在java.io.*;下
java中主要研究:
	怎么new对象
	调用流对象的哪个方法是读,哪个方法是写。

4、java IO流有四大家族:
四大家族首领:【都是抽象类】

java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流

java.io.Reader 字符输入流
java.io.Writer 字符输出流

注意:在java中只要“类名”以Stream结尾的都是字节流,以“Reader/Writer”结尾的都是字符流。

**所有的流都实现了:
	java.io.Closeable接口,都是可关闭的,都有close方法**。
		流是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
		不然会耗费(占用)很多资源。一定养成用完流就关闭的习惯。

*所有的输出流都实现了:
	java.io.Flushable接口,都是可刷新的,都有flush()方法。
	养成这样一个习惯:
	输出流在最终输出之后,一定要记得flush()方法刷新一下,这个刷新表示
	将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是
	清空管道。

注意:如果没有flush可能会导致数据丢失。

5、java.io包下需要掌握的流有16个:

  • 文件专属:

     java.io.FileInputStream
     java.io.FileOutputStream
     java.io.FileReader
     java.io.FileWriter
    
  • 转换流:(将字节流转换成字符流)

     java.io.InputStreamReader
     java.io.OutputStreamWriter
    
  • 缓冲流专属:

     java.io.BufferedReader
     java.io.BufferedWriter
     java.io.BufferedInputStream
     java.io.BufferedOutputStream
    
  • 数据流专属:

     java.io.DataInputStream
     java.io.DataOutputStream
    
  • 标准输出流:

     java.io.PrintWriter
     java.io.PrintStream
    
  • 对象专属流:

     java.io.ObjectInputStream
     java.io.ObjectOutputStream
    

(1).FileInputStream

package javaCoreTest;

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

/*
 * java.io.FileInputStream
 * 	1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
 * 2.字节的方式,完成输入的操作,完成读的操作(硬盘-->内存)
 */

public class FileInputStreamTest01 {

	public static void main(String [] args) {
		FileInputStream fis = null;
		
		try {
			//创建文件字节输入流对象
			//文件路径:D:\Java核心技术\java核心技术\src\javaCoreTest\Wim(IDE会自动把\变成\\,因为java中\表示转义)
			//以下都是采用了绝对路径的方式。
			FileInputStream fis1 = new FileInputStream("D:\\Java核心技术\\java核心技术\\src\\javaCoreTest\\Wim.txt");
			//写成/也是可以的
			//fis = new FileInputStream("D:/Java核心技术/java核心技术\\src/javaCoreTest/Wim.txt");
			
			//开始读
			int readData = fis1.read();//这个方法返回值是:读取到的“字节”本身
			System.out.println(readData);//97
			
			readData = fis1.read();
			System.out.println(readData);//98
			
			readData = fis1.read();
			System.out.println(readData);//99
			
			readData = fis1.read();
			System.out.println(readData);//100
			
			readData = fis1.read();
			System.out.println(readData);//101
			
			readData = fis1.read();
			System.out.println(readData);//102
			
			//已经读到文件的末尾,再读的时候读取不到任何数据,返回-1
			readData = fis1.read();
			System.out.println(readData);//-1
			
			readData = fis1.read();
			System.out.println(readData);//-1
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//在finally语句块中确保流一定关闭
			if(fis != null) {
				//关闭流的前提是:流不是空,流是null的时候没必要关闭。
				try {
					fis.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
	}
}
package javaCoreTest;

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

/*
 * 对第一个程序进行改进。循环方式
 * 
 * 缺点:
 * 	一次只能读取一个字节,内存和硬盘之间交互频繁
 */

public class FileInputStreamTest02 {
	
	public static void main(String [] args) {
		FileInputStream fis = null;
		
		try {
			fis = new FileInputStream("D:/Java核心技术/java核心技术\\src/javaCoreTest/Wim.txt");
			
			/*while(true) {
				int readData = fis.read();
				
				if(readData == -1) {
					break;
				}
				
				System.out.println(readData);
			}*/
			
			//改造while循环
			int readData = 0;
			while((readData = fis.read()) != -1 ) {
				System.out.println(readData);
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}
package javaCoreTest;

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

/*
 * int read(byte [] b) 	这个方法返回的是读取到的字节数量(不是字节本身)
 * 一次最多读取b.length个字节
 * 减少硬盘和内存的交互,提高程序的执行效率
 * 往byte[]数组当中读
 */

public class FileInputStreamTest03 {

	public static void main(String [] args) {
		FileInputStream fis = null;
		
		try {
			//相对路径:从当前所在的位置作为起点开始找(不用加文件后缀)
			//IDE默认的当前路径是:工程的根(与src同一地位)
			//fis = new FileInputStream("D:/Java核心技术/java核心技术\\src/javaCoreTest/Wim.txt");
			fis = new FileInputStream("tsv");//tsv为一个文件,里面的内容为abcdef
			
			//开始读,采用byte数组,一次读取多个字节,最多读取“数组.length"个字节
			byte[] bytes = new byte[4];
			
			int readCount = fis.read(bytes);//第一次读到了四个字节
			System.out.println(readCount);//4
			//将字节数组全部转换成字符串
			//System.out.println(new String(bytes));//abcd
			//但是不应该全部转换,应该是取了多少个字节就转换多少个
			System.out.println(new String(bytes, 0, readCount));//abcd
			
			readCount = fis.read(bytes);//第二次只能读取到两个字节
			System.out.println(readCount);//2
			System.out.println(new String(bytes, 0, readCount));//ef
			
			readCount = fis.read(bytes);//一个字节都没有读取到返回-1
			System.out.println(readCount);//-1
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
package javaCoreTest;

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

/*
 * 继续改进以上程序
 */

public class FileInputStreamTest04 {

	public static void main(String [] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("tsv");//tsv为一个文件,里面的内容为abcdef
			
			//准备一个byte数组
			byte[] bytes = new byte[4];
			
			/*while(true) {
				int readCount = fis.read(bytes);
				if(readCount == -1) {
					break;
				}
				System.out.print(new String(bytes, 0, readCount));
			}*/
			
			//循环改进版
			int readCount = 0;
			while((readCount = fis.read(bytes)) != -1) {
				System.out.print(new String(bytes, 0, readCount));
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
package javaCoreTest;

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

/*
 * FileInputStream类的其他常用方法:
 * 		int available():返回流当中剩余的没有读到的字节数量
 * 		long skip(long n):跳过几个字节不读。
 */

public class FileInputStreamTest05 {

	public static void main(String [] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("tsv");//tsv为一个文件,里面的内容为abcdef
			
			//1、int available():返回流当中剩余的没有读到的字节数量
			
			/*int readCount = fis.read();
			//读出还剩下的字节数量
			System.out.println("剩下多少个字节没有读:" + fis.available());*/
			
			//byte [] bytes = new byte[fis.available()];//这种读的方式不适合太大的文件,因为byte数组不能太大
			//int readCount = fis.read(bytes);
			//System.out.println(new String(bytes));
			
			//2、long skip(long n):跳过几个字节不读。
			fis.skip(3);
			System.out.println(fis.read());//100
			
 		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(2)、FileOutputStream

package javaCoreTest;

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

/*
 * 写
 * 从内存 --> 硬盘
 */

public class FileOutputStreamTest01 {

	public static void main(String [] args) {
		FileOutputStream fos = null;
		try {
			//这种方法谨慎使用!因为他会先将源文件清空然后重新写入
			//可以以追加的方式在文件末尾写入,不会清空原文件内容
			//当文件不存在的时候回自动新建
			//fos = new FileOutputStream("tsv");
			fos = new FileOutputStream("tsv", true);
			
			//开始写
			byte [] bytes = {97, 98, 99};
			//将byte数组全部写出
			fos.write(bytes);
			
			//将数组的一部分写出
			fos.write(bytes, 0, 2);
			
			//字符串
			String s = "I am a Chinese.";
			//将一个字符串转换成一个byte数组
			byte[] by = s.getBytes();
			//写入
			fos.write(by);
			
			//写完之后一定要刷新
			fos.flush();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(3)、FileReader

package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * FileReader:
 * 		文件字符输入流,只能读取普通文本
 * 		读取文本内容时,比较方便快捷。
 */

public class FileReaderTest01 {

	public static void main(String [] args) {
		FileReader reader = null;
		try {
			//创建文件字符输入流
			reader = new FileReader("tsv");
			//开始读
			char [] chars = new char[4];
			int readCount = 0;
			while((readCount = reader.read(chars)) != -1) {
				System.out.print(new String(chars, 0, readCount));
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(4)、FileWriter

package javaCoreTest;

import java.io.FileWriter;
import java.io.IOException;

/*
 * FileWriter:
 * 		文件字符输出流,写
 * 		只能输出普通文本
 */

public class FileWriterTest01 {

	public static void main(String [] args) {
		FileWriter out = null;
		try {
			//这种会使文件先清空,然后重写
			//out = new FileWriter("tsv");
			
			//这种写法不会是文件清空
			out = new FileWriter("tsv", true);
			
			char[] chars = {'l', 'o', 'v', 'e'};
			out.write(chars);
			
			//换行
			out.write("\n");
			out.write(chars, 0, 2);
			
			//刷新
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(5)、BufferedReader

package javaCoreTest;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * BufferedReader:
 * 		带有缓冲区的字符输入流
 * 		使用这个流的时候不需要自定义char 数组,或者说不需要自定义byte数组,自带缓冲
 */

public class BufferedReaderTest01 {

	public static void main(String [] args) throws IOException {
		
		FileReader reader = new FileReader("tsv");
		//当一个构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
		//外部负责包装的这个流叫做:包装流,还有一个名字叫做:处理流。
		//像当前这个程序来说:FileReader就是一个节点流,BufferedReader就是处理流/包装流
		BufferedReader br = new BufferedReader(reader);
		
		//readLine()  读一行
		//读取一个文本行,但不带换行符
		/*String line1 = br.readLine();
		System.out.println(line1);
		
		String line2 = br.readLine();
		System.out.println(line2);*/
		
		String s = null;
		while((s = br.readLine()) != null) {
			System.out.println(s);
		}
		//关闭流
		//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭(看源代码可以得出)
		br.close();
	}
}
package javaCoreTest;

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

/*
 * 字节流转换为字符流
 */

public class BufferedReaderTest02 {

	public static void main(String [] args) throws IOException {
		
		/*//字节流
		FileInputStream in = new FileInputStream("tsv");
		
		//通过转换流转换【InputStreamReader将字节流转换成字符流】
		//在此处in是节点流,reader是包装流
		InputStreamReader reader = new InputStreamReader(in);
		
		//这个构造方法只能传一个字符流,不能传字节流
		//reader是节点流,br是包装流
		BufferedReader br = new BufferedReader(reader);*/
		
		//合并
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("tsv")));
		
		String s = null;
		while((s = br.readLine()) != null) {
			System.out.println(s);
		}
	}
}

(6)、BufferedWriter

package javaCoreTest;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/*
 * BufferedWriter:带有缓冲的字符输出流
 */

public class BufferedWriterTest01 {

	public static void main(String [] args) throws IOException {
		//带有缓冲区的字符输出流
		//BufferedWriter out = new BufferedWriter(new FileWriter("tsv"));
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("tsv", true)));
		
		//开始写
		out.write("hello");
		out.write("\n");
		out.write("money");
		
		//刷新
		out.flush();
		
		//关闭最外层
		out.close();
	}
}

(7)、DataOutputStream

package javaCoreTest;

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

/*
 * java.io.DataOutputStream:数据专属的流
 * 		这个流可以将数据连同数据的类型一并写入文件。
 * 		注意:这个文件不是普通文本文档。(这个文件用记事本打不开)
 */

public class DataOutputStreamTest01 {

	public static void main(String [] args) {
		
		//创建数据专属的字节输出流
		DataOutputStream data = null;
		try {
			data = new DataOutputStream(new FileOutputStream("tsv"));
			
			//写数据
			byte b = 100;
			short s = 12;
			int i = 13;
			long l = 78L;
			float f = 3.14f;
			double d = 6.28;
			boolean bb = true;
			char c = 'a';
			
			//写入
			data.writeByte(b);//把数据以及数据的类型一并写入文件中
			data.writeShort(s);
			data.writeInt(i);
			data.writeLong(l);
			data.writeFloat(f);
			data.writeDouble(d);
			data.writeBoolean(bb);
			data.writeChar(c);
			
			//刷新
			data.flush();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(data != null) {
				try {
					data.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(8)、DataInputStream

package javaCoreTest;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * DataInputStream:数据字节输入流
 * DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候需要提前知道写入的顺序,
 * 读的顺序需要和写的顺序一致,才可以正常取出数据。
 */

public class DataInputStreamTest01 {

	public static void main(String [] args) {
		DataInputStream data = null;
	
		try {
			 data = new DataInputStream(new FileInputStream("tsv"));
			 
			 //开始读
			byte b = data.readByte();
			short s = data.readShort();
			int i = data.readInt();
			long l = data.readLong();
			float f = data.readFloat();
			double d = data.readDouble();
			boolean bb = data.readBoolean();
			char c = data.readChar();
			
			System.out.println(b);
			System.out.println(s);
			System.out.println(i);
			System.out.println(l);
			System.out.println(f);
			System.out.println(d);
			System.out.println(bb);
			System.out.println(c);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(data != null) {
				try {
					data.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

(9)、PrintStream

package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.PrintStream;

/*
 * java.io.PrintStream:标准的字节输出流。默认输出到控制台。
 */

public class PrintStreamTest01 {

	public static void main(String [] args) throws FileNotFoundException {
		
		//联合起来写
		System.out.println("hello world");
		
		//分开写
		PrintStream ps = System.out;
		ps.println("hello zhangsan");
		ps.println("hello lisi");
		ps.println("hello wangwu");
		
		//标准输出流不需要手动close()关闭
		
		//标准输出流不再指向控制台,指向tsv文件
		PrintStream print = new PrintStream("tsv");
		
		//修改输出方向,将输出方向修改到tsv文件
		System.setOut(print);
		//再输出
		System.out.println("hello world");
		System.out.println("hello king");
		System.out.println("hello wangtiechui");
	}
}

6.java.io.File类
常用方法

package javaCoreTest;

import java.io.File;
import java.io.IOException;

/*
 * File
 * 		1、File类和四大家族没有关系,所以File类不能完成文件的读和写
 * 		2、File对象代表什么?
 * 			文件和目录路径名的抽象表示形式
 * 			一个File对象有可能对应的是目录,也有可能是文件。
 * 		3、需要掌握File类中常用的方法
 */

public class FileTest01 {

	public static void main(String [] args) {
		//创建一个File对象
		File f1 = new File("E:\\file");
		
		//1、boolean exists();判断文件是否存在
		System.out.println(f1.exists());//false
		
		//如果不存在,则以文件的形式创建出来
		/*if(!f1.exists()) {
			//2、createNewFile()	以文件的形式新建
			try {
				f1.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}*/
		
		//如果不存在,以目录的形式创建出来
		/*if(!f1.exists()) {
		 
		 //3、mkdir()	以目录的形式新建
			f1.mkdir();
		}*/
		
		//创建多重目录
		File f2 = new File("E:\\file\\a\\ba\\c\\d");
		
		if(!f2.exists()) {
			//4、mkdirs()	创建多重目录
			f2.mkdirs();
		}
		
		File f3 = new File("E:\\计算机组成原理\\file");
		
		//5、String getParent()	获取文件的父路径,返回类型为String
		String parentPath = f3.getParent();
		System.out.println(parentPath);//E:\计算机组成原理
		
		//6、File getParentFile()	获取文件的父路径,返回类型为File
		File parentFile = f3.getParentFile();
		System.out.println(parentFile);
		
		//7、File getAbsoluteFile()	获取文件的绝对路径
		File f4 = new File("tsv");
		File abso = f4.getAbsoluteFile();
		System.out.println(abso);
		
		//8、String getAbsolutePath()	获取文件的绝对路径
		String s = f4.getAbsolutePath();
		System.out.println(s);
	}
}
package javaCoreTest;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * File类的常用方法
 */

public class FileTest02 {

	public static void main(String [] args) {
		File f1 = new File("E:\\计算机组成原理\\file");
		
		//1、String getName()		获取文件名
		System.out.println(f1.getName());//file
		
		//2、boolean isDirectory() 	判断是否是一个目录
		System.out.println(f1.isDirectory());//false
		
		//3、boolean isFile()		判断是否是一个文件
		System.out.println(f1.isFile());//false
		
		//4、long lastModified()		获取文件最后一次修改时间
		long haoMiao = f1.lastModified();//这个毫秒是从1970年到现在的总毫秒数
		//将总毫秒数转换成日期
		Date time = new Date(haoMiao);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss SSS");
		String s = sdf.format(time);
		System.out.println(s);
		
		//5、long length()	获取文件大小
		System.out.println(f1.length());
		
		//6、File[] listFiles()	获取当前目录下所有的子文件
		File f = new File("E:\\计算机组成原理");
		File [] files = f.listFiles();
		for(File file : files) {
			System.out.println(file.getAbsolutePath());
		}
	}
}

7.序列化 反序列化在这里插入图片描述
(1)和(2)的例1和例2读写相互对应

(1)、序列化【ObjectOutputStream】

package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/*
 * ObjectOutputStream:
 * 
 * 1、参与序列化和反序列化的对象,必须实现Serializable接口
 * 
 * 2、注意:通过源代码发现,Serializable接口只是一个标志接口:
 * 		public interface Serializable{
 * 		}
 * 		这个接口当中什么代码都没有。
 * 		那么它起到一个什么作用?
 * 			起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。
 * 			Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类生成一个序列化版本号。
 * 
 * 3、若源代码改动后,重新编译之后生成了全新的字节码文件,并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变
 * 
 * 4、序列化版本号有什么用?
 * 		java中采用什么机制来区分类的?
 * 			第一:首先通过类名进行比对,如果类名不一样,肯定不是同一个类
 * 			第二:如果类名一样,靠序列化版本号进行区分。
 * 
 * 5、这种自动生成的序列化版本号有什么缺点?
 * 		一旦代码确定后,不能进行后续的修改,因为只要修改,必然会重新编译,
 * 		此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。
 * 
 */

public class ObjectOutputStreamTest01 {

	public static void main(String [] args) {
		
		//序列化
		ObjectOutputStream oos = null;
		try {
			//创建java对象
			Student01 s = new Student01(111, "zhangsan");
			oos = new ObjectOutputStream(new FileOutputStream("tsv"));
			
			//序列化对象
			oos.writeObject(s);
			
			//刷新
			oos.flush();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(oos!= null) {
				try {
					oos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}

class Student01 implements Serializable{
	
	//java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号。
	//这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。
	//建议将序列化版本号手动的写出来,不建议自动生成。
	private static final long serialVersionUID = 8683452581122892189L;
	int no;
	String name;
	
	public Student01() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student01(int no, String name) {
		super();
		this.no = no;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student01 [no=" + no + ", name=" + name + "]";
	}
	
	
}
package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/*
 * 一次可以序列化多个对象,可以将对象放到集合当中,序列化集合
 * 提示:
 * 	参与序列化的ArrayList集合以及集合中的元素User都需要实现java.io.Serializable接口
 */

public class ObjectOutputStreamTest02 {

	public static void main(String [] args) throws FileNotFoundException, Exception {
		
		List<UserPerson> userList = new ArrayList<>();
		
		userList.add(new UserPerson(2, "lidi"));
		userList.add(new UserPerson(3, "wangwu"));
		userList.add(new UserPerson(4, "zhaoliu"));
		
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tsv"));

		
		oos.writeObject(userList);
		
		oos.flush();
		oos.close();
	}
}

class UserPerson implements Serializable{
	int no;
	//transient关键字表示游离,不参与序列化
	transient String name;//name不参与序列化操作!
	
	public UserPerson(int no, String name) {
		this.no = no;
		this.name = name;
	}

	public UserPerson() {

	}

	public String toString() {
		return "User [no=" + no + ", name=" + name + "]";
	}
	
}

(2)、反序列化【ObjectInputStream】

package javaCoreTest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

/*
 * 反序列化
 */

public class ObjectInputStreamTest01  {

	public static void main(String [] args) {
		
		ObjectInputStream ois = null;
		
		try {
			ois = new ObjectInputStream(new FileInputStream("tsv"));
			
			//开始反序列化,读
			System.out.println(ois.readObject());
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(ois != null) {
				try {
					ois.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
package javaCoreTest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.List;

/*
 * 反序列化集合
 */

public class ObjectInputStreamTest02 {

	public static void main(String [] args) {
		
		ObjectInputStream ois = null;
		
		try {
			ois = new ObjectInputStream(new FileInputStream("tsv"));
			
			Object obj = ois.readObject();
			//System.out.println(obj instanceof List);
			
			List<UserPerson> uList = (List<UserPerson>)ois.readObject();
			
			for(UserPerson user : uList) {
				System.out.println(user);
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				ois.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

8、IO和Properties联合使用
IO流:文件的读和写
Properties:是一个Map集合,key和value都是String类型

package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Properties;

/*
 * IO + Properties的联合使用
 * 		设计理念:
 * 			以后经常改变的数据,可以单独写到一个文件中,使用程序动态读取。
 * 			将来只需要修改这个文件的内容,java代码不需要改动,不需要重新
 * 			编译,服务器也不需要重启,就可以拿到动态的信息。
 * 
 * 	类似于以上机制的这种文件被称为配置文件。
 * 	并且当配置文件中的内容格式是:
 * 		key1 = value
 * 		key2 = value
 * 	的时候,把这种配置文件叫做属性配置文件。
 * 
 * 属性配置文件中key重复的话,value会自动覆盖
 * 
 * java规范中有要求:属性配置文件建议以.properties结尾,但这不是必须的
 */

public class IoPropertiesTest01 {

	public static void main(String [] args) throws Exception {
		/*
		 * Properties是一个Map集合,key和value都是String类型
		 * 想将userinfo文件中的数据加载到Properties对象当中
		 */
		
		//新建一个输入流对象
		FileReader reader = new FileReader("src/javaCoreTest/userinfo.properties");
		
		//新建一个Map集合
		Properties pro = new Properties();
		
		//调用Properties对象的load方法将文件中的数据加载到Map集合中
		pro.load(reader);//文件中的数据顺着管道加载到Map集合中,其中等号左边是key,右边是value
		
		//通过key来获取value
		String username = pro.getProperty("username");
		System.out.println(username);
		
		String password = pro.getProperty("password");
		System.out.println(password);
	}
}

9.文件拷贝
(1)、使用FileInputStream + FileOutputStream完成文件的拷贝

package javaCoreTest;

import java.io.*;

/*
 * 文件复制:
 * 	使用FileInputStream + FileOutputStream完成文件的拷贝
 * 	拷贝的过程应该是一边读,一边写。
 * 	使用以上字节流拷贝文件的时候,文件类型随意,什么样的文件都能拷贝。
 */

public class CopyTest01 {

	public static void main(String [] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			//创建一个输入流对象
			fis = new FileInputStream("tsv");
			//创建一个输出流对象
			fos = new FileOutputStream("D:\\搜狗高速下载\\zzbm_sqb_06191830\\sunqi\\新建文本文档.txt");
			
			//最核心:一边读,一边写
			byte[] bytes = new byte[1024 * 1024];
			int readCount = 0;
			while((readCount = fis.read(bytes)) != -1) {
				fos.write(bytes, 0, readCount);
			}
			
			
			//刷新
			fos.flush();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if( fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		
	}
}

(2)、使用FileReader + FileWriter进行拷贝

package javaCoreTest;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 使用FileReader + FileWriter进行拷贝,只能拷贝普通文件
 */

public class CopyTest02 {

	public static void main(String [] args) {
		FileReader in = null;
		FileWriter out = null;
		
		try {
			//读
			in = new FileReader("tsv");
			//写
			out = new FileWriter("D:\\Java核心技术\\java核心技术\\课堂笔记(test).txt");
			
			char[] chars = new char[1024 * 512];
			
			int readerCount = 0;
			while((readerCount = in.read(chars)) != -1) {
				out.write(chars, 0, readerCount);
			}
			
			//刷新
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			if(out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

10.记录日志

package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * 记录日志的方法
 */

public class Logger {

	public static void log(String msg) {
		try {
			//指向一个日志文件
			PrintStream ps = new PrintStream(new FileOutputStream("tsv", true));
			
			//改变输出方向
			System.setOut(ps);
			
			//日期当前时间
			Date nowTime = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss SSS");
			String strTime = sdf.format(nowTime);
			
			System.out.println(strTime + ":" + msg);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

public class LogTest {

	public static void main(String [] args) {
		Logger.log("用户尝试进行登录,验证失败!");
		Logger.log("调用了UserService的doSome方法");
	}
}

11、文件路径

package javaCoreTest;

/*
 * 关于文件路径
 * 	怎么获取一个文件的绝对路径,以下的这种方式是通用的,但前提是:文件需要在类路径下,才能用这种方式
 */

public class AboutPath {

	public static void main(String [] args) {
		
		//使用以下方式的前提是:这个文件必须在类路径下
		//什么是类路径下?
		//在src下的都是类路径下
		//src是类的根路径
		
		/*
		 *解释:
		 *	 Thread.currentThread()当前线程对象
		 *	 getContextClassLoader()是线程对象的方法,可以获取到当前线程的类加载对象
		 *	 getResource()【获取资源】这是类加载器对象的方法,当前线程的类加载器默认从类的根路径下加载资源。
		 */
		
		String pathString = Thread.currentThread().getContextClassLoader()
				.getResource("txt").getPath();
		
		//采用以上的代码可以拿到一个文件的绝对路径
		System.out.println(pathString);
		
		//从scr目录的下一个开始写,要带文件后缀(从类的根路径下作为起点开始)
		String pathString2 = Thread.currentThread().getContextClassLoader()
				.getResource("javaCoreTest/Wim.txt").getPath();
		System.out.println(pathString2);
	}
}
package javaCoreTest;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.util.Properties;

public class IoPropertiesTest {

	public static void main(String [] args) throws Exception {
		//获取一个文件的绝对路径
		/*
		 * String pathString = Thread.currentThread().getContextClassLoader()
		 * .getResource("txt.txt").getPath();
		 * 
		 * FileReader reader = new FileReader(pathString);
		 */
		
		//直接以流的形式返回
		InputStream reader = Thread.currentThread()
				.getContextClassLoader().getResourceAsStream("txt.txt");
		
		Properties properties = new Properties();
		properties.load(reader);
		reader.close();
		//通过key获取value
		String classNameString = properties.getProperty("className");
		System.out.println(classNameString);
	}
}
package javaCoreTest;

import java.util.ResourceBundle;

//资源绑定器
/*
 * java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。
 * 使用以下这种方法的时候,属性配置文件xxx.properties必须放到类路径下
 */

public class ResourceBundleTest {

	public static void main(String [] args) {
		//资源绑定器,只能绑定xxx.properties文件,并且这个文件必须在类路径下,文件扩展名也必须是properties
		//并且在写路径的时候,路径后面的扩展名不能写
		ResourceBundle bundle = ResourceBundle.getBundle("classinfo2");
		
		ResourceBundle bundle2 = ResourceBundle.getBundle("javaCoreTest/userinfo");
		
		String classNameString2 = bundle.getString("password");
		System.out.println(classNameString2);
		
		String classNameString = bundle.getString("classname");
		System.out.println(classNameString);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值