ObjectInputStream ObjectOutputStream
静态不能被序列化
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("d:\\person.object"));
System.out.println(ois.available());
Person p=(Person) ois.readObject();
System.out.println(ois.available());
ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj() throws IOException
{
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("d:\\person.object"));
oos.writeObject(new Person("lisi",39));
oos.close();
}
}
import java.io.*;
class Person implements Serializable
{
String name;
int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String toString()
{
return name+":"+age;
}
}
RandomAccessFile
随机访问文件,自身具备读写的方法。
import java.io.*;
/*
该类不是算是IO体系中子类
而是直接继承自Object
但是它是IO包中成员。因为它具备读和写功能
内部封装了一个数组,而且通过指针对数组的元素进行操作
可以通过getFilePointer获取指针位置
同时可以通过 seek 改变指针的位置
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读 r,读写 rw等.
而且该对象的构造函数要操作的文件不存在,会自动创建。
如果存在则不会覆盖。
如果模式为只读 r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式rw 操作的文件不存在,会自动创建,如果存在则不会覆盖。
*/
class RandomAccessFileDemo
{
public static void main(String[] args) throws IOException
{
//writeFile_2();
//writeFile();
readFile();
}
public static void writeFile_2() throws IOException //在指定位置写入内容
{
RandomAccessFile raf = new RandomAccessFile("d:\\ran.txt","rw");
raf.seek(8*3);
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void readFile() throws IOException//读取指定位置内容
{
byte[] buf = new byte[4];
RandomAccessFile raf = new RandomAccessFile("d:\\ran.txt","r");
//调整对象中指针
//raf.seek(8);
//跳过指定的字节数
raf.skipBytes(8);
int len=raf.read(buf);
int age=raf.readInt();
System.out.println(new String(buf));
System.out.println("age="+age);
}
public static void writeFile() throws IOException//写入文件内容
{
RandomAccessFile raf = new RandomAccessFile("d:\\ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(258);
raf.write("张三".getBytes());
raf.writeInt(28);
raf.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];
int len = in.read(buf);
String s=new String(buf,0,len);
System.out.println(s);
in.close();
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("-------------------");
throw new RuntimeException("管道读取失败");
}
}
}
class Write implements Runnable{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out = out;
}
public void run()
{
try
{
out.write("piped lai la".getBytes());
out.close();
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("-------------------");
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();
}
}
DataStream
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args) throws IOException
{
//writeData();
readData();
}
public static void writeUTFDemo()
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("utfdate.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void readData() throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("d:\\data.txt"));
int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();
System.out.println(num+","+b+","+d);
}
public static void writeData() throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("d:\\data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
}
}
ByteArrayStream
操作字节数组
ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭
字符编码
- 字符流额出现为了方便操作字符
- 更重要的是加入了编码转换
- 通过子类转换流来完成
- InputStreamReader
- OutputStreamWriter
- 在两个对象进行构造的时候可以加入字符集
常见的编码表
- ASCII: 美国标准信息交换码
- 用一个自己的7位可以表示
- ISO8859-1: 拉丁码表 欧洲码表
- 用一个字节的8位表示
- GB2312: 中国的中文编码表
- GBK: 中国的中文编码表升级,融合了更多的中文文字符号
- Unicode: 国际标准码,融合了多种文字
- 所有文字都用两个字节来表示,Java语言使用的就是unicode
- UTF-8: 最多用三个字节来表示一个字符
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("gbk.txt"),"GBK");
char[] buf=new char[10];
int len=isr.read(buf);
String str=new String(buf,0,len);
System.out.println(str);
isr.close();
}
public static void writeText() throws IOException
{
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}