黑马程序员_java基础篇操作对象ObjectStream,管道流,随机存储Day5(下)

 ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! -----------


                           黑马程序员_java基础篇操作对象ObjectStream,管道流,随机存储Day5(下)


在了解怎样操作对象之前,我们先解释一下我们经常忽视的JVM中的堆区, 栈区, 方法区.

 

堆区: 
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令) 
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 
栈区: 
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。 
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。 
方法区: 
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。 
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。 

 

当我们了解了这些时,我们就可以继续我们的流操作了

 

(一)对于操作对象的流ObjectInputStream

 

对象是存在堆中的,堆的对象会封装一些数据,当我们用ObjectInputStream

去操作对象时,如下:

Peoson p=new Peoson("ouyang","2","hk");

ObjectOutputStream obj=newObjectOutputStream(new FileOutputStream("d:/ouyang.txt"));

 obj.writeObject(p);

一定要将操作对象序列化,为什么要序列化?这样保证操作对象的唯一性, 序列化是什么?

我们可以看一些代码:

public class Peoson  implements  Serializable就是一个接口,这个接口是没有方法的,通常我们称这样的接口为标记接口.

public static void w() 
	{
         Peoson p=new Peoson("ouyang","2","hk");
		
         try{
		ObjectOutputStream obj=new ObjectOutputStream(new FileOutputStream("d:/ouyang.txt"));
		
	    obj.writeObject(p);
	    
	    obj.close();
         }catch(Exception e)
         {
        	 e.printStackTrace();
         }
		
	}
	
	public static void r() throws FileNotFoundException, IOException, ClassNotFoundException
	{
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/ouyang.txt"));
		Peoson p=(Peoson)ois.readObject();
		System.out.println(p.getAge()+p.getName()+p.country);
		
	}

由于我们使用了序列化对象,那么如果我们在编译执行以后又修改了原来的类,我们重新读取时,可能会出错,由于序列化的ID变了.所以如果我们想一直让此程序为固定id,我们可以用

public static final long serialVersionUID=42L;定义ID.

   

这有两个方法,读对象,写对象.注意在Peoson类中的静态变量是不能改写的,当我们试着改写peoson中定义的Static a=1时,我们怎么修改还是为1.如果这个数不是静态变量,我们怎么使其不备修改妮?这样定义 transientint a=1声明序列化的时候不被存储.静态变量是在方法区中的,对象流只能操作堆中的数据。


(二)管道流PipedInputStream,PipedOutputStream

 

在IO流中涉及到多线程的是管道流,为什么说管道流涉及到多线程呢?因为单线程可能发生死锁,如果一个线程将不知道分配资源给谁,如果给读取PipedInputStream,但没有写入,读取是空的,相反同理。

 

代码如下:

package Heima;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class Pip {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		PipedInputStream pis=new PipedInputStream();
		PipedOutputStream pos=new PipedOutputStream();
		pis.connect(pos);
		Read r=new Read(pis);
		Write w=new Write(pos);
	    Thread tr=new Thread(r);
	    Thread tw=new Thread(w);
	    tr.start();
	    tw.start();
	}


}

class Read implements Runnable
{

	private PipedInputStream pis;
	Read(PipedInputStream pis)
	{
		this.pis=pis;
	}
	public void run() {
		// TODO Auto-generated method stub
		
		
		try {
			byte[] b=new  byte[1024];
			int len=pis.read(b);
			String str=new String(b,0,len);
			System.out.println(str);
			pis.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	
}

class Write implements Runnable
{
	private PipedOutputStream pos;
	
	 public Write(PipedOutputStream pos)
	 {
		this.pos=pos;
	 }
	 
	 public void run() {
		// TODO Auto-generated method stub
		try
		{
			System.out.println("成功");
			Thread.sleep(2000);
			
		 pos.write("sssss".getBytes());
		 pos.close();
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
  	
	

 

 

(三)随机访问类RandomAccessFile

 

这是一个神奇的类,直接继承Object,既能读又能写,同时想读哪里指哪里。

注意里面的seek,skipBytes

我们看代码理解的比较清楚:

package Heima;

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

public class RamdomAccecc {

	/**
	 * 
	 * 他不是IO体系中的,
	 * 但是直接继承Object,但是他是IO包的成员,因为他能完成读写
	 * 可以通过getFilePointer得到指针的位置,可以通过seek改变指针位置
	 * 内部封装了字节输入流,输出流
	 * 通过他的构造函数,看出,他只能操作文件,而且操作文件还有模式
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		
		RandomAccessFile raf=new RandomAccessFile("d:/1.txt","rw");
		byte[] b=new byte[4];
		
		raf.write("欧阳".getBytes());
		raf.writeInt(23);
		
		raf.write("整的".getBytes());
		raf.writeInt(24);
		raf.close();
		
		RandomAccessFile raf1=new RandomAccessFile("d:/1.txt","rw");
	
		
	//	raf.write("欧阳".getBytes());
		//raf.writeInt(23);
		//raf.close();
		//raf1.seek(8);//移动指针
		raf1.skipBytes(8);//这个只能往后移,但是seek想移哪里,移哪里。
		
		  raf1.read(b);
		  //raf1.readInt();
		  System.out.println(new String(b,0,4)+raf1.readInt());
		  
		  
		  
		
	}

}



 ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! -----------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值