【我的Java笔记】IO流_IO流中的其他类

DataOutputStream & DataInputStream

数据输出流 & 数据输入流

1.概述:二者都属于数据流(可以针对Java基本数据类型进行读写操作)

注:通过DataOutputStream写入的数据不能直接读懂,需要靠DataInputStream来读出写入的数据


2.构造方法:

DataOutputStream :public DataOutputStream(OutputStream out)

DataInputStream: public DataInputStream(InputStreamin)


例:

写入数据

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataOutputStreamDemo {
	public static void main(String[] args) throws IOException {
		write();
	}

	// 写数据
	private static void write() throws FileNotFoundException, IOException {
		// 创建数据输出流对象
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("1129.txt"));

		// 写数据
		dos.writeByte(100);
		dos.writeInt(1000);
		dos.writeShort(120);
		dos.writeLong(1000000L);
		dos.writeChar('A');
		dos.writeBoolean(true);
		dos.writeFloat(12.34F);
		dos.writeDouble(12.56);

		// 释放资源
		dos.close();
	}
}


读出刚刚写入的数据
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class DataInputStreamDemo {
	public static void main(String[] args) throws IOException {

		read();
	}

	// 读数据
	private static void read() throws FileNotFoundException, IOException {
		// 读数据
		// 创建数据输入流对象
		DataInputStream dis = new DataInputStream(new FileInputStream("1129.txt"));

		// 读数据
		byte b = dis.readByte();
		int i = dis.readInt();
		short s = dis.readShort();
		long l = dis.readLong();
		char ch = dis.readChar();
		boolean flag = dis.readBoolean();
		float f = dis.readFloat();
		double d = dis.readDouble();

		// 释放资源
		dis.close();
		
		//打印出来
		System.out.println(b);
		System.out.println(i);
		System.out.println(s);
		System.out.println(l);
		System.out.println(ch);
		System.out.println(flag);
		System.out.println(f);
		System.out.println(d);
	}

}


读取结果:
【我的Java笔记】IO流_IO流中的其他类_第1张图片








ByteArrayInputStream & ByteArrayOutputStream
内存操作输入流 & 内存操作输出流

1.概述:内存操作流,针对内存的数据进行操作的,程序一结束,这些内存中的数据也就消失掉了
(1)ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不 断写入而自动增长。可使用 toByteArray() toString() 获取数据。
(2)ByteArrayInputStream:包含一个内部缓冲区,该缓冲区包含从流中读取的字节

2.特点:针对小文件进行操作

3.构造方式:
(1)ByteArrayInputStream:public ByteArrayInputStream(byte[] buf):参数是一个字节数组(缓冲数组)
(2)ByteArrayOutputStream: public ByteArrayOutputStream():创建默认的缓冲区大小的内存操作输出流(单位是字节)

4.成员方法:
(1)ByteArrayOutputStream:
①public byte[] toByteArray()创建一个新分配的 byte 数组(将内存操作输出流对象转换成字节数组)
②void reset()重置内存操作输出流
③public String toString() 使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串

注:此流关闭无效。此类中的方法在关闭此流后仍可被调用

例:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class ByteArrayStreamDemo {
	public static void main(String[] args) throws IOException {

		// 创建内存操作输出流对象
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		// 写数据
		for (int  i= 0; i < 5; i++) {
			baos.write(("hello" + i).getBytes());
		}

		// 将内存操作输出流对象转换成字节数组
		// public byte[] toByteArray()创建一个新分配的 byte 数组(将内存操作输出流对象转换成字节数组)
		byte[] bys = baos.toByteArray();

		// 创建内存操作输入流对象
		ByteArrayInputStream bais = new ByteArrayInputStream(bys);

		// 一次读取一个字节
		int by = 0;
		while ((by = bais.read()) != -1) {
			System.out.print((char) by);
		}
	
	}
}
结果:











PrintStream & PrintWriter
字节打印流 & 字符打印流

1.概述:PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。


2.打印流特点:

(1)复制文件,打印流不能操作数据源,只能操作目的地数据(只能输出数据

(2)打印流存在自动刷新的功能(自动调用flush()方法)

(3)打印流可以直接针对文本文件进行操作


注:什么情况可以针对文本文件进行操作?

只要构造方法的参数中存在File类或者是String类型,都可以直接针对文本文件进行操作

例如:FileInputStream、FileOutputStream、FileReader、FileWriter


3.构造方法:

(1)public PrintWriter(String fileName)

(2)PrintWriter自动刷新功能

public PrintWriter(Writer out,boolean autoFlush)  第二个参数为true,则自动刷新


4.特有方法:

(1)public void print()参数可以传任意类型进行打印

(2)public void println()通过写入行分隔符终止当前行



例1:自动刷新和换行功能的使用

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterDemo {
	public static void main(String[] args) throws IOException {

		// 创建字符打印流对象
		PrintWriter pw = new PrintWriter(new FileWriter("ss.txt"), true);	//自动刷新

		// 写入数据
		// 使用public void println(String x):打印字符串,并且终止该行
		pw.println("i");
		pw.println("am");
		pw.println("Zilatan");

		// 释放资源
		pw.close();
	}
}

【我的Java笔记】IO流_IO流中的其他类_第2张图片




例2:使用打印流进行文件的复制

/*
 * 需求:将当前项目下的“学生成绩.txt”复制到当前项目下的“复制学生成绩.txt”
 * */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterCopyDemo {
	public static void main(String[] args) throws IOException {

		// 封装数据源
		BufferedReader br = new BufferedReader(new FileReader("学生成绩.txt"));

		// 封装目的地,使用字符打印流对象并启动自动刷新功能
		PrintWriter pw = new PrintWriter(new FileWriter("复制学生成绩.txt"), true); // 此种构造方式可以自动刷新

		// 读取数据
		String line = null;
		while ((line = br.readLine()) != null) {
			// 写入数据,读取一行并启动自动换行
			pw.println(line);
		}

		// 释放资源
		br.close();
		pw.close();
	}
}










RandomAccessFile
随机访问流

1.概述:随机访问流:此类的实例支持对随机访问文件的读取和写入

不是实际意义上的流,他继承自Object类


2.构造方法:

public RandomAccessFile(String name,String mode)

参数一:指定该文件的路径参数二:指定的一种模式,常用的模式:"rw",这种模式表示可读也是可写的


3.成员方法:

public long getFilePointer()返回此文件中的当前偏移量(文件开头的偏移量。以字节为单位)


例:

写入数据

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

	public static void main(String[] args) throws IOException {
		
		write();
	}

	// 写数据
	private static void write() throws FileNotFoundException, IOException {
		// 创建随机访问流对象
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");

		// 写数据
		raf.writeByte(100);
		raf.writeChar('a');
		raf.writeUTF("中国");

		// 关闭资源
		raf.close();
	}
}


读取数据

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo {

	public static void main(String[] args) throws IOException {

		read();
	}

	// 读数据
	private static void read() throws FileNotFoundException, IOException {
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");

		// 读数据
		byte b = raf.readByte();
		System.out.println(b);

		char ch = raf.readChar();
		System.out.println(ch);

		String str = raf.readUTF();
		System.out.println(str);

		// public long getFilePointer():返回此文件中的当前偏移量。 文件开头的偏移量(以字节为单位)
		System.out.println("getFilePointer:" + raf.getFilePointer());

		// 关闭资源
		raf.close();
	}
}


结果:

【我的Java笔记】IO流_IO流中的其他类_第3张图片












SequenceInputStream
合并流

1.概述:表示其他输入流的逻辑串联。从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

2.特点:合并流在复制文件的时候,只能操作数据源,不能操作目的地。(与打印流相反)

3.构造方法:
(1)public SequenceInputStream(InputStream s1,InputStream s2)
(2)public SequenceInputStream(Enumeration e)
Vector集合中的特有功能:public Enumeration elements()枚举

4.复制两个文件的操作步骤:
(1)数据源:数据源文件1,数据源文件2--------------->SequenceInputStream(分别读取文件1和文件2,合并为SequenceInputStream对象
(2)目的地:目的地文件--------------->BufferedOutputStream(写入数据)

5.一次复制多个文件的操作步骤
(1)数据源:数据源文件1,数据源文件2,数据源文件3······--------------->添加至Vector集合(使用elements()方法产生Enumeration对象)--------------->SequenceInputStream(将Enumeration对象添加至合并流中
(2)目的地:目的地文件--------------->BufferedOutputStream(写入数据)


例1:使用第一种构造方法进行两个文件的复制
/*
 * 需求:将当前项目下的文件“s.txt”和“ss.txt”复制到“sss.txt”中
 * */

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;

public class SequenceInputStreamDemo {
	public static void main(String[] args) throws IOException {
		// 分别封装这个两个源数据文件
		InputStream s1 = new FileInputStream("s.txt");
		InputStream s2 = new FileInputStream("ss.txt");

		// 创建合并流对象封装这两个源数据文件
		SequenceInputStream sis = new SequenceInputStream(s1, s2);

		// 封装目的地
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("sss.txt"));

		// 一次读取一个字节数组写入数据
		byte[] bys = new byte[1024];
		int len = 0;
		while ((len = sis.read(bys)) != -1) {
			// 写数据
			bos.write(bys, 0, len);
			bos.flush();
		}

		// 释放资源
		sis.close();
		bos.close();
	}
}


例2:使用第二种构造方法进行多个文件的复制
/*
 * 需求:将文件s.txt,ss.txt和sss.txt复制到ssss.txt文件中
 * */

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class SequenceInputStreamDemo1 {

	public static void main(String[] args) throws IOException {

		// 创建一个Vector集合,泛型数据类型
		Vector v = new Vector();

		// 封装者三个java文件
		InputStream s1 = new FileInputStream("s.txt");
		InputStream s2 = new FileInputStream("ss.txt");
		InputStream s3 = new FileInputStream("sss.txt");

		// 添加到集合中
		v.add(s1);
		v.add(s2);
		v.add(s3);

		// 调用Vector集合的特有功能:public Enumeration elements()
		Enumeration en = v.elements();
		// 创建合并流对象
		SequenceInputStream sis = new SequenceInputStream(en);
		// 封装目的地
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ssss.txt"));

		// 一次读取一个字节数组
		byte[] bys = new byte[1024];
		int len = 0;
		while ((len = sis.read(bys)) != -1) {
			// 写数据
			bos.write(bys, 0, len);
			bos.flush();
		}

		// 释放资源
		bos.close();
		sis.close();
	}
}













ObjectInputStream & ObjectOutputStream

反序列化流 & 序列化流(可以将对象以流来操作

1.概述:

(1)ObjectOutputStream(序列化流):将对象或者网络传输中的数据以流的方式写入OutputStream

对象---------->流数据(写数据)

(2)ObjectInputStream(反序列化流):将流数据或者网络传输中的流数据读取出来

流数据---------->还原成对象(读数据)


2.成员方法:

(1)ObjectOutputStream中的成员方法:

public final void writeObject(Object obj)将obj对象写入到当前的序列化流中

(2)ObjectInputStream中的成员方法:

public final Object readObject()从当前反序列化流中读取一个对象


3.注意事项:

(1)在使用序列化或者反序列时,该对象所在的类须实现一个标记接口:Serializable(标记接口:接口中不存在字段、搞糟方法和方法)

(2)序列化和反序列化的过程中,当改变对象所在类中的成员变量时,会因产生的版本ID不一致而出现异常,可使用Ececlipse产生固定、随机ID的方法(点对象所在类名上的黄线,第一种方法产生固定serialVersionUID)

注:此种方法不用在改变对象的类中的成员变量或者成员常量后,再重新序列化再反序列化(不用在重新的写入数据再读数据)

(3)关键字:transient,当自定义类中的 成员常量/成员变量 不想被序列化时可用此关键字修饰 


例:

/*
 * 需求:使用序列化将Person类的对象写入流中,再使用反序列化读取流中的对象
 * */

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectStreamDemo {

	public static void main(String[] args) throws Exception {

		// write();
		 read();
	}

	// 反序列化(读取数据:将当前流数据--->对象)
	private static void read() throws IOException, FileNotFoundException, ClassNotFoundException {
		// 创建一个反序列化流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("sss.txt"));

		// 读取数据
		Object obj = ois.readObject();

		// 关闭资源
		ois.close();
		System.out.println(obj);
	}

	// 序列化(写入数据)
	private static void write() throws IOException {

		// 创建一个Person对象
		Person p = new Person("伊卡尔迪", 24);
		// 创建一个序列化流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("sss.txt"));

		// 写数据入数据:writeObject(Object obj)
		oos.writeObject(p);

		// 释放资源
		oos.close();
	}
}



// Person类,该类若要序列化则需实现Serializable接口
class Person implements Serializable {

	// default Servial ID 生成一个ID
	private static final long serialVersionUID = 1L;

	private String name;
	private int age;

	public Person() {
		super();
	}

	public Person(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 "Person [name=" + name + ", age=" + age + "]";
	}

}














Properties(将Map集合以流来操作)
属性集合类(该类继承自Hashtable

1.概述:

该类表示一个属性集合类(该类表示了一个持久的属性集)。

Properties可保存在流中或从流中加载。该类继承自Hashtable,属于Map集合。


2.特点:

属性列表中每个键及其对应值都是一个字符串!!!

2.构造方法:

public Properties() 创建一个空属性列表


3.Properties 中的遍历和添加元素的功能:

(1)public Object setProperty(String key,String value) 给当前的属性列表中添加元素

注:相当于Map集合的 put() 方法

   (2)public Set stringPropertyNames() 获取当前属性列表中所有的键的集合,键值都是String类型

注:相当于Map集合的 keySet() 方法

   (3)public String getProperty(String key) 用指定的键在此属性列表中搜索属性值

注:相当于Map集合的 getKey() 方法


4.Properties 可保存在流中或从流中加载 的方法:

(1)读取数据:将文件中的数据加载到属性集合中: public void load(Reader reader)

(2)写入数据:将属性集合中的数据保存到文件中: public void store(Writer writer,String comments)

注:第二个参数comments,相当于对当前属性列表的描述



例1:给Properties属性集中放入元素并遍历

import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

	public static void main(String[] args) {

		// 创建属性集合类对象
		// 默认泛型String:Properties prop = new Properties() ;
		Properties prop = new Properties();

		// 添加元素public Object setProperty(String key,String value)
		// 或采用Map集合中的放置元素方法:put()
		prop.setProperty("伊卡尔迪", "30");
		prop.setProperty("佩里西奇", "25");
		prop.setProperty("坎德雷瓦", "40");
		prop.setProperty("汉达诺维奇", "35");

		// 遍历集合
		// 获取所有的键的集合:public Set stringPropertyNames()
		// 或采用Map集合中的遍历方法:keySet()
		Set keySet = prop.stringPropertyNames();
		// 增强for遍历
		for (String key : keySet) {
			// 或采用Map集合中的获取值方法:get(key)
			String value = prop.getProperty(key);
			System.out.println(key + "=" + value);
		}
	}
}


【我的Java笔记】IO流_IO流中的其他类_第4张图片


例2:使用属性集合Properties实现流中数据的写入和读取load(Reader reader)和store(Writer writer,String comments)方法

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo1 {
public static void main(String[] args) throws IOException {
		
		//myStore();
		myLoad() ;
	}
	
	//读取数据
	private static void myLoad() throws IOException {
		//创建属性集合类对象
		Properties prop = new Properties() ;
		
		//创建字符输入流对象
		FileReader fr = new FileReader("PropertiesTest.txt") ;
		
		//调用方法读取数据到Properties集合:public void load(Reader reader)
		prop.load(fr) ;
		
		//释放资源
		fr.close() ;
		
		//显示输出
		Set keySet = prop.stringPropertyNames();
		for (String key : keySet) {
			String value = prop.getProperty(key);
			System.out.println(key + "=" + value);
		}
	}
	
	//写入数据
	private static void myStore() throws IOException {
		//创建属性集合类对象
		Properties prop = new Properties();
		
		//给属性集合中添加数据
		prop.setProperty("伊卡尔迪", "30") ;
		prop.setProperty("佩里西奇", "40") ;
		prop.setProperty("坎德雷瓦", "50") ;
		
		//将属性列表中的数据保存到文件中:public void store(Writer writer,String comments)
		//创建字符输出流
		FileWriter fw = new FileWriter("PropertiesTest.txt") ;
		//调用方法将Properties中的数据写入文件
		prop.store(fw, "names content") ;
		
		//释放资源
		fw.close() ;
	}
}





练习:有一个文本文件test.txt,知道数据是键值对形式保存的,但是不知道内容是什么。请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”

/*
 * 分析:
 * 		1)将test.txt文件中的内容加载到属性集合类中
 *		2)遍历属性列表:
 *			获取所有的键的集合:stringPropertyNames()
 *			判断:如果"lisi"和键中key值相等,就修改值:setProperty(key,"100") 
 *		3)重新将属性集合中的数据写到test.txt中
 * */

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class PropertiesTest {

	public static void main(String[] args) throws IOException {
		// 创建属性集合类对象
		Properties prop = new Properties();

		// 创建字符输入流对象
		FileReader fr = new FileReader("test.txt");
		// 加载到属性集合中
		prop.load(fr);

		// 关闭流资源
		fr.close();

		// 遍历属性列表
		Set keySet = prop.stringPropertyNames();
		for (String key : keySet) {
			// 判断
			if ("lisi".equals(key)) {
				// 修改
				prop.setProperty(key, "100");
			}
		}

		// 创建字符输出流对象
		FileWriter fw = new FileWriter("test.txt");
		// 调用功能
		prop.store(fw, "content");

		// 释放资源
		fw.close();
	}
}


【我的Java笔记】IO流_IO流中的其他类_第5张图片










你可能感兴趣的:(JavaSE)