1.数据输入输出流
数据输入流: DataInputStream
数据输出流: DataOutputStream
特点: 可以写基本数据类型,可以读取基本数据类型
public class Demo1 {
public static void main(String[] args) throws IOException {
//数据输入输出流 DataOutputStream DataInputStream
//特点:能写基本数据类型,能读取基本数据类型
dataWrite();
dataRead();
//读的顺序要和写的顺序一样,否则易乱码
}
private static void dataRead() throws IOException {
DataInputStream in=new DataInputStream(new FileInputStream("a.txt"));
System.out.println(in.read());
System.out.println(in.readInt());
System.out.println( in.readLong());
System.out.println(in.readShort());
}
private static void dataWrite() throws IOException {
DataOutputStream out=new DataOutputStream(new FileOutputStream("a.txt"));
out.write(2);//写入指定字节的低八位out.writeBoolean(true);//boolean类型
out.writeInt(12);//int类型
out.writeLong(12345);//long类型
out.writeShort(3);//short类型
out.writeByte(34);//将一个 byte 值以 1-byte 值形式写出到基础输出流中
out.writeBytes("明天你会感激今天努力的你");
out.writeDouble(3.1415926);
out.writeFloat(9);
out.writeUTF("爱生活爱 Java");
out.flush();
out.close();
}
}
2.内存操作流
内存操作流的概述
a:操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
此流关闭无效,所以无需关闭
b:操作字符数组
CharArrayWrite
CharArrayReader
c:操作字符串
StringWriter
StringReader
public class Demo2 {
public static void main(String[] args) throws IOException {
//内存操作流的概述
// a:操作字节数组
// ByteArrayOutputStream
// ByteArrayInputStream
// 此流关闭无效,所以无需关闭//取出数据的方法 :toByteArray(),toString()
ByteArrayOutputStream out=new ByteArrayOutputStream();
byte[] bytes={123,122,22,120};
out.write(bytes,0,3);
out.write(10);
//从缓冲区中取出数据
byte[] bytes1=out.toByteArray();
for(byte b:bytes1){
System.out.println(b);
}
ByteArrayOutputStream out1=new ByteArrayOutputStream();
out1.write("努力的你终将会有回报".getBytes());
out1.write("\r\n".getBytes());
out1.write("越努力越幸运".getBytes());
byte[] bytes2=out1.toByteArray();
System.out.println(out1.toString());
System.out.println("------------------------");
ByteArrayInputStream in=new ByteArrayInputStream(bytes1);
int len=0;
while((len=in.read())!=-1){
System.out.println(len);
}
ByteArrayInputStream in1=new ByteArrayInputStream(bytes2);
byte[] bytes3=new byte[1024];
in1.read(bytes3);
String str=new String(bytes3);
System.out.println(str);
}
}
public class Demo2 {
public static void main(String[] args) throws IOException {
//内存操作流的概述
// a:操作字节数组
// ByteArrayOutputStream
// ByteArrayInputStream
// 此流关闭无效,所以无需关闭//取出数据的方法 :toByteArray(),toString()
ByteArrayOutputStream out=new ByteArrayOutputStream();
byte[] bytes={123,122,22,120};
out.write(bytes,0,3);
out.write(10);
//从缓冲区中取出数据
byte[] bytes1=out.toByteArray();
for(byte b:bytes1){
System.out.println(b);
}
ByteArrayOutputStream out1=new ByteArrayOutputStream();
out1.write("努力的你终将会有回报".getBytes());
out1.write("\r\n".getBytes());
out1.write("越努力越幸运".getBytes());
byte[] bytes2=out1.toByteArray();
System.out.println(out1.toString());
System.out.println("------------------------");
ByteArrayInputStream in=new ByteArrayInputStream(bytes1);
int len=0;
while((len=in.read())!=-1){
System.out.println(len);
}
ByteArrayInputStream in1=new ByteArrayInputStream(bytes2);
byte[] bytes3=new byte[1024];
in1.read(bytes3);
String str=new String(bytes3);
System.out.println(str);
}
}
3.打印流:
printStream 字节打印流 printWriter 字符打印流
printStream: 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式.。它还提供其他两项功能:PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志;另外,为了自动刷新,可以创建一个 PrintStream。
printWriter 字符打印流
向文本输出流打印对象的格式化表示形式。与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作。
public class Demo4 {
public static void main(String[] args) throws IOException {
//PrintStream 字节打印流,能够打印出各种类型数据
File file=new File("a.txt");
PrintStream ps=new PrintStream(file);
ps.println("123456");
ps.println(true);
ps.println(1);
ps.println(3.14);
//注意此字节打印流关联的不是屏幕,所以打印不到屏幕上
System.out.println("---------------");
//out 标准的输出流,关联的设备是屏幕,可以直接打印出来看到
PrintStream out=System.out;
out.println(true);
out.println(123);
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public class Demo5 {
public static void main(String[] args)throws IOException {
//PrintWriter字符打印流
//没有自动刷新功能
PrintWriter pw=new PrintWriter("a.txt");
pw.println("爱生活,爱java");
pw.write("123456");
pw.println('m');
pw.flush();
pw.close();
System.out.println("------------");
//定义有自动刷新的功能
PrintWriter pw1=new PrintWriter(new FileOutputStream("a.txt"),true);
pw1.println("窗前明月光");
pw1.println("疑是地上霜");
pw1.println("热爱学习,热爱劳动");
}
}
public class Demo6 {
public static void main(String[] args)throws IOException {
//打印流复制文本文件
//打印流只能写,不能读取,我们采用BufferedReader读取
// PrintWriter pw=new PrintWriter(new FileOutputStream("b.txt"),true);
// pw.println("窗前明月光");
// pw.println("疑是地上霜");
// pw.println("举头望明月");
// pw.println("低头思故乡");
// pw.println("热爱学习,热爱劳动");
BufferedReader reader=new BufferedReader(new FileReader("b.txt"));
PrintWriter pw=new PrintWriter("copy.txt");
String line=null;
while((line=reader.readLine())!=null){
pw.println(line);
pw.flush();
}
pw.close();
reader.close();
}
}
4.标准的输入输出流
在System类中存在着两个静态的成员变量:
Public static final InputStream in:标准的输入流,对应的设备是键盘;
Public static final PrintStream out:标准的输出流,对应的设备是显示器。
注意:System.in的类型是InputStream。
System.out的类型是PrintStream。
案例:两种方式实现键盘录入
1.Scanner
2. BufferedReader
分析:由于标准的输入流对应的设备是键盘,且类型是Inputstream,故可以采用BufferedReader的readLine()方法。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public class Demo7 {
public static void main(String[] args) throws IOException {
//键盘的两种录入方式
//1.Scanner
//2.BufferedReader
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
while(true){
System.out.println("请键盘录入数据:");
String s=br.readLine();
if("end".equals(s)){
break;
}
System.out.println(s);
}
br.close();
}
}
5.随机访问流
RandomAccessFile概述 最大特点 能读能写
RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。此类支持对随机访问文件的读取和写入,随机访问文件的行为类似存储在文件系统中的一个大型byte数组,存在指向该数组的指针。该文件指针可以通过getFilePointer方法读取,并通过seek方法设置。
构造方法:
RandomAccessFile(File file, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
案例:
案例2:断点复制
public class Demo8 {
public static void main(String[] args) throws IOException {
//随机访问流 RandomAccessFile 可读可写
//写数据
WriteData();
//读数据
readData();
}
private static void readData() throws IOException {
RandomAccessFile ra = new RandomAccessFile("c.txt", "rw");
int b= ra.read();
long pointer=ra.getFilePointer();
System.out.println("指针位置"+pointer);
System.out.println(b);
byte[] bytes=new byte[3];
ra.read(bytes);
pointer=ra.getFilePointer();
System.out.println("指针位置"+pointer);
for(byte be:bytes){
System.out.println(be);
}
boolean bo=ra.readBoolean();
pointer=ra.getFilePointer();
System.out.println("指针位置"+pointer);
System.out.println(bo);
String s=ra.readUTF();
pointer=ra.getFilePointer();
System.out.println("指针位置"+pointer);
System.out.println(s);
//定位指针位置
ra.seek(4);
System.out.println(ra.readBoolean());
}
private static void WriteData() throws IOException {
RandomAccessFile ra = new RandomAccessFile("c.txt", "rw");
ra.write(95);
byte[] bytes = {1,2,3,44,55};
ra.write(bytes, 1, 3);
ra.writeBoolean(true);
ra.writeUTF("爱java");//一个汉字占五个字节
ra.close();
}
public class Demo9 {
public static void main(String[] args) throws IOException {
//断点复制文件,即文件复制一部分之后暂停了,下次可以从此处接着复制
//采用的是RandomAccessFile中的seek指针
RandomAccessFile r=new RandomAccessFile("论文.pdf","rw");
RandomAccessFile w=new RandomAccessFile("论文2.pdf","rw");
File file = new File("论文2.pdf");
if(file.exists()){
long len=file.length();
r.seek(len);
w.seek(len);
}else{
r.seek(0);
w.seek(0);
}
copyFile(r,w);
}
private static void copyFile(RandomAccessFile r, RandomAccessFile w)throws IOException {
String line=null;
while((line=r.readLine())!=null){
w.writeBytes(line);
long pointer=w.getFilePointer();
System.out.println(pointer);
}
r.close();
w.close();
}
}
6.序列化流与反序列化流
序列化:把对象通过流的方式存储到文件中,即把数据写到硬盘上。
反序列化:就是把文件存储的对象以流的方式还原成对象,即把数据读取到内存中。
序列化流:ObjectOutputStream
反序列化流:ObjectInputStream
注意:一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口。
Serializable接口是一个标记接口,此接口中没有任何方法。
public class Demo10 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化流ObjectOuptStream与反序列化流ObjectInputStream
//序列化:就是把数据写入硬盘中
//writeObj();
//反序列化:就是把数据读到内存中
readObj();
}
private static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("student.txt"));
Object obj1=ois.readObject();
Student stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
obj1=ois.readObject();
stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
obj1=ois.readObject();
stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
obj1=ois.readObject();
stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
obj1=ois.readObject();
stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
obj1=ois.readObject();
stu1=(Student)obj1;
System.out.println(stu1.name);
System.out.println(stu1.age);
ois.close();
}
private static void writeObj() throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("student.txt"));
Student s1=new Student("天天",12);
Student s2=new Student("天天1",11);
Student s3=new Student("天天2",12);
Student s4=new Student("天天3",14);
Student s5=new Student("天天4",16);
Student s6=new Student("天天5",19);
oos.writeObject(s1);
oos.writeObject(s2);
oos.writeObject(s3);
oos.writeObject(s4);
oos.writeObject(s5);
oos.writeObject(s6);
oos.close();
}
}
public class Student implements Serializable {
static final long serialVersionUID = 42L;//给Serializable添加的标记
String name;
transient int age;//用transient标记不被序列化的成员变量。
public Student(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
7.Properties
(1)Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
Properties父类是Hashtable,属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型。
案例演示: Properties作为Map集合的使用
public class Demo11 {
public static void main(String[] args) {
//Properties作为Map集合使用
Properties pro=new Properties();
pro.put(1,"小明");
pro.put(2,"天天");
pro.put(3,"亮亮");
pro.put(4,"顶顶");
pro.put(5,"小小");
pro.put(6,"明明");
//遍历找值
//方法1,键找值
Set<Object> key=pro.keySet();
for(Object k:key){
Object value=pro.get(k);
System.out.println(k+"----"+value);
}
System.out.println("---------------------");
//方法2:键值对找值
Set<Map.Entry<Object,Object>> entryset=pro.entrySet();
for(Map.Entry<Object,Object> en:entryset){
Object k=en.getKey();
Object v=en.getValue();
System.out.println(k+"-----"+v);
}
}
}
(2)Properties的特殊功能
public Object setProperty(String key,String value)添加元素,注意:第一次添加元素的时候返回的是null,下一次添加元素的时候返回的是上一次键对应的值。
public String getProperty(String key)根据键获取值
public Set stringPropertyNames()获取所有的键对应的Set集合
Properties集合的特有的遍历方式: 根据键找值
Set names = prop.stringPropertyNames() ;
for(String name : names){
// 获取值
String value = prop.getProperty(name) ;
// 输出
System.out.println(name + “----” + value);
}
public class Demo12 {
public static void main(String[] args) {
//Properties的特殊功能的使用
// public Object setProperty(String key,String value)添加元素
//注意:第一次添加元素的时候返回的是null,下一次添加元素的时候返回的是上一次键对应的值。
// public String getProperty(String key)根据键获取值
// public Set<String> stringPropertyNames()获取所有的键对应的Set集合
Properties pro=new Properties();
Object str= pro.setProperty("开开","心心");
System.out.println(str);//null
Object str1=pro.setProperty("开开","旺旺");
System.out.println(str1);//心心
pro.setProperty("小","大");
pro.setProperty("左","右");
System.out.println(pro.getProperty("小"));
System.out.println("-------------------");
Set<String> keyset=pro.stringPropertyNames();
for(String key:keyset){
Object v=pro.get(key);
System.out.println(v);
}
}
}
(3)Properties的load()和store()功能
Properties和IO流进行配合使用:
public void load(Reader reader): 读取键值对数据把数据存储到Properties中
public void store(Writer writer, String comments)把Properties集合中的键值对数据写入到文件中, comments注释.
public class Demo13 {
public static void main(String[] args) throws IOException {
// Properties的load()和store()功能
// public void load(Reader reader): 读取键值对数据把数据存储到Properties中
// public void store(Writer writer, String comments)把Properties集合中的键值对数据写入
Properties pro=new Properties();
FileWriter fw=new FileWriter("user.txt");
pro.setProperty("小","大");
pro.setProperty("左","右");
pro.setProperty("高","矮");
pro.setProperty("lisi","wangwu");
pro.store(fw,"反义词");
InputStreamReader in=new InputStreamReader(new FileInputStream("user.txt"));
Properties pro1=new Properties();
pro1.load(in);
Set<String> keyset=pro1.stringPropertyNames();
for(String k:keyset){
Object v=pro1.get(k);
System.out.println(k+"---"+v);
}
}
}
(4) 判断文件中是否有指定的键如果有就修改值.
案例演示
需求:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
分析:
a: 把文本文件中的数据加载到Properties集合中。
b: 判断这个集合中是否有"lisi"这个键如果有直接修改其值为100。
c: 把集合中的数据再次存储到文本文件中。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Set;
public class Demo14 {
public static void main(String[] args)throws IOException {
//我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
// 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
InputStreamReader in=new InputStreamReader(new FileInputStream("user.txt"));
Properties pro=new Properties();
pro.load(in);
Set<String> keyset=pro.stringPropertyNames();
for(String k:keyset){
if(k.equals("lisi")){
System.out.println("键lisi存在");
pro.setProperty("lisi","100");
}
}
for(String k1:keyset){
Object v=pro.get(k1);
System.out.println(k1+"---"+v);
}
}
}