黑马程序员——IO流——IO转换流,打印流,序列化流,properties以及其他流

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1.转换流



A:转换流OutputStreamWriter:
字符流通向字节流的桥梁。
OutputStreamWriter是Writer的子类,是FileWriter的父类,是字符流的一种。

B:转换流InputStreamReader:
字节流通向字符流的桥梁。
InputStreamReader是Reader的子类,是FileReader的父类,是字符流的一种。

注意事项:转换流构造方法中,均有字节流与编码表两个参数。
字符 = 字节 + 编码表


InputStreamReader isr = new InputStreamReader(System.in);
InputStreamReader isr = new InputStreamReader(new FileInputStream(...));


OutputStreamWriter osw = new OutputStreamWriter(System.out);
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(...));


2.字符编码


(1)编码表
字符及其对应的数值组成的一张表。

(2)常见的码表:


ASCII:美国标准信息交换码。
ISO8859-1:拉丁码表。欧洲码表。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
BIG-5码 :通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符。


(3)编码应用:
A:IO转换流使用
创建转换流对象时,使用编码。
与字符串共同使用时,保证编码统一

B:字符串的使用
字符转成字节数组时,指定码表。
字节数组转成字符串时,指定码表。


编码表使用原则:编码与解码码表统一.


转换流与编码结合案例:

package cn.itcast2;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class Test {

	/**
	 * 转换流:将字节流转换为字符流 字符= 字节 + 编码
	 */
	public static void main(String[] args) throws IOException {

		// 创建字节流对象
		FileInputStream fis = new FileInputStream("a.txt");
		// 经输入转换流InputStreamReader将字节流转换为字符流
		InputStreamReader isr = new InputStreamReader(fis, "GBK");
		// 将字符流转换为高效流
		BufferedReader br = new BufferedReader(isr);


		// 创建字节流对象
		OutputStream os = new FileOutputStream("b.txt");
		// 创建转换流对象
		Writer w = new OutputStreamWriter(os, "GBK");
		// 创建高效字符流对象
		BufferedWriter bw = new BufferedWriter(w);
		
		//复制读取
		int len;
		char[] chars = new char[1024];
		while ((len= br.read(chars))!=-1) {
			//复制写入
			bw.write(chars, 0, len);
		}

		// 关闭流
		bw.close();
		br.close();

	}

}



3.打印流


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

(2)特点:

A:只操作目的地,不操作数据源
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法和printf()方法的时候,能够换行并刷新
D:可以直接操作文件


(3)复制文本文件
<span style="white-space:pre">		</span>BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
		
		String line = null;
		while((line=br.readLine())!=null) {
			pw.println(line);
		}
		
		pw.close();
		br.close();


案例:打印流的常规操作与刷新

package cn.itcast2;

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

public class Demo3 {
	/*
	 * 打印流支持自动刷新:
	 * 		1:要使用带自动刷新开关的构造
	 * 		public PrintWriter(OutputStream out, boolean autoFlush)
	 * 		public PrintWriter(Writer out,   boolean autoFlush)
	 * 		2:如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成刷新
	 */
	public static void main(String[] args) throws FileNotFoundException {
		//创建文件对象
		File  file = new File("b.txt");
		//创建字节打印流对象
		PrintStream  ps = new PrintStream(file);
		//调用print()方法打印
		ps.print(false);
		ps.print(97);
		//调用println()方法打印
		ps.println(22.22);
		ps.println();
		//调用printf()方法打印
		ps.printf("wo ao ye 123%d%.3f", 2,78.8);
		//如果构造函数没有自动刷新,必须自己刷新
		ps.flush();
		//关闭打印流没有意义,一般不用
//		ps.close();
	}

}


4.序列化流
(1)序列化流和反序列化流

序列化流:
ObjectOutputStream
writeObject(Object obj)
反序列化流:
ObjectInputStream
readObject()

可以把对象写入文本文件或者在网络中传输

(2)如何实现序列化
让被序列化的对象所属类实现序列化接口,该接口是一个标记接口,没有功能需要实现。
序列化接口:Serializable
无方法,仅作为可序列化标记使用.写出与读入时,序列化ID必须相同


(3)注意问题:
把数据写到文件后,在去修改类会产生一个问题。

解决问题方法:
在类文件中,给出一个固定的序列化id值,也可以解决黄色警告线问题

案例:将一个Person对象进行序列化和反序列化

a.将Person对象实现序列化接口

package cn.itcast2;

import java.io.Serializable;
//Person类实现序列化接口Serializable
public class Person implements Serializable {
	
	//给出一个固定的序列化id值,解决修改类产生找不到文件的问题
	private static final long serialVersionUID = 1L;
	private String name;
	public int age;
	public Person() {
		super();
		
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	
}


b.对实现序列化的Person对象进行序列化和反序列化操作
package cn.itcast;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//创建输出流对象
		FileOutputStream fos = new FileOutputStream("a.txt");
		//创建序列化流对象
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		//创建Person对象
		Person p = new Person("白百合",27);
		//写入对象
		oos.writeObject(p);
		//关闭流
		oos.close();
		
		//创建输入流对象
		FileInputStream  fis =  new FileInputStream("a.txt");
		//创建反序列流对象
		ObjectInputStream ois = new ObjectInputStream(fis);
		//读取到对象数据
		Object object = ois.readObject();
		//将对象进行向下转型
		Person person = (Person)object;
		//将数据进行打印进行查看
		System.out.println(person);
		
		ois.close();
		
	}

}




5.Properties


(1)Properties是Hashtable的子类。叫做属性集,用于存储属性键值对,通常作为配置文件来使用。

特点:
键值对均为字符串
可以直接操作IO流


(2)特有功能:
A:添加
Object setProperty(String key, String value) 
B:获取
String getProperty(String key)  
String getProperty(String key, String defaultValue)  
Set<String> stringPropertyNames() 相当于以前的keySet()

(3)和IO流结合的功能:

A:list() 把集合中的数据写到文本文件。只能使用打印流。
B:load() 把文本文件中的数据加载到集合。
C:store() 把集合中的数据写到文本文件。


(4)案例:设置游戏Person血量和魔法的属性集

package cn.itcast2;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;

public class Demo6 {
	/*
	 * Properties:属性集 双列集合的一种
	 * 
	 * 属性列表中每个键及其对应值都是一个字符串
	 * Properties可以直接操作IO
	 * 
	 */
	public static void main(String[] args) throws IOException {
		//创建属性集对象
		Properties  p = new Properties();
		//使用一般集合方法添加元素
		p.put("blood", "3000");
		//使用属性集的特有方法setProperty添加元素
		p.setProperty("magic", "2000");
		//打印属性集p进行查看
		System.out.println(p);
		
		//将属性集写入文件
		//创建文件对象
		File file = new File("s.txt");
		
		//创建流对象
		PrintWriter pw = new PrintWriter(file);
		//使用打印流把集合中的数据写到文本文件
		p.list(pw);
		//把集合中的数据写到文本文件
		p.store(pw, "person properties");
		pw.close();
		
		//将属性从文件中读取出来
		Properties p2 = new Properties();
		File file2 = new File("s.txt");
		InputStream  is = new FileInputStream(file2);
		//把文本文件中的数据加载到集合
		p2.load(is);
		is.close();
		//打印加载到属性集中的内容
		System.out.println(p2);
		
	}

}


6.数据操作流


(1)针对操作基本类型的数据

(2)流对象名称
数据输入流:DataInputStream
数据输出流:DataOutputStream

注意事项:在数据输入输出流的操作过程中,必须按照写入顺序读取,
否则由于读取规则的不同,会造成乱码。




7.内存操作流


(1)有时候操作完毕后,不需要产生一个文件,就要使用内存操作流。

(2)三种

A:字节内存操作流
ByteArrayInputStream:从数组中读取字节
ByteArrayOutputStream:将字节写入到数组中

B:字符内存操作流
CharArrayReader:从数组中读取字符
CharArrayWriter:将字符写到数组中

C:字符串内存操作流
StringWriter:将字符写到字符串中
StringReader:从字符串中读取数据

注意事项:有些IO操作流流关闭无效,不会产生IO异常。
如ByteArray操作流与String操作流


8.标准输入输出流


(1)System类下面有这样的两个字段
in 标准输入流
out 标准输出流

(2)三种键盘录入方式
A:main方法的args接收参数

B:System.in通过BufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

C:Scanner
Scanner sc = new Scanner(System.in);

(3)输出语句的原理和如何使用字符流输出数据

A:原理
System.out.println("helloworld");
PrintStream ps = System.out;
ps.println("helloworld");

B:把System.out用字符缓冲流包装一下使用
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
案例演示原理:

package cn.itcast2;

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

/*
 * System.in:
 * 		标准输入流    类型:InputStream
 */
public class Demo06_System_in {

	public static void main(String[] args) throws IOException {
		//定义标准输入流
		InputStream is = System.in;
		//将标准输入流通过转换流转化为字符输入流
		InputStreamReader isr = new InputStreamReader(is);
		//将字符输入流包装为缓冲区字符流
		BufferedReader br = new BufferedReader(isr);
		//定义字符串变量line
		String line;
		//读取控制台输入的数据
		while((line=br.readLine())!=null) {
			//定义一个结束标志byebye结束控制台录入
			if("byebye".equals(line)) {
				break;
			}
			//将控制台输入的数据再输出控制台
			System.out.println(line);
		}
		
		br.close();
	}

}



9.随机访问流

(1)RandomAccessFile对文件进行随机访问
可以按照文件指针的位置写数据和读数据。

(2)特点
同时支持读与写.
需要指定模式,使用"rw"模式。

(3)特殊方法:

获取指针所在位置:
public long getFilePointer() throws IOException
需要注意writerUTF的指针字节个数。

设置指针位置:
public void seek(long?pos) throws IOException
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值