`
jiao13953900900
  • 浏览: 32225 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

黑马程序员-IO_其他常用流对象

    博客分类:
  • java
阅读更多

 

---------------------- android培训java培训、期待与您交流! ----------------------

 

 

其他常用流对象

 

 

打印流:

该流提供了打印方法,可以将各种数据类型的数据都原样打印。

 

字节打印流:

PrintStream

构造函数可以接收的参数类型:

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

 

字符打印流:

PrintWriter

构造函数可以接收的参数类型:

1,file对象。File

2,字符串路径。String

3,字节输出流。OutputStream

4,字符输出流,Writer。

 

打印流 PrintWriter与PrintStream 可以直接操作输入流和文件。

 

import java.io.*;

class  PrintStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));

		PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());
			//out.flush();
		}

		out.close();
		bufr.close();

	}	
}

 

序列流

SequenceInputStream

对多个流进行合并。

 

import java.io.*;
import java.util.*;
class SequenceDemo 
{
	public static void main(String[] args) throws IOException
	{

		Vector<FileInputStream> v = new Vector<FileInputStream>();

		
		v.add(new FileInputStream("c:\\1.txt"));
		v.add(new FileInputStream("c:\\2.txt"));
		v.add(new FileInputStream("c:\\3.txt"));

		Enumeration<FileInputStream> en = v.elements();//建立枚举

		SequenceInputStream sis = new SequenceInputStream(en);//创建SequenceInputStream对象

		FileOutputStream fos = new FileOutputStream("c:\\4.txt");

		byte[] buf = new byte[1024];

		int len =0;
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}

		fos.close();
		sis.close();
	}
}

 

对文件进行分割并合并。

 

import java.io.*;
import java.util.*;

class SplitFile 
{
	public static void main(String[] args) throws IOException
	{
		//splitFile();
		merge();
	}

	//对流文件进行合并
	public static void merge()throws IOException
	{
		//因为需要对两个以上的流进行合并,所以创建Lise集合,用来存放流对象。
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
		//遍历将所有的碎片文件存入集合
		for(int x=1; x<=3; x++)
		{
			al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));//根据不同名字创建流对象
		}
		//创建迭代器对象
		final Iterator<FileInputStream> it = al.iterator();
		//创建一个枚举,覆盖枚举中的取出方法。内部调用迭代的方法
		Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
		{
			public boolean hasMoreElements()
			{
				return it.hasNext();
			}
			public FileInputStream nextElement()
			{
				return it.next();
			}
		};
		//将枚举传入SequenceInputStream作为参数。
		SequenceInputStream sis = new SequenceInputStream(en);

		//建立目标对象
		FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");

		byte[] buf = new byte[1024];

		int len = 0;
		//循环对SequenceInputStream流中的数据进行取出,知道取出到最后一个流的末尾结束
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}

		fos.close();
		sis.close();
	}

	public static void splitFile()throws IOException
	{
		FileInputStream fis =  new FileInputStream("c:\\1.bmp");

		FileOutputStream fos = null;


		byte[] buf = new byte[1024*1024];//缓冲区

		int len = 0;
		int count = 1;
		while((len=fis.read(buf))!=-1)
		{
			//没循环一次,就将取出的部分存储到一个文件中,实现文件的分割。
			fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}
		
		fis.close();
		
	}
}

 

 

操作对象的流对象

ObjectInputStream与ObjectOutputStream

通过流的方法,将对象存到硬盘上,--对象的持久化存储(序列化)。

在对象中提供了很多可以直接操作对象和操作基本数据类型的方法。

 

writeObject(Object obj)  将指定的对象写入 ObjectOutputStream。

readObject()   从 ObjectInputStream 读取对象。

 

一般将对象存储到扩展名为对象的文件中,如:obj.Object。

注意:被操作的对象需要实现Serializable (标记接口);

2.类中的静态属性是无法进行序列化的。

3.如果非静态属性也不想被序列化,可以加上transient关键字进行修饰。

 

import java.io.*;

class ObjectStreamDemo 
{
	public static void main(String[] args) throws Exception
	{
		//writeObj();
		readObj();
	}
	public static void readObj()throws Exception
	{
		//建立Object读取流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

		Person p = (Person)ois.readObject();//该方法可以读出流中的对象。如果不涉及对象的特有方法,可以不进行强转。

		System.out.println(p);//通过打印,调用对象的toString方法,可以看到对象的信息。
		ois.close();
	}

	public static void writeObj()throws IOException
	{
		//建立Object存储流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));

		oos.writeObject(new Person("lisi0",399,"kr"));//将对象存储到流中,然后存储到文件中。

		oos.close();
	}
}

 

 要求被序列化的对象必须实现Serializable接口,该接口中没有方法,是一个标记接口,实现该接口就表示该类对象可以被序列化。

 

import java.io.*;
class Person implements Serializable
{
	//可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:
	//如果不进行自己指定,jvm会根据类中的成员进行自动指定一个uid。
	public static final long serialVersionUID = 42L;

	private String name;
	transient int age;如果非静态属性也不想被序列化,可以加上transient关键字进行修饰。
	static String country = "cn";
	Person(String name,int age,String country)
	{
		this.name = name;
		this.age = age;
		this.country = country;
	}
	public String toString()
	{
		return name+":"+age+":"+country;
	}
}

 

 

管道流对象:

输入输出可以直接进行相连,通过结合多线程使用,是一个涉及多线程的IO流对象。

涉及多线程的io流对象

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);

			System.out.println(s);

			in.close();

		}
		catch (IOException e)
		{
			throw new RuntimeException("管道读取流失败");
		}
	}
}

 

 

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 lai la".getBytes());//只有写入倒流中以后read方法才能够读取到。
			out.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException("管道输出流失败");
		}
	}
}

 

 

import java.io.*;
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包中成员。因为它具备读和写功能。

内部封装了一个数组,而且通过指针对数组的元素进行操作。

可以通过getFilePointer获取指针位置,

同时可以通过seek改变指针的位置。

 

 

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

 

通过构造函数可以看出,该类只能操作文件。

而且操作文件还有模式:只读r,,读写rw等。

 

如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。

如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

 

可以将数据分割成多段进行同时操作,多线程的下载就是根据这种思想实现的。

 

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

		System.out.println(Integer.toBinaryString(258));

	}
	public static void readFile()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
		
		//调整对象中指针。可以向前,也可以向后,比较常用。
		//raf.seek(8*1);

		//跳过指定的字节数,只能向后跳。
		raf.skipBytes(8);

		byte[] buf = new byte[4];

		raf.read(buf);

		String name = new String(buf);

		int age = raf.readInt();
		System.out.println("name="+name);
		System.out.println("age="+age);

		raf.close();


	}
	//通过seek方法改变指针位置,进行调整指定位置读取,存储的数据必须的有规律排列的。
	public static void writeFile_2()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
		raf.seek(8*0);//调整到指定字节进行读取、
		raf.write("周期".getBytes());
		raf.writeInt(103);

		raf.close();
	}
	//连续读取
	public static void writeFile()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");

		raf.write("李四".getBytes());
		raf.writeInt(97);
		raf.write("王五".getBytes());
		raf.writeInt(99);

		raf.close();
	}
}

 

 

DataInputStream与DataOutputStream

 

可以用于操作基本数据类型的数据的流对象。

基本数据类型和流相结合

 

import java.io.*;
class DataStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		//writeData();
		//readData();

		//writeUTFDemo();
		//使用流的方式指定编码表
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");

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

		readUTFDemo();

	}
	//演示使用指定的utf修改版进行读写
	public static void readUTFDemo()throws IOException
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));

		String s = dis.readUTF();

		System.out.println(s);
		dis.close();
	}


	//演示使用指定的utf修改版进行读写
	public static void writeUTFDemo()throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));

		dos.writeUTF("你好");//写入中文

		dos.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();

		System.out.println("num="+num);
		System.out.println("b="+b);
		System.out.println("d="+d);

		dis.close();
	}
	public static void writeData()throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

		dos.writeInt(234);//写入int类型的值
		dos.writeBoolean(true);//写入boolean类型的值
		dos.writeDouble(9887.543);//写入double类型的值

		dos.close();

		ObjectOutputStream oos = null;
		oos.writeObject(new O());

		
	}
}

 

 

内存为源和目的的操作

操作字节数组

ByteArrayInputStream与ByteArrayOutputStream

操作字符数组

CharArrayReader与CharArrayWrite

操作字符串

StringReader 与 StringWriter

 

用于操作字节数组的流对象。

 

ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。

 

ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。

这就是数据目的地。

 

因为这两个流对象都操作的数组,并没有使用系统资源。

所以,不用进行close关闭。

 

在流操作规律讲解时:

 

源设备,

键盘 System.in,硬盘 FileStream,内存 ArrayStream。

目的设备:

控制台 System.out,硬盘FileStream,内存 ArrayStream。

 

 

用流的读写思想来操作数据。

 

import java.io.*;
class ByteArrayStream 
{
	public static void main(String[] args) 
	{
		//数据源。
		ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());

		//数据目的
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		int by = 0;

		while((by=bis.read())!=-1)
		{
			bos.write(by);
		}
		System.out.println(bos.size());
		System.out.println(bos.toString());

	//	bos.writeTo(new FileOutputStream("a.txt"));将数组中的数据写入到文件中

	}
}

 

 

 

 

---------------------- android培训java培训、期待与您交流! ----------------------

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics