——- android培训、java培训、期待与您交流! ———-
字节输入输出流和字符输入输出流以及他们的高效流我们已将讲过了,
下面我们在了解下其他的一些特殊IO流。每一个我们都一个练习帮助消化
数据输入输出流:
特点: 可以操作基本的数据类型
数据输入流: DataInputStream
数据输出流: DataOutputStream
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 数据的输入和输出流
* 数据输入流: DataInputStream
* 数据输出流: DataOutputStream
*
* 特点:
* 可以将基本的java 的数据类型写入到文件中
*/
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
write() ;
read() ;
}
/**
* 使用数据的输入流进行读取数据
*/
private static void read() throws IOException {
// 创建对象
/**
* public DataInputStream(InputStream in)
*/
DataInputStream dis = new DataInputStream(new FileInputStream("dataStream.txt")) ;
// 读取数据
int i = dis.readInt() ;
char a = dis.readChar() ;
String r = dis.readUTF() ;
// 释放资源
dis.close() ;
// 输出
System.out.println(i);
System.out.println(a);
System.out.println(r);
}
/**
* 使用数据输出流写入基本的数据类型
* @throws IOException
*/
private static void write() throws IOException {
/**
* public DataOutputStream(OutputStream out)
*/
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dataStream.txt")) ;
// 写数据
/**
* 写入基本的数据类型的数据
*/
dos.writeInt(100) ;
dos.writeChar(97) ;
dos.writeUTF("中国") ;
// 释放资源
dos.close() ;
}
}
但当我们打开该文件dataStream.txt时候发现全是乱码。我会骗你?
怎么会,这是因为编码的问题。想看,ok。读出来就ok了。
内存操作流:
a:操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
b:操作字符数组
CharArrayWriter
CharArrayReader
c:操作字符串
StringWriter
StringReader
public static void main(String[] args) {
// 创建ByteArrayOutputStream对象
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
// 写数据
baos.write("hello".getBytes()) ;
// 我们可以通过调用toByteArray()和toString()方法获取数据
byte[] bytes = baos.toByteArray() ;
// 输出
// System.out.println(new String(bytes)) ;
// 调用toString方法获取数据
// String result = baos.toString() ;
// 输出
// System.out.println(result) ;
System.out.println("---------------------------") ;
ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ;
// 读取数据
int by = 0 ;
while((by = bais.read()) != -1){
System.out.print((char)by) ;
}
}
打印流
字节打印流: PrintStream
字符打印流: PrintWriter
特点:
a: 只能操作目的地,不能操作数据源
b: 可以操作任意的数据类型
c: 如果启动了自动刷新,那么可以完成自动刷新 (println , printf , format)
d: 可以直接的对文件进行操作
那些流对象可以直接的操作文件?
FileInputStream
FileOutputStream
FileReader
FileWriter
PrintStream
PrintWriter
需要提醒大家的是打印流无法读,在用它复制文件的时候还要配合Reader或InputStream使用。
并且开启自动刷新后只有在调用println , printf , format这三个方法时才会奏效。
什么?特点都说了!好吧,我只是凑个脸熟
使用打印流复制文本文件:
public static void copyFile() throws IOException {
// 创建高效的字符输入流对象
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() ;
}
标准的输入和输出流:
在System类中存在两个静态的成员变量一个是in , 一个是out
public static final InputStream in ; 标准输入流 对应的设备是键盘
public static final PrintStream out ; 标准输出流 对应的设备是显示器
键盘录入数据的二种方式:
a: 使用Scanner
Scanner sc = new Scanner(System.in) ;
b: 使用main方法
java HelloWorld hello world java
这个就不多说了,键盘录入应该都用过吧
序列化流和反序列化流:
序列化: 就是把对象存储到文本文件中
反序列化: 就是把文本文件中的对象还原成一个对象
transient: 此关键字用来修饰不需要序列化的参数
如果我们想让一个对象可以被序列化, 那么该对象对应的类就需要实现Serializable接口.
序列化流: ObjectOutputStream
public final void writeObject(Object obj);
反序列化流: ObjectInputStream
public final Object readObject() ;
下面我们用Student类练习下序列化和反序列话、
首先我们需要创建个Student类,不要忘了实现Serializable接口.
import java.io.Serializable;
public class Student implements Serializable {
//保证序列化后修改Student类不会对反序列话产生影响Eclipse会提供此方法
private static final long = -3936363714564814861L;
private String name ;
// 如果我们不想让某一个字段被序列化那么我们可以使用transient这个关键字来修饰该字段
private transient int age ;
public Student() {
super();
}
public Student(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 "Student [name=" + name + ", age=" + age + "]";
}
}
序列化和反序列化
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 序列化: 就是把对象存储到文件中
* 反序列化: 把文件中的对象还原成一个对象
*
* 序列化流: ObjectOutputStream
* 反序列化流: ObjectInputStream
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// writeObject() ;
readObject() ;
}
/**
* 使用反序列化流进行读取数据
* @throws IOException
* @throws ClassNotFoundException
* @throws FileNotFoundException
*/
private static void readObject() throws IOException, ClassNotFoundException {
/**
* public ObjectInputStream(InputStream in):
*/
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("objects.txt")) ;
/**
* public final Object readObject(): 读取对象
*/
Object obj = ois.readObject() ;
// 向下转型
// Student s = (Student)obj ;
// 输出
System.out.println(obj);
// System.out.println(s.getName() + "----" + s.getAge());
// 释放资源
ois.close() ;
}
/**
* 使用序列化流把对象存储到文本文件中
* @throws IOException
* @throws FileNotFoundException
*/
private static void writeObject() throws IOException {
/**
* public ObjectOutputStream(OutputStream out)
*/
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("objects.txt")) ;
// 创建一个对象
Student s = new Student("张三" , 23) ;
// 写对象
oos.writeObject(s) ;
// 释放资源
oos.close() ;
}
}
Properties :
Properties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载。
属性列表中每个键及其对应值都是一个字符串。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。
但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项
public Object setProperty(String key,String value): 添加元素
public String getProperty(String key): 根据键获取值
public Set<String> stringPropertyNames(): 获取所有的键对应的Set集合
public void load(Reader reader) : 可以把一个文本文件中的数据加载到一个集合中
public void store(Writer writer,String comments) : 可以把一个集合
下面我们做个练习
需求:
我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
文本文件内容:
zhangsan=23
lisi=35
wangwu=28
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/**
* 我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
分析:
a: 创建一个Propertes对象
b: 调用load方法加载文本文件中的数据到集合中
c: 获取所有键对应的Set集合
d: 判断这个Set集合中是否存在"lisi"这个键,如果存在就重新设置其值为100
e: 把集合中的数据存储到文本文件中调用store方法
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException {
// 创建一个Propertes对象
Properties prop = new Properties() ;
// 调用load方法加载文本文件中的数据到集合中
prop.load(new FileReader("info.txt")) ;
// 获取所有键对应的Set集合
Set<String> names = prop.stringPropertyNames() ;
// 判断这个Set集合中是否存在"lisi"这个键,如果存在就重新设置其值为100
if(names.contains("lisi")){
// 把值设置成100
prop.setProperty("lisi", "100") ;
}
// 把集合中的数据存储到文本文件中调用store方法
prop.store(new FileWriter("info.txt"), null) ;
}
}
当然IO流还有其它的类,这里就将这么多了。有兴趣的可以在做研究