把字节流转换为字符流,转换流是一种处理流。字节流有乱码的可能。
假设input.txt文件中存放了字符串“abc中国”
,使用字节流读取会乱码,使用字符流读取是使用平台默认的编码格式读取的,如果文本存储是不是平台的编码格式,也会出现乱码。转换流本质上就是加了编码格式的字符流。
@Test
public void test(){
//字节输入流
FileInputStream fis = new FileInputStream("test/input.txt");
int b ;
while((b = fis.read()) != -1){
System.out.println((char) b);
}
fis.close();
}
@Test
public void test(){
//字符输入流
FileReader fis = new FileReader("test/input.txt");//IDEA默认设置为utf-8格式
int b ;
while((b = fis.read()) != -1){
System.out.println((char) b);
}
fis.close();
}
@Test
public void test(){
//转换流 = 字节流 + 编码格式
InputStreamReader isr = new InputStreamReader(
new FileStreamReader("test/input.txt"), "GBK");
int b ;
while((b = fis.read()) != -1){
System.out.println((char) b);
}
fis.close();
}
由于字符集的数量很多,在输入输出时,必须使用转换流转换成对应编码格式后再进行写入和读出,才能保证数据不会乱码。
@Test
public void test(){
//文件字节输出流
FileOutputStream fos = new FileOutputStream("output.txt");//没有指定编码格式
//中占了两个字节,切分后会乱码
fos.write("中");//该代码只会输出一半
fis.close();
}
@Test
public void test(){
//创建文件输出流
OutputStreamWriter fos = new OutputStreamWriter("output.txt");
//创建转换流
OutputStreamWriter osr = new OutputStreamWriter(fos, "GBK");
fos.write("中");//转换流写出
fis.close();
}
数据流也是一种处理流,用来读写取基本数据类型的数据。
写入数据到文件中
public class DataioDemo {
@Test
public void test1() throws IOException {
//创建数据输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("test/dos.txt"));
//写出数据
dos.writeBoolean(true);
dos.writeDouble(123.45);
dos.writeInt(23);
dos.writeUTF("您好");
//关闭流
dos.close();
}
从文件中读取数据,注意读取数据顺序要和写入数据顺序一致。
@Test
public void test2() throws IOException {
//创建数据输入流
DataInputStream dis = new DataInputStream(new FileInputStream("test/dos.txt"));
//读取数据
//读取数据顺序要和写入数据顺序一致
boolean b = dis.readBoolean();
System.out.println("b = " + b);
double d = dis.readDouble();
System.out.println("d = " + d);
int i = dis.readInt();
System.out.println("i = " + i);
String s = dis.readUTF();
System.out.println("s = " + s);
}
序列化:序列化是指将内存中java对象以字节序列的形式表示,用于持久化存储。
反序列化:把字节序列重构为内存中的java对象。
前提条件:一个类要被序列化,那么这个类必须实现序列化接口。
类实现序列化接口后,进行序列化时会自动生成一个序列化版本号,一旦在反序列化时,如果修改过类的属性 和方法,会再自动生成另一个序列号。如果两者不一致,则无法实现序列化。实际开发过程中,新增一个属性、方法或者删除某个方法是很常见的,为了能够使修改后也能读取文件中的序列化对象,可以手动为类加上序列化ID。
private static final long serialVersionUID = -2324225L;
注: transient关键字:它修饰的变量不会被序列化。静态变量也不会被序列化。
对象序列化后转换成为字节序列,对象流的作用是用来读写对象的字节序列。分为对象输入流和对象输出流。
@Test
public void test1() throws IOException {
//创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test/obj.txt"));
//写出数据:java对象
oos.writeObject(new Student("张三",34));
//关闭流
oos.close();
}
@Test
public void test2() throws IOException, ClassNotFoundException {
//创建对象输出流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test/obj.txt"));
//读取对象数据
Student s = (Student) ois.readObject();
System.out.println(s);
//关闭流
ois.close();
}
只有输出,没有输入,输出的数据全部以字符串形式输出。分别为PrintStream字节打印流和PrintWriter字符打印流。
打印流的特有方法:
打印输出任意类型的数据,结果都是先转换为字符串再输出。带缓冲区的输出流数据默认先进入缓冲区,打印流可以支持自动刷新缓冲区。打印流也支持指定编码格式输出字符串。
@Test
public void test(){
//创建字节打印流
PrintStream ps =
new PrintStream("test/ps.txt");
//打印数据
ps.print("hello");
ps.print(true);
ps.print("world");
ps.print(123.45);
//关闭流
ps.close();
}
带缓冲的字节打印流
@Test
public void test(){
//创建缓冲流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test/ps.txt"));
//创建字节打印流
PrintStream ps = new PrintStream(bos);
//打印数据
ps.println(97);
//关闭流
ps.close();
}
创建字符打印流
@Test
public void test(){
//创建字符打印流
PrintWriter pw =
new PrintWriter("test/pw.txt");
//打印数据
pw.println("hello");
pw.println("您好");
pw.println(123);
//关闭流
ps.close();
}
标准输入输出流是打印流的一种,输出内容到控制台。可以通过setOut方法来修改打印位置。
自己模拟扫描器Scanner:
@Test
public void test(){
BufferedReader br = new BufferedReader(
new InputSteamReader(System.in));
System.out.println("请输入数据");
String line = br.readLine();
System.out.println("您输入的是: " + line );
}
该类有store方法和load方法可以将属性集合从内存中写入到文件中,也可以从文件中取出数据。
@Test
public void test1(){
Properties prop = new Properties();
prop.setProperty("name", "tom");
prop.store(new FileWriter("test/prop.properties"));
}
@Test
public void test1(){
Properties prop = new Properties();
prop.load(new FileReader("test/prop.propties"));
//从集合中取出数据
String name = prop.getProperty("name");
System.out.println(name);
}