IO框架和流学习笔记

I/O框架

I---input
O---output
流----流向划分:输入和输出
流---单元划分:字节流和字符流
字符流基于字节流
以Stream结尾的为字节流,以write或者Reader结尾的为字符流,所有的输出流都是抽象类IuputStream(字节流)或者抽象类Reader(字符输出流)的子类。所有的输出流都是抽象类OutputStream(字节输出流)或者抽象类OutputWriter(字符输出流)的子类。
字符流能实现的功能字节流都能实现,反正不一定。比如图片、视频等等二进制文件。
file类
//File类提供了用于操作文件和获取文件信息的一些列方法
File file = new File("A");
		file.mkdir(); // 创建一个文件夹 
		
		File files = new File("B/C/D");
		files.mkdirs();
		
		file.delete();
		files.delete(); // B 文件夹中有内容 不能删除 
        
        File file1 = new File("a.txt"); // 相对路径 相对于我们当前操作的目录而言的路径
		File file2 = new File("C:\\Users\\WHD\\Desktop\\test.txt"); // 绝对路径 具体的路径
		try {
			file1.createNewFile(); // 返回值 true表示创建成功  false表示创建失败
			file2.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("a.txt文件是否存在" + file1.exists());
		System.out.println("a.txt文件的相对路径" + file1.getPath());
		System.out.println("a.txt文件的绝对路径" + file1.getAbsolutePath());
		System.out.println("a.txt文件的大小" + file1.length());
		System.out.println("a.txt文件的名称" + file1.getName());
		System.out.println("a.txt是否是一个文件" + file1.isFile());
		System.out.println("a.txt是否是一个文件夹" + file1.isDirectory());
		System.out.println("是否删除成功" + file1.delete());
字节流
字节文件读取流
父类--abstract InputStream
字节读取流---FileInputStream

    raed()
        //每次读取一个字节返回值是读取内容的ascii码值
    read(byte[] datas)
        //可以读取指定数组长度的内容,返回值是每次读取的长度,读取的内容存放在数组中,可以使用String类构造方法来封装为字符串new String(byte[] b,int offset,int length);
    字节
        byte 8位 ASCII码
父类--
FileInputStream fis = null;
			try {
				fis = new FileInputStream("b.txt");
				int data = -1;
				while((data = fis.read()) != -1) {
					System.out.print((char)data);
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
	// 我们这时候会发现读取不了汉字,汉字是乱码,因为一个汉字是16字节的所以另辟蹊径
	//每次读取两个还是不行
		byte[] datas = new byte[2];
		FileInputStream file = null;
		try {
			file = new FileInputStream("b.txt");
			int data = -1;
			while ((data = file.read(datas)) != -1) {
				System.out.println(data);
				System.out.println(new String(datas, 0, data));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(file != null) {
				try {
					file.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
/*
		 * 定义一个长度较大的byte数组或者使用字节流FileInputStream的available()方法
		 */
		FileInputStream file = null;
		try {
			file = new FileInputStream("b.txt");
			//byte [] datas = new byte[100];
			byte [] datas = new byte[file.available()];
			int data = -1;
			while((data = file.read(datas)) != -1) {
				System.out.println(new String(datas, 0, data));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(file != null) {
				try {
					file.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
字节文件写入流
父类---abstract OutputStream
字节文件写入流---FileOutputStream
	void write();
		//每次写入一个字节
	void write(byte [] datas);
		//写入一个byte数组,可以使用String类的getBytes()方法将字符串转换为byte数组
	flush();
		//内容刷新到文件中
	close():
	//关闭资源
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("b.txt"); // 没有文件会创建一个
			fos.write(97);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(fos != null) {
					// 加上判断 因为如果fos对象为null  那么继续调用方法 将报 NullPointException 空指针
					fos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("c.txt", true);
			String str = "学java 到千锋 郑州千锋找帅栋 23564545";
			byte [] datas = str.getBytes();
			fos.write(datas);
			fos.flush(); // 将缓存中的内容刷新到文件
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
字符流
字符的文件读取流
父类---abstract Reader
FileReader---基于字符的文件读取流
	int read();
		//每次读取一个字符

	int read(char[] datas);
		//每次读取char数组长度的内容,返回值是读取的长度,读取的内容存放在数组中,可以直接打印
		try {
			FileReader fr = new FileReader("c.txt");
			int data = -1;
			while((data =fr.read()) != -1) {
				System.out.println((char)data);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		FileReader fr  = null;
		try {
			fr = new FileReader("c.txt");
			char [] datas = new char[100];
			int dataCount = -1;
			while((dataCount = fr.read(datas)) != -1) {
				System.out.println(dataCount);
				System.out.println(datas); 
				System.out.println(new String(datas, 0, dataCount));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
字符的文件读取缓冲流
BufferedReader---基于字符的文件读取缓冲流
	1).从字符输入流中读取文本,缓冲各个字符,实现字符、数组和行的高校读取。
	2).可以指定缓冲区的大小,或者使用默认的大小。大多数情况下默认就足够大。
	3).通常,Reader所做的每个读取请求都会导致对底层字符或者字节流进行相应的读取请求,建议BufferedReader包装所有其read()操作可能开销很高的Reader(如FileReader和InputStreamReader)
	例如	BufferedReader = new BufferedReader(new FileReader("a.txt"));
	4).将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
	FileReader fr = null;
		BufferedReader br = null;	
		try {
			fr = new FileReader("c.txt");
			br = new BufferedReader(fr);
			int data = -1;
			while((data = br.read()) != -1) {
				System.out.println((char)data);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}	
FileReader fr = null;
		BufferedReader br = null;
		try {
			fr = new FileReader("c.txt");
			br = new BufferedReader(fr);
			String line = null;
			while((line = br.readLine()) !=null) {
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
            //这里是关闭资源
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}	
			}
			if(br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}		
指定编码格式的字符读取流
InputStreamReader---可以指定编码格式的字符读取流
		FileInputStream fis;
		try {
			fis = new FileInputStream("C:\\Users\\WHD\\Desktop\\testCode.txt");
			InputStreamReader isr = new InputStreamReader(fis,"GBK");
			char []datas = new char[100];
			int dataCount = -1;
			while((dataCount  = isr.read(datas)) != -1) {
				System.out.println(datas);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			// 关闭资源
		}
字符的文件写入流
父类---abstract Writer
FileWriter---基于字符的文件写入流
    write();
    	//每次写入一个字符
    write(char [] datas);
    	//每次写入一个char数组	
    write(String str);
    	//每次写入一个字符串
FileWriter
	//字符写入流 一次写入一个字符 也可以写入char数组 或者一个String
	try {
			FileWriter fw = new FileWriter("d.txt", true);
			fw.write("hello nihao\n世界你好");
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//关闭资源
		}

字符的文件写入缓冲流
BufferedWriter---基于字符的文件写入缓冲流

    write();
    	//每次写入一个字符

    write(char [] datas);
    	//每次写入一个char数组

    newLine();//换行
	1).将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
	2).可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
	3).该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。
	4).通常 Writer 将其输出立即发送到底层字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,
 	PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
	5).缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的。
缓冲区的工作原理:1、使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。2、通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。3、如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。
FileWriter
	//字符写入流 一次写入一个字符 也可以写入char数组 或者一个String
	try {
			FileWriter fw = new FileWriter("d.txt", true);
			fw.write("hello nihao\n世界你好");
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//关闭资源
		}
指定编码格式的字符写入流
子类:OutputStreamWriter

write():每次写入一个字符

write(char [] datas):每次写入一个char数组

write(String str):每次写入一个字符串
		FileOutputStream fos;
		try {
			fos = new FileOutputStream("f.txt");
			OutputStreamWriter osw = new OutputStreamWriter(fos);
			osw.write("hello world");
			osw.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

数据流
数据流属于字节流,用于读取二进制文件,比如图片,音频,视频等等
DataInputStream		负责读取二进制文件
DataOutputStream	负责写入二进制文件

		FileInputStream fis;
		try {
			FileOutputStream fos = new FileOutputStream("copy.png");//这是写
			fis = new FileInputStream("C:\\Users\\18409\\Desktop\\zs.png");
			DataInputStream dps = new DataInputStream(fis);//这是读
			DataOutputStream dos = new DataOutputStream(fos);
			byte[] datas = new byte[fis.available()];
			int data = -1;
			while((data = dps.read(datas))!=-1) {
				dos.write(datas);
			}	
		} catch (FileNotFoundException e) {	
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//关闭资源
		}
		

对象流
对象流输入字节流,用于读取对象和写入对象
ObjectInputStream	对象读取流---序列化:讲对象以二进制的形式写入(存储)文件中
ObjectOutputStream	对象写入流---反序列化:将存有对象的文件读取出来生成对象
被序列化的对象必须实现Serializable接口
	此接口是空接口,相当于一个标识,实现此接口的了才能被序列化

		FileOutputStream fos;
		try {
			fos = new FileOutputStream("stu.txt");
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			Student stu1 = new Student("赵四", 20);
			Student stu2 = new Student("广坤", 22);
			Student stu3 = new Student("小宝", 19);
			oos.writeObject(stu1);//存对象
			oos.writeObject(stu2);
			oos.writeObject(stu3);
			FileInputStream fis = new FileInputStream("stu.txt");
			ObjectInputStream ois = new ObjectInputStream(fis);
			while(fis.available()>0) {				
					Student readStu1 = (Student) ois.readObject();
					System.out.println(readStu1);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {		
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

乱码
乱码出现的原因:
	编码的方式和解码的方式不一样
编码文件类型
	java文件编码
	html文件编码
	数据库文件编码
	js文件编码
	...
解决乱码的方式:
	统一编码
	可以将出现的乱码的内容打散(iso-8859-1)按照我们自己的编码方式组合
常见的编码格式:
	GBK国标扩展版	简体和繁体
	GB2312	国标版本	简体
	ISO-8859-1	最原始的编码方式,通常用于解决乱码
	UTF-8	unicode	万国吗	包含世界上大多数国家的语言编码
	ANSI 不具体制定某一编码,因为在不同的操作系统上,表示对应的编码 比如Win10中文版就是GBK

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值