java--io流-打印流,序列流,操作对象,管道流,RandomAccessFile,操作字节数组

打印流:

该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:
PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。

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);
		//PrintWriter out = new PrintWriter(System.out,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 
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。  
可以将多个流对象合并成一个流对象。
构造方法:
SequenceInputStream(InputStream s1, InputStream s2) ;通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
SequenceInputStream(Enumeration<? extends InputStream> e) ;通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。

将1.txt,2.txt,3.txt合并成4.txt。

import java.util.*;
import java.io.*;
class  Test
{
	public static void main(String[] args) throws IOException
	{
		Vector<FileInputStream> v=new Vector<FileInputStream>();
		v.add(new FileInputStream("1.txt"));
		v.add(new FileInputStream("2.txt"));
		v.add(new FileInputStream("3.txt"));
		Enumeration<FileInputStream> e=v.elements();
		SequenceInputStream sis=new SequenceInputStream(e);
			
		FileOutputStream fos=new FileOutputStream("4.txt");
			
		byte[] b=new byte[1024];
		int len;
		while((len=sis.read(b))!=-1)
		{
			fos.write(b,0,len);
		}
		sis.close();
		fos.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
	{
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();//ArrayList比Vector效率高
		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 sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
		byte[] buf = new byte[1024];
		int len = 0;
		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
被操作的对象需要实现Serializable(标记接口);

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。

import java.util.*;
import java.io.*;
class  Test
{
	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();
		System.out.println(p);
		ois.close();
	}
	public static void writeObj()throws IOException
	{
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
		oos.writeObject(new Person("lisi",39,"dy"));
		oos.close();
	}
}
class Person implements Serializable
{
	
	public static final long serialVersionUID = 42L;//给类固定一个标识

	private String name;
	transient int age;//使非静态的变量也不可被序列化。
	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;
	}
}

管道流:

PipedInputStream和PipedOutputStream
输入输出可以直接连接,通过结合线程使用

管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 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);
			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());
			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包中成员。因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。应用在多线程中。
完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

Java API:此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

方法:
skipBytes();//跳过指定的字节数,只能往后跳。等

import java.io.*;
class  Test
{
	public static void main(String[] args) throws Exception
	{
		writeFile();
		writeFile_2();
		readFile();
	}
	public static void readFile()throws IOException //读取打印信息
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
		for(int i=0;i<11;i++)
		{
			raf.seek(8*i);
			byte[] b=new byte[4];
			raf.read(b);
			String name=new String(b);
			int age=raf.readInt();
			System.out.println("name="+name+",age="+age);
		}
		raf.close();
	}
	public static void writeFile_2()throws IOException //写入信息2
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
		raf.seek(8*10);//可以随便写位置,随便覆盖位置上的内容。
		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(258);
		raf.close();
	}
}

DataInputStreamDataOutputStream

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

oid writeUTF(String str) 以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。

import java.io.*;
class  Test
{
	public static void main(String[] args) throws Exception
	{
		writeFile();
		read();
		Demo();
	}
	public static void Demo()throws IOException
	{
		DataOutputStream dos=new DataOutputStream(new FileOutputStream("UTFdemo.txt"));
		dos.writeUTF("发货个人规划的分割肉哥哥的非农赶紧的搜狗奇偶");
		dos.close();
		DataInputStream dis=new DataInputStream(new FileInputStream("UTFdemo.txt"));
		System.out.println(dis.readUTF());
		dis.close();
	}
	public static void read()throws IOException
	{
		DataInputStream dis=new DataInputStream(new FileInputStream("DataOutputStream.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 writeFile()throws IOException //写入信息
	{
		DataOutputStream dos=new DataOutputStream(new FileOutputStream("DataOutputStream.txt"));
		dos.writeInt(2134);
		dos.writeBoolean(true);
		dos.writeDouble(3253.453);
		dos.close();
	}
}
操作字节数组
ByteArrayInputStream :在构造的时候,需要接收数据源,而且数据源是一个字节数组。ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪  read 方法要提供的下一个字节。关闭  ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何  IOException
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了 可变长度的字节数组。这就是数据目的地。此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用  toByteArray() 和  toString() 获取数据。关闭  ByteArrayOutputStream无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何  IOException

因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
在流操作规律讲解时:
源设备,
键盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
用流的读写思想来操作数据。

import java.io.*;
class  Test
{
	public static void main(String[] args) throws Exception
	{
		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"));
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值