------- android培训、java培训、期待与您交流! ----------
对象的序列化
操作对象
ObjectInputStream与ObjectOutputStream
import java.io.*;
class ObjectStreamDemo {
publicstatic void main(String[] args) {
}
publicstatic void writeObj() {
ObjectOutputStreamoos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
}
}
RandomAccessFile
随机访问文件,自身具备读写的方法
通过skipBytes(int x),seek(int x)来达到随机访问
该类不算是IO体系中的子类
而是直接继承自Object
但是它是IO包中成员,因为它具备读和写功能
内部封装了一个数组,而且通过指针对数组的元素进行操作
可以通过getFilePointer获取指针位置
同时可以通过seek改变指针的位置
其实完成读写的原来就是内部封装了字节输入流和输出流
通过构造函数可以看出,该类只能操作文件
而且操作文件还有模式 :只读 r 读写rw等
如果模式为只读r 不会创建文件,回去读取一个已存在的文件,如果该文件不存在,则会出现异常
如果模式为rw 操作的文件不存在,会自动创建,如果存在则不会覆盖
import java.io.*;
class RandomAccessFileDemo {
publicstatic void main(String[] args)throws IOException
{
//writeFile();
//readFile();
writeFile_2()
}
publicstatic void readFile() throws IOException {
RandomAccessFileraf = new RandomAccessFile("ran.txt", "r");
//调整对象指针
raf.seek(8);
//跳过指定的字节数
raf.skipBytes(8);//只能往前跳 不能往后跳
byte[]buf = new byte[4];
raf.read(buf);
Stringname = new String(buf);
intage = raf.readInt();
System.out.println("name="+ name);
System.out.println("age="+ age);
raf.close();
}
publicstatic void writeFile_2() throws IOException {
RandomAccessFileraf = new RandomAccessFile("ran.txt", "rw");
raf.seek(8* 3);
//raf.seek(8*0);//会对数据进行覆写
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
publicstatic void writeFile() throws IOException {
RandomAccessFileraf = new RandomAccessFile("ran.txt", "rw");
raf.write("李四".getBytes());
//raf.write(258);//write只写出最低八位,超出八位的话会数据丢失
raf.writeInt(97);//writeInt(int v) 按四个字节将 int 写入该文件,先写高字节
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
管道流
PipedInputStream和PipedOutputStream
输入输出可以直接进行连接,通过结合线程使用
操作基本数据类型
DataInputStream与DataOutputStream
操作字节数组
ByteArrayInputStream与ByteArrayOutputStream
操作字符数组
CharArrayReader与CharArrayWriter
操作字符串
StringReader与StringWriter
DataInputStream与DataOutputStream
可以用于操作基本数据类型的流对象
import java.io.*;
class DataStreamDemo {
publicstatic void main(String[] args) throws IOException {
writeData();
//readData()
}
publicstatic void readData() throws IOException {
DataInputStreamdos = new DataIntputStream(new FileIntputStream("data.txt"));
intnum = dis.readInt();
booleanb = dis.readBoolean();
doubled = dis.readDouble();
System.out.println("num="+ num);
System.out.println("b="+ b);
System.out.println("d="+ d);
dis.close();
}
publicstatic void writeData() throws IOException {
DataOutputStreamdos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9007.543);
dos.close();
}
}
操作字节数组
ByteArrayInputStream与ByteArrayOutputStream
用于操作字节数组的流对象
ByteArrayInputStream在构造的时候,需要接受数据源,而且数据源是一个字节数组
ByteArrayOutputStream在够在的时候,不用定义数据目的,因为该对象中已经封装了
可变长度的字节数组,这就是数据目的地
因为这两个流对象都操作的数组,并没有使用系统资源
所有,不用进行close关闭
在流操作规律讲解时:
源设备:
键盘 System.in 硬盘 FileStream 内存 ArrayStream
目的:
控制台 System.out 硬盘 FileStream 内存 ArrayStream
用流的读写思想操作数组
import java.io.*;
class ByteArrayStream
{
public static void main(String[] args)
{
//数据源
ByteArrayInputStream bis = newByteArrayInputStream("ABCDEF".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());
}
}
字符编码
字符流的出现为了方便操作字符
更重要的是加入了编码转换
通过子类转换流来完成
InputStreamReader
OutputStreamWriter
在两个对象进行构造的时候可以加入字符集
编码表的由来
计算机只能识别二进制数据,早起由来是电信号
为了方便应用计算机,让它可以识别各个国家的文字
就将各个国家的文字用数字来表示,并一一对应,形成一张表
这就是编码表
常见的编码表
ASCII:没过标准信息交换码。
用一个字节的7位可以表示
ISO08859-1:拉丁码表。欧洲码表
用一个字节的8位表示
GB2312: 中国的中文编码表
GBK:中国的中文编码表升级,融合了更多的中文文字符号
Unicode:国际标准码,融合了多种文字
所有文字都用两个字节来表示,java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符
转换流的编码应用
可以将字符以指定编码格式存储
可以对文本数据指定编码格式来解读
指定编码表的动作由构造函数完成
import java.io.*;
class EncodeStream {
publicstatic void main(String[] args) throws IOException {
writeText();
}
publicstatic void readText() throws IOException {
InputStreamReaderisr = new InputStreamReade(new FileInputStream("gbk.txt"),"gbk");
char[]buf = new char[10];
intlen = isr.read(buf);
Stringstr = new String(buf, 0, len);
System.out.println(str);
isr.close();
}
publicstatic void writeText() throws IOException {
OutputStreamWriterosw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
OutputStreamWriterosw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}
编码:字符串变成字节数组
解码:字节数组变成字符串
String-->byte[] str.getBytes(charsetName)
byte[]-->String new String(byte[],charsetName)
import java.util.*;
class EncodeDemo {
publicstatic void main(String[] args) throws Exception {
Strings = "你好";
byte[]b1 = s.getBytes("GBK");// 用GBK编码
Strings1 = new String(b1, "ISO8859-1");// 用ISO8859-1解码
//System.out.println(s1);
//System.out.println(Arrays.toString(b1));
byte[]b2 = s1.getBytes("ISO8859-1");
System.out.println(Arrays.toString(b2));
Strings2 = new String(b2, "gbk");
System.out.println("s2="+ s2);
}
}
字符编码--联通
class EncodeDemo2 {
publicstatic void main(String[] args) {
Strings = "联通";
byte[]by = s.getBytes("gbk");
for(byte b : by) {
System.out.println(Integer.toBinaryString(b& 255));
}
}
}
有五个学生,每个学生有3门课的成绩
从键盘输入以上数据(包括姓名,三门课成绩)
输入格式如:张三,30,40,60计算出总成绩
并把学生的信息和计算出的总分数高低顺序存放在磁盘文件“stud.txt”
1.描述学生对象
2.定义一个可操作学生对象的工具类
思想
1.通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象
2.因为学生有很多,那么就需要存储,使用到集合。因为要对学生总分排序
所以可以使用TreeSet
3.将集合的信息写入到一个文件中
import java.io.*;
import java.util.*;
class Student implementsComparable<Student> {
privateString name;
privateint ma, cn, en;
privateint sum;
Student(Stringname, int ma, int cn, int en) {
this.name= name;
this.ma= ma;
this.cn= cn;
this.en= en;
sum= ma + cn + en;
}
publicint compareTo(Student s) {
intnum = new Integer(this.sum).compareTo(new Integer(s.sum));
if(num == 0)
returnthis.name.compareTo(s.name);
returnnum;
}
publicString getName() {
returnname;
}
publicint getSum() {
returnsum;
}
publicint hashCode() {
returnname.hashCode() + sum * 78;
}
publicboolean equals(Object obj) {
if(!(obj instanceof Student))
thrownew ClassCastException("类型不匹配");
Students = (Student) obj;
returnthis.name.equals(s.name) && this.sum == s.sum;
}
publicString toString() {
return"student[" + name + ", " + ma + ", " + cn +", " + en + "]";
}
}
class StudentInfoTool {
publicstatic Set<Student> getStudents() throws IOException {
returngetStudents(null);
}
publicstatic Set<Student> getStudents(Comparator<Student> cmp) throwsIOException {
BufferedReaderbufr = new BufferedReader(new InputStreamReader(System.in));
Stringline = null;
Set<Student>stus = null;
if(cmp == null)
stus= new TreeSet<Student>();
else
stus= new TreeSet<Student>(cmp);
while((line = bufr.readLine()) != null) {
if("over".equals(line))
break;
String[]info = line.split(",");
Studentstu = new Student(info[0], Integer.parseInt(info[1]),Integer.parseInt(info[2]), Integer.parseInt(info[3]));
stus.add(stu);
}
bufr.close();
returnstus;
}
publicstatic void write2File(Set<Student> stus) throws IOException {
BufferedWriterbufw = new BufferedWriter(new FileWriter("stuinfo.txt"));
for(Student stu : stus) {
bufw.write(stu.toString()+ "\t");
bufw.write(stu.getSum()+ "");
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
class StudentInfoTest {
publicstatic void main(String[] args) throws IOException {
Comparator<Student>cmp = Collections.reverseOrder();
Set<Student>stus = StudentInfoTool.getStudents(cmp);
StudentInfoTool.write2File(stus);
}
}
合并流
SequenceInputStream
构造方法摘要
SequenceInputStream(Enumeration<?extends InputStream> e)
SequenceInputStream(InputStream s1,InputStream s2)
import java.io.*;
import java.util.*;
class SequenceDemo {
public static void main(String[] args) throws IOException {
// 新建Vector对象
Vector<FileInputStream> v = new Vector<FileInputStream>();
// 将流对象添加到集合中
v.add(new FileInputStream("e:\\Java练习\\1.txt"));
v.add(new FileInputStream("e:\\Java练习\\2.txt"));
v.add(new FileInputStream("e:\\Java练习\\3.txt"));
// 返回此向量的组件的枚举。返回到Enumeration中
Enumeration<FileInputStream> en = v.elements();
// 如果需要传入2个以上的流对象 SequenceInputStream(Enumeration<? extends InputStream>
// e)可以实现
// 需要传入Enumeration 而Vector可以获取Enumeration
// 因此需要新建Vector对象
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("e:\\Java练习\\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 {
publicstatic void main(String[] args) {
//splitFile();
merge();
}
publicstatic void merge()
{
ArrayList<FileInputStream> al = newArrayList<FileInputStream>();
for(int x=1;x<=5;x++)
{
al.add(newFileInputStream("e:\\Java练习\\"+(x++)+".part"))
}
Iterator it = al.iterator();
Enumeration<FileInputStream> en = newEnumeration<FileInputStream>()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStreamnextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("e:\\Java练习\\1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read())!=-1)
{
fos.write(buf,0,len)
}
fos.close();
sis.close();
}
publicstatic void splitFile()
{
FileInputStream fis = new FileInputStream("e:\\Java练习\\0.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int x = 1;
while((len=fis.read(buf))!=-1)
{
fos = newFileOutputStream("e:\\Java练习\\"+(x++)+".part")
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}