小结

操作对象
ObjectInputStream与ObjectOutputStream
可直接操作对象的流。

对象本身存在于堆内存中,当程序运行完时,内存被释放,对象也不存在了。
可以使用流将对象存于硬盘上。




import java.io.*;

class Person implements Serializable
{
	public static final long serialVersionUID = 36L;
	//给定id,定义固定标识,使区别化方便。

	private String name;
	transient int age; //加上关键字transient成员同样不能被序列化,而保证
		//成员的值在堆内存中存在而不在文本中存在
	static String country = "cn";//静态是不能被序列化的。所以打印的还是cn

	Person(String name,int age,String country)
	{
		this.name = name;
		this.age = age;
		this.country = country;
	}

	public String toString()
	{
		return name+"::"+age+"::"+country;
	}
}



import java.io.*;

/*
使Person继承Serializable,使其序列化。ObjectStreamDemo中的Person类对象的序列号是Java根
据Person中的成员获取而来的。若将Person类中的成员改变,对应的对象的序列号会改变继而发生异常。
但如果自己定义一个id,既可避免。*/

class ObjectStreamDemo
{
	public static void main(String[] args) throws Exception
	{
		writeObj();
		//readObj();
	}

	public static void readObj() throws Exception
	{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

		Person p = (Person)ois.readObject();
		//编译时抛出ClassNotFoundException异常,将跑出IOE改为E

		System.out.println(p);

		ois.close();
	}

	public static void writeObj() throws IOException
	{
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
		//讲一个对象写入文件中

		//对象new Person("lisi",23);应存在于内存中,而现在直接写到硬盘上了。
		oos.writeObject(new Person("lisi02",43,"UK"));//lisi,43,cn 
			//类Person中country是static,静态不能被序列化。
		

		oos.close();
	}
}






/*
管道流
PipedInputStream和PipedOutputStream
输入输出可以直接进行连接,通过结合线程使用。
*/


import java.io.*;

class  Read implements Runnable
{
	private PipedInputStream in;
	Read(PipedInputStream in)
	{
		this.in = in;
	}
	public void run()
	{
		try
		{
			byte[] buf = new byte[1024];
			
			System.out.println("读取前。。没有数据阻塞");
			int len = in.read(buf);//read()方法没有读到数据都会阻塞
			System.out.println("读到数据。。阻塞结束");
			
			String s = new String(buf,0,len);
			//此处读到上面PipedInputStream in中的数据
			
			System.out.println(s);
			
			in.close();
		}
		catch(IOException e)
		{
			throw new RuntimeException("管道读取流失败");
		}
	}
}

class Write implements Runnable
class Write implements Runnable
{
	private PipedOutputStream out;
	Write(PipedOutputStream out)
	{
		this.out = out;
	}
	public void run()
	{
		try
		{
			System.out.println("开始写入数据,等待6秒");
			Thread.sleep(6000);
			out.write("piped is coming".getBytes());
			//此处数据写到上面Read—>Read的PipedInputStream in中
			out.close();
		}
		catch(Exception e)
		{
			throw new RuntimeException("管道输出流失败");
		}
	}
}

class PipedStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		PipedInputStream in = new PipedInputStream();
		PipedOutputStream out = new PipedOutputStream();
		in.connect(out);
		
		Read r = new Read(in);
		Write w = new Write(out);
		new Thread(r).start();
		new Thread(w).start();
	}
}



/*
RandomAccessFile
随机访问文件。此类的实例支持对随机访问文件的读取和写入。

该类不算是IO体系中的子类,而是直接继承Object。
但其仍是IO包中的成员,因它具备读和写的功能。
其内部也封装了一个数组,而且通过只针对数组的元素进行操作。
可以通过getFilePoint获取指针位置,
同时可以通过seek改变指针位置。

其实完成读写的原理是其内部封装了字节输入流和输出流。

通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读 r;读写 rw等

如果模式为只读 r,不会创建文件,会去读取一个已存在的文件,若文件不存在,则会出现异常。
如果模式为rw,而且该对象的构造函数要操作的文件不存在,会自动创建文件,若存在也不会覆盖。
*/






ort java.io.*;

class RandomAccessFileDemo
{
	public static void main(String[] args) throws IOException 
	{
		//writeFile();
		//readFile();
		writeFile_2();
	}

	public static void readFile() throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
		//文件中的数据在数组中,可以通过调整指针来取出数据。

		//调整对象中的指针
		//raf.seek(8*0);//指向李四
		//raf.seek(8*1); //指向王五

		//跳过指定字节数,但不能往回跳
		raf.skipBytes(8);

		byte[] buf = new byte[4];//用于装人名,人名4个字节

		raf.read(buf);//将ran.txt读到buf中

		String name = new String(buf);

		int age =raf.readInt(); //readInt();从文件读取一个有符号的32位整数
		
		System.out.println("name="+name);
		System.out.println("age="+age);

		raf.close();
	}
	
	public static void writeFile() throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");//不会覆盖文件
		//getBytes(); 使用平台默认的字符集将String编码为byte序列并存到一个新的byte[]中
		raf.write("李四".getBytes());
		//只写出int类型最低的8位(二进制).
		//当数据达到一定时会发生数据丢失,256——1 00000000。
		//一个int型对应4个字节,一个字节对应8位

		raf.writeInt(97);//按四个字节将 int 写入该文件,先写高字节
		raf.write("王五".getBytes());
		raf.writeInt(100);
		
		raf.close();
	}

	public static void writeFile_2() throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
			//不会覆盖文件ran.txt
		raf.seek(8*3);//会在王五后面留一个位置.若是8*0,会将李四替换
		raf.write("周期".getBytes());
		raf.writeInt(103);

		raf.close();
	}
}






IO包中的其他类

操作基本数据类型
	DataInputStream和DataOutputStream

操作字节数组
	ByteArrayInputStream和ByteArrayOutputStream
	可直接操作字节数组中数据的流对象

操作字符数组
	CharArrayReader和CharArrayWrite

操作字符串
	StringReader和StringWriter






/*
DataInputStream和DataOutputStream
可以用于操作基本数据类型的数据的流对象。
*/

import java.io.*;

class DataStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		//writeData();
		//readData();
		//writeUTFDemo();
		readUTFDemo();
	}

	public static void writeUTFDemo() throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));

		dos.writeUTF("你好");

		dos.close();


		OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("utf.txt"),"utf-8");

		osw1.write("你好");
		osw1.close();


		OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

		osw2.write("你好");
		osw2.close();
	}

	public static void readUTFDemo() throws IOException //只能用对应的方法(表)读取
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("utfdate.txt"));

		String s = dis.readUTF();

		sop(s);

		dis.close();
	}

	public static void readData() throws IOException
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));

		//此处是按位读取数据的
		int num = dis.readInt();
		boolean b = dis.readBoolean();
		double d = dis.readDouble();

		sop("num:"+num);
		sop("b:"+b);
		sop("d:"+d);

		dis.close();
	}

	public static void writeData() throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
		//FileOutputStream 流

		dos.writeInt(234);//4个字节
		dos.writeBoolean(true);//1个字节
		dos.writeDouble(9887.5432);//8个字节

		dos.close();
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}







字符编码
字符流的出现是为了方便操作字符数据,原因是字符流内部加入了编码表。
更重要的是加入了编码转换。

字节和字符之间的转换需要通过两个对象——InputStream、OutputStream。这
两个的对象中是加入了编码表的流对象。
还有PrintStream和printWriter可以加入编码表。但只能打印不能读取。




import java.io.*;

class EncodeStream 
{
	public static void main(String[] args) throws IOException
	{
		//writeText();
		readText();
	}

	public static void readText() throws IOException
	{
		InputStreamReader isr = new InputStreamReader(new FileInputStream("GBK2.txt"),"GBK");

		char[] buf = new char[10];

		int len = isr.read(buf);

		String str = new String(buf,0,len);

		sop(str);

		isr.close();
	}

	public static void writeText() throws IOException
	{
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("GBK2.txt"));
		
		osw.write("你好");

		osw.close();
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}







import java.util.*;

/*
编码:字符串变成字节数组
String -->byte[]; str.getBytes(CharsetName); 按指定字符集

解码:字节数组变成字符串
byte[] -->String; new String(byte[],CharsetName);
*/

class EncodeDemo 
{
	public static void main(String[] args) throws Exception
	{
		//method_1();
		method_2();
	}

	public static void method_1() throws Exception
	{
		String s = "你好";

		//byte[] b1 = s.getBytes();//[-60,-29,-70,-61]

		byte[] b1 = s.getBytes("GBK");// 会抛出不支持编码异常
			//[-60,-29,-70,-61]  默认编码即GBK

		String s1 = new String(b1);

		System.out.println("s1="+s1);

		System.out.println("b1:"+Arrays.toString(b1));
	}

	public static void method_2() throws Exception
	{
		/*
		你好——(编码)GBK——[-60,-29,-70,-61]——(解码)ISO8859-1——????-
		-(编码)ISO8859-1——[-60,-29,-70,-61]——(解码)GBK——你好
		*/

		String s = "你好";

		byte[] b1 = s.getBytes("GBK");//编码

		sop("b1:"+Arrays.toString(b1));

		String s1 = new String(b1,"ISO8859-1");//解码

		sop("s1:"+s1);

		byte[] b2 = s1.getBytes("ISO8859-1");

		sop("b2:"+Arrays.toString(b2));

		String s2 = new String(b2,"GBK");

		sop("s2:"+s2);
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);	
	}
}








//加入编码表后是会报异常的

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

		String s = "联通";

		byte[] by = s.getBytes("gbk");

		for(byte b:by)
		{
			System.out.println(Integer.toBinaryString(b&255));
		}
	}
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值