登录注册IO版本案例(掌握)
要求,对着写一遍。
cn.itcast.pojo User
cn.itcast.dao UserDao
cn.itcast.dao.impl UserDaoImpl(实现我不管)
cn.itcast.game GuessNumber
cn.itcast.test UserTest
数据操作流(操作基本类型数据的流)(理解)
1、可以操作基本类型的数据
2、流对象名称
DataInputStream
A:创建数据输出流对象
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"dos.txt"));
B:写数据
dos.writeByte(10);
dos.writeShort(100);
dos.writeInt(1000);
dos.writeLong(10000);
dos.writeFloat(12.34F);
dos.writeDouble(12.56);
dos.writeChar('a');
dos.writeBoolean(true);
C:释放资源
dos.close();
DataOutputStream
A:创建数据输入流对象
DataInputStream dis = new DataInputStream(
new FileInputStream("dos.txt"));
B:读数据
byte b = dis.readByte();
short s = dis.readShort();
int i = dis.readInt();
long l = dis.readLong();
float f = dis.readFloat();
double d = dis.readDouble();
char c = dis.readChar();
boolean bb = dis.readBoolean();
C:释放资源
dis.close();
内存操作流(理解)
1、有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
2、三种
A:操作字节数组
ByteArrayInputStream
//将写入的流转化为字符数组
byte[] bys = baos.toByteArray();
//创建对象
ByteArrayInputStream bais = new ByteArrayInputStream(bys);
//读数据
int by = 0;
while ((by = bais.read()) != -1) {
System.out.print((char) by);
}
ByteArrayOutputStream
// 创建对象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 写数据
for (int x = 0; x < 10; x++) {
baos.write(("hello" + x).getBytes());
}
// 释放资源
// 通过查看源码我们知道这里什么都没做,所以根本需要close()
// baos.close();
B:操作字符数组
CharArrayReader
CharArrayWriter
C:操作字符串
StringReader
StringWriter
打印流(掌握)
1、字节打印流 PrintStream,字符打印流 PrintWriter
2、特点:
A:只操作目的地,不操作数据源(只能写不能读)
B:可以操作任意类型的数据
C:如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
D:可以直接操作文件
问题:哪些流可以直接操作文件呢?
FileInputStream
FileOutputStream
FileReader
FileWriter
PrintStream
PrintWriter
流分为基本流(能直接读写文件)和高级流(在基本流基础上提供一些其它功能)
看API,如果其构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的
3、复制文本文件
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); //println自动刷新功能
}
pw.close();
br.close();
标准输入输出流(理解)
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));
随机访问流(理解)
RandomAccessFile类不属于流,是Object类的子类。
但它融合了InputStream和OutputStream的功能。
支持对文件的随机访问读取和写入。
1、可以按照文件指针的位置写数据和读数据。
2、案例:
A:创建随机访问流对象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw"); //第一个参数是文件路径,第二个参数是操作文件的模式。
//模式有四种,我们最常用的一种叫"rw",这种方式表示我既可以写数据,也可以读取数据
B:写数据
raf.writeChar('a');
C:读数据
char ch = raf.readChar();
D:获取和改变文件指针的位置
raf.getFilePointer();
E:设置指针位置
raf.seek(4);
合并流(理解)
1、把多个输入流的数据写到一个输出流中。
2、构造方法:
A:SequenceInputStream(InputStream s1, InputStream s2)
B:SequenceInputStream(Enumeration<? extends InputStream> e)
3、例子:
public class SequenceInputStreamDemo2 {
public static void main(String[] args) throws IOException {
// 需求:把下面的三个文件的内容复制到Copy.java中
// ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java
// SequenceInputStream(Enumeration e)
// 通过简单的回顾我们知道了Enumeration是Vector中的一个方法的返回值类型。
// Enumeration elements()
Vector v = new Vector();
InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
InputStream s2 = new FileInputStream("CopyFileDemo.java");
InputStream s3 = new FileInputStream("DataStreamDemo.java");
v.add(s1);
v.add(s2);
v.add(s3);
Enumeration en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("Copy.java"));
// 如何写读写呢,其实很简单,你就按照以前怎么读写,现在还是怎么读写
byte[] bys = new byte[1024];
int len = 0;
while ((len = sis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
sis.close();
}
}
序列化流(理解)
1、可以把对象写入文本文件或者在网络中传输。对象 -- 流数据(ObjectOutputStream)
2、如何实现序列化呢(NotSerializableException:未序列化异常)?
implements Serializable 让被序列化的对象所属类实现序列化接口。
该接口是一个标记接口。没有功能需要实现。
3、注意问题(InvalidClassException):
把数据写到文件后,在去修改类,不写再读,会产生一个问题。
如何解决该问题呢?
实际开发中,需要修改类但还需要使用以前写过的数据,不能重新写入。怎么办呢?
在类文件中,给出一个固定的序列化id值。
点击黄色警告线 Add generated serial version ID, 这样也可以解决黄色警告线问题
我一个类中可能有很多的成员变量,有些我不想进行序列化。请问该怎么办呢?
使用transient关键字声明不需要序列化的成员变量(private transient int age;)
4、面试题:
什么时候序列化?
如何实现序列化?
什么是反序列化?
反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 -- 对象(ObjectInputStream)
Properties(理解)
1、 属性集合类。是一个可以和IO流相结合使用的集合类。
可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
是Hashtable的子类,说明是一个Map集合。
Properties prop = new Properties();
// 添加元素
prop.put("it002", "hello");
prop.put("it001", "world");
prop.put("it003", "java");
// System.out.println("prop:" + prop);
// 遍历集合
2、特有功能
A:public Object setProperty(String key,String value); //添加元素
B:public String getProperty(String key); //获取元素
C:public Set stringPropertyNames(); //获取所有键的集合
D:例子
public class PropertiesDemo2 {
public static void main(String[] args) {
// 创建集合对象
Properties prop = new Properties();
// 添加元素
prop.setProperty("张三", "30");
prop.setProperty("李四", "40");
prop.setProperty("王五", "50");
// public Set stringPropertyNames():获取所有的键的集合
Set set = prop.stringPropertyNames();
for (String key : set) {
String value = prop.getProperty(key);
System.out.println(key + "---" + value);
}
}
}
3、和IO流结合的方法
把键值对形式的文本文件内容加载到集合中
public void load(Reader reader)
public void load(InputStream inStream)
把集合中的数据存储到文本文件中
public void store(Writer writer,String comments)
public void store(OutputStream out,String comments)
注意:这里的集合指的是properties集合
例子:
public class PropertiesDemo3 {
public static void main(String[] args) throws IOException {
// myLoad();
myStore();
}
private static void myStore() throws IOException {
// 创建集合对象
Properties prop = new Properties();
prop.setProperty("林青霞", "27");
prop.setProperty("武鑫", "30");
prop.setProperty("刘晓曲", "18");
//public void store(Writer writer,String comments):把集合中的数据存储到文件
Writer w = new FileWriter("name.txt");
prop.store(w, "helloworld");
w.close();
}
private static void myLoad() throws IOException {
Properties prop = new Properties();
// public void load(Reader reader):把文件中的数据读取到集合中
// 注意:这个文件的数据必须是键值对形式
Reader r = new FileReader("prop.txt");
prop.load(r);
r.close();
System.out.println("prop:" + prop);
}
}
4、案例:
A:根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100
B:写一个程序实现控制猜数字小游戏程序不能玩超过5次
NIO(了解)
1、JDK4出现的NIO,对以前的IO操作进行了优化,提高了效率。但是大部分我们看到的还是以前的IO。
2、JDK7的NIO的使用
Path:路径
Paths:通过静态方法返回一个路径
public static Path get(URI uri)
Files:提供了常见的功能
复制文件:
public static long copy(Path source,OutputStream out)
把集合中的数据写到文本文件:
public static Path write(Path path,Iterable<? extends CharSequence> lines,Charset cs,OpenOption... options)
3、例子:
public class NIODemo {
public static void main(String[] args) throws IOException {
// public static long copy(Path source,OutputStream out)
// Files.copy(Paths.get("ByteArrayStreamDemo.java"), new
// FileOutputStream(
// "Copy.java"));
ArrayList array = new ArrayList();
array.add("hello");
array.add("world");
array.add("java");
Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
}
}