目录
数据操作流
简介
- 数据输入流: DataInputStream(InputStream in)
- 数据输出流: DataOutputStream(OutputStream out)
举例
读
private static void read() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
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();
dis.close();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(c);
System.out.println(bb);
}
写
private static void write() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
// 写数据了
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);
// 释放资源
dos.close();
}
内存操作流
简介
用于处理临时存储信息的,程序结束,数据就从内存中消失
字节数组
- ByteArrayInputStream
- ByteArrayOutputStream
字符数组
- CharArrayReader
- CharArrayWriter
字符串
- String Reader
- String Writer
举例
// 写数据
// ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 写数据
for (int x = 0; x < 10; x++) {
baos.write(("hello" + x).getBytes());
}
// 释放资源
// 通过查看源码我们知道这里什么都没做,所以根本不需要close()
// baos.close();
// public byte[] toByteArray()
byte[] bys = baos.toByteArray();
// 读数据
// ByteArrayInputStream(byte[] byte)
ByteArrayInputStream bais = new ByteArrayInputStream(bys);
int by = 0;
while ((by = bais.read()) != -1) {
System.out.print((char)by);
}
// bais.close();
打印流
简介
- 字节流打印流: PrintStream
- 字符打印流: PrintWriter
- 打印流的特点:
-
A:只有写数据的,没有读取数据。只能操作目的地,不能操作数据源
-
B:可以操作任意类型的数据
-
C:如果启动了自动刷新,能够自动刷新。
-
D:该流是可以直接操作文本文件的。
哪些流对象是可以直接操作文本文件的呢?
FileInputStream
FileOutputStream
FileReader
FileWriter
PrintStream
PrintWriter
看API,查流对象的构造方法,如果同时有File类型和String
类型的参数,一般来说就是可以直接操作文件的流:
基本流:就是能够直接读写文件的
高级流:在基本流基础上提供了一些其他的功能
-
举例
- 1
PrintWriter pw = new PrintWriter("pw.txt");
pw.write("hello");
pw.write("world");
pw.write("java");
pw.close();
- 2
// 可以操作任意类型的数据
// 启用自动刷新
/* PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"),true);
* 还是应该调用println()的方法才可以
* 这个时候不仅仅自动刷新了,还实现了数据的换行
*
* println()
* 其实等价于:
* bw.write();
* bw.newLine();
* bw.flush();
*/
// 创建打印流对象
PrintWriter pw= new PrintWriter(new FileWriter("pw2.txt"),true);
pw.println("hello");
pw.println(true);
pw.println(100);
pw.close();
- 复制文件
BufferedReader br = new BufferedReader(new FileReader("DataStreamDemo.java"));
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"),true);
String line = null;
while((line = br.readLine())!=null) {
pw.println(line);
}
pw.close();
br.close();
- 标准输入输出流
- System类中的两个成员变量
public static final InputStream in: 标准输入流
InputStream is = System.in;
public static final PrintStream out: 标准输出流
PrintStream ps = System.out; - System.out
// 由这里的讲解我们就知道了,这个输出语句本质
System.out.println("helloworld");
PrintStream ps = System.out;
ps.println("helloworld");
ps.println();
// ps.print();// 这个方法不存在
System.out.println();
- System.in
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一个字符串");
String line = br.readLine();
System.out.println("你输入的字符串是:"+line);
System.out.println("请输入一个整数");
int i = Integer.parseInt(br.readLine());
System.out.println("你输入的整数是:"+i);
- 标准输入流方式把数据输出到控制台
OutputStream os = System.out; // 多态
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("hello");
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("java");
bw.newLine();
bw.flush();
bw.close();
随机访问流
介绍
RandomAccessFile类不属于流,是Object类的子类但它融合了InputStream和OutputStream的功能,支持对文件的随机访问读取和写入
构造方法
public RandomAccessFile(String name,String mode)
// 第一个参数是文件路径,第二个参数是操作文件的模式
// 模式有4中,我们最常用的一种叫"rw",这种方式表示我既可以写数据。
// 也可以读数据
举例
write
private static void write() throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
raf.writeInt(100);
raf.writeChar('a');
raf.writeUTF("中国");
raf.close();
}
read
private static void read() throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
int i = raf.readInt();
System.out.println(i);
// 该文件指针可以通过getFilePointer方法读取,并通过seek
// 方法设置
System.out.println("当前文件的指针位置是:"+raf.getFilePointer());
char ch = raf.readChar();
System.out.println(ch);
System.out.println("当前文件的指针位置是:"+raf.getFilePointer());
String s = raf.readUTF();
System.out.println(s);
System.out.println("当前文件的指针位置是:"+raf.getFilePointer());
//
raf.seek(4);
ch = raf.readChar();
System.out.println(ch);
}
合并流
两个文件
// 需求:把ByteArrayStreamDemo.java和DataStreamDemo.java
// 的内容复制到copy.java中
InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
InputStream s2 = new FileInputStream("DataStreamDemo.java");
SequenceInputStream sis = new SequenceInputStream(s1,s2);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java"));
byte[] bys = new byte[1024];
int len = 0;
while((len=sis.read())!=-1) {
bos.write(bys,0,len);
}
bos.close();
sis.close();
三个文件
// 需求:把下面的三个文件的内容复制到Copy.java中
Vector<InputStream> v = new Vector<InputStream>();
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<InputStream> 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())!=-1) {
bos.write(bys,0,len);
}
bos.close();
sis.close();
序列化流
定义
(1) 序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输
(2) 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象
举例
write
private static void write() throws IOException {
// 创建序列化流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
// 创建对象
Person p = new Person("林青霞",27);
// public final void writeObject(Object obj)
oos.writeObject(p);
// 释放资源
oos.close();
}
read
private static void read() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
// 还原对象
Object obj = ois.readObject();
// 释放资源
ois.close();
// 输出对象
System.out.println(obj);
}
注意
① 定义的类要实现Serializable接口,该接口没有任何方法,类似于这种没有方法的接口被称为标记接口
② NotSerializableException:未序列化异常
③ 一个类中可能有很多的成员变量,有些我不想序列化怎么办呢?使用transient关键字声明不需要序列化的成员变量
属性集合类
定义
Properties: 是一个可以和IO流相结合使用的集合类,可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串
是Hashtable的子类,说明是一个Map集合
作为Map集合的使用举例
Properties prop = new Properties();
// 添加元素
prop.put("it002", "hello");
prop.put("it001", "world");
prop.put("it004", "java");
System.out.println("prop:"+prop);
// 遍历集合
Set<Object> set = prop.keySet();
for(Object key:set) {
Object value = prop.get(key);
System.out.println(key+"---"+value);
}
特殊功能
public Object setProperty(String key,String value) // 添加元素
public String getProperty(String key) // 获取元素
public Set<String> stringPropertyNames() // 获取所有的键的集合
举例
// 创建集合对象
Properties prop = new Properties();
// 添加元素
prop.setProperty("张三", "30");
prop.setProperty("李四", "40");
prop.setProperty("王五", "50");
// public Set<String> stringPropertyNames()
Set<String> set = prop.stringPropertyNames();
for(String key:set) {
String value = prop.getProperty(key);
System.out.println(key+"---"+value);
}
和IO流结合的方法
public void load(Reader reader) // 把文件中的数据读取到集合中
public void store(Writer writer,String comments) // 把集合中的数据存储到文件
myLoad
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);
}
myStore
private static void myStore() throws IOException {
// 创建集合对象
Properties prop = new Properties();
prop.setProperty("林青霞", "27");
prop.setProperty("武鑫", "30");
prop.setProperty("刘晓曲", "18");
Writer w = new FileWriter("name.txt");
prop.store(w, "helloworld");
w.close();
}
NIO
简介
- nio包在JDK4出现,提供了IO流的操作效率,但是目前还不是大范围使用的
- 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)
举例
Files.copy(Paths.get("ByteArrayStreamDemo.java"), new FileOutputStream("Copy.java"));
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));