黑马程序员——IO流(三)

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值