切割流和合并流:
切割流:一个源流对应多目的流 指定大小输出到不同的流中
合并流:多个源流对应一个目的流 先把源流合并起来,再输出到目的流 SequenceInputStream
对象的序列化:对象的持久化。需要对象的类实现 Serializable接口,并且定义固定的
UID:public static final long serialVersionUID = 42L;
对象中的成员(成员变量和成员函数)都是计算UID的部分,如果改变成员的值,会生成新的
UID,不能再用流读取硬盘上的对象。如果需要让指定成员不被序列化,可以用关键字 transient
修饰。
注意:静态是不能序列化的。
管道流: PipedInputStream PipedOutputStream 与多线程相关
RandomAccessFile:该类直接继承自Object,但是是IO包中的成员,因为具备读和写的功能。
内部封装了一个数组,通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。能完成读写的原理是内部封装了读取流和写入流。
构造函数中只能接受文件,并且有指定操作模式。只读:"r" ,读写:"rw".
如果模式为只读,不会创建文件,如果该文件不存在,则会发生异常
如果模式为读写,如果该对象的构造函数要操作的文件不存在,会自动创建。如果存在则不覆盖。
可以通过设置指针偏移随机访问数组中的元素。
seek(int offset): 调整对象的指针,按照指针位置读取写入,如果指针位置已有内容,写入内容会覆盖原来内容。
skipBytes(int number):跳过指定字节数
DataInputStream DataOutputStream:基本数据类型流对象
可以对基本数据类型进行流的操作。
ByteArrayInputStream:在构造的时候,需要接受数据源,且是一个数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
因为两个流对象都操作的数组,并没有系统资源,不用进行close关闭,就算关闭资源,其方法还是可以调用。
用流的读写思想来操作数组。
流规律:
源设备:键盘(System.in) 硬盘(FileStream) 内存(ArrayStream)
目的设备:控制台(System.out) 硬盘(FileStream) 内存(ArrayStream)
切割流:一个源流对应多目的流 指定大小输出到不同的流中
合并流:多个源流对应一个目的流 先把源流合并起来,再输出到目的流 SequenceInputStream
import java.io.*;
import java.util.*;
class SplitAndSequence
{
static int count = 0;
public static void main(String[] args) throws IOException
{
splitFile();
sequence();
}
public static void sequence()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int x=1; x<=count; x++)
{
al.add(new FileInputStream("part\\"+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("part\\tanfu.mp3");
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("tanfu.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len =0;
//int count =1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("part\\"+(++count)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
对象的序列化:对象的持久化。需要对象的类实现 Serializable接口,并且定义固定的
UID:public static final long serialVersionUID = 42L;
对象中的成员(成员变量和成员函数)都是计算UID的部分,如果改变成员的值,会生成新的
UID,不能再用流读取硬盘上的对象。如果需要让指定成员不被序列化,可以用关键字 transient
修饰。
注意:静态是不能序列化的。
import java.io.*;
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();
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",40));
oos.close();
}
}
class Person implements Serializable
{
public static final long serialVersionUID = 42L;
String name;
int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String toString()
{
return name+".."+age;
}
}
管道流: 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];
int len = in.read(buf);
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
{
out.write("piped is coming".getBytes());
out.close();
}
catch (IOException 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);
new Thread(new Read(in)).start();
new Thread(new Write(out)).start();
}
}
RandomAccessFile:该类直接继承自Object,但是是IO包中的成员,因为具备读和写的功能。
内部封装了一个数组,通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。能完成读写的原理是内部封装了读取流和写入流。
构造函数中只能接受文件,并且有指定操作模式。只读:"r" ,读写:"rw".
如果模式为只读,不会创建文件,如果该文件不存在,则会发生异常
如果模式为读写,如果该对象的构造函数要操作的文件不存在,会自动创建。如果存在则不覆盖。
可以通过设置指针偏移随机访问数组中的元素。
seek(int offset): 调整对象的指针,按照指针位置读取写入,如果指针位置已有内容,写入内容会覆盖原来内容。
skipBytes(int number):跳过指定字节数
DataInputStream DataOutputStream:基本数据类型流对象
可以对基本数据类型进行流的操作。
ByteArrayInputStream:在构造的时候,需要接受数据源,且是一个数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
因为两个流对象都操作的数组,并没有系统资源,不用进行close关闭,就算关闭资源,其方法还是可以调用。
用流的读写思想来操作数组。
流规律:
源设备:键盘(System.in) 硬盘(FileStream) 内存(ArrayStream)
目的设备:控制台(System.out) 硬盘(FileStream) 内存(ArrayStream)