IO流之其他功能类详解.docx
- 文档编号:11358041
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:21
- 大小:21.35KB
IO流之其他功能类详解.docx
《IO流之其他功能类详解.docx》由会员分享,可在线阅读,更多相关《IO流之其他功能类详解.docx(21页珍藏版)》请在冰豆网上搜索。
IO流之其他功能类详解
IO包其他功能流及字符编码详解
打印流(PrintStream和PrintWriter)
该流提供了打印方法,可以将各种数据类型的数据都原样打印
字节打印流:
PrintStream
构造函数可以接受的参数类型
a)File对象File
b)字符串路径。
String
c)字节输出流。
OutputStream
字符打印流:
PrintWriter
构造函数可以接受的参数类型
a)File对象File
b)字符串路径。
String
c)字节输出流。
OutputStream
d)字符输出流.Writer
我们开发常用的是printWriter,那么printWriter有什么常用的方法呢?
a)特殊构造方法:
PrintWriter(OutputStreamout,booleanautoFlush):
如果为true,可以自动刷新println,printf,format
b)voidprintln(Strings);打印
我们用这些方法来演示下PrintWriter的基本方法:
importjava.io.*;
classPrintWriterDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
method();
}
publicstaticvoidmethod()throwsIOException
{
BufferedReaderbr=
newBufferedReader(newInputStreamReader(System.in));
PrintWriterpw=newPrintWriter(newFileWriter("a.txt"),true);
Stringline=null;
while((line=br.readLine())!
=null)
{
if("over".equals(line))
{
break;
}
pw.println(line.toUpperCase());//
//pw.flush();
}
br.close();
pw.close();
}
}
合并流(SequenceInputStream)
我们首先将一个mp3文件切割成一个个碎片,这里就涉及到IO流的应用,我们把切割代码演示如下:
importjava.io.*;
classSpilteDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
spite();
}
publicstaticvoidspite()throwsIOException
{
FileInputStreamfis=newFileInputStream("1.mp3");
FileOutputStreamfos=null;
byte[]buf=newbyte[1024*1024];
intlen=0;
intcount=1;
while((len=fis.read(buf))!
=-1){
//每次循环我们都创建一个写入流,保存到递增的文件中
fos=newFileOutputStream("c:
//splitest//"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
然而我们有时需要将文件合并到一起,那么我们怎么办呢?
我们这时就需要一个IO流的合并流
合并流(SequenceInputStream)即将多个流合并成一个流,即多个文件合并成一个文件
构造方法:
SequenceInputStream(Enumeration
extendsInputStream>e):
接收一个Enumeration类型参数,需要用到集合
我们通过代码简单演示下如何将之前MP3文件合并在一起:
importjava.io.*;
importjava.util.*;
classSequenceInputStreamDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
//只有Vector才有Enumeration
Vector
v.add(newFileInputStream("c:
//splitest//1.part"));
v.add(newFileInputStream("c:
//splitest//2.part"));
v.add(newFileInputStream("c:
//splitest//3.part"));
v.add(newFileInputStream("c:
//splitest//4.part"));
v.add(newFileInputStream("c:
//splitest//5.part"));
v.add(newFileInputStream("c:
//splitest//6.part"));
v.add(newFileInputStream("c:
//splitest//7.part"));
v.add(newFileInputStream("c:
//splitest//8.part"));
Enumeration
//创建一个合并流,且构造方法传入的必须是Enumeration类型
SequenceInputStreamsis=newSequenceInputStream(e);
//将多个文件的数据传入到4.txt
BufferedOutputStreambw=
newBufferedOutputStream(newFileOutputStream("c:
//mp3//1.mp3"));
intlen=0;
while((len=sis.read())!
=-1){
bw.write(len);
}
sis.close();
bw.close();
}
}
对象流(对象序列化ObjectStream)
对象流是可以将对象以序列化的方式存入到一个文件里,对象流有非常重要的两个类,该两个类是成对出现的。
ObjectOutputStream:
将对象存储到一个文件中
存储方法:
voidwriteObject(Objectobj)
ObjectInputStream:
操作输出对象流一保存的数据,通常和ObjectOutputStream成对使用。
读取方法:
voidreadObject();
我们基本演示下将Person对象存入到文件中:
importjava.io.*;
classObjectDemo
{
publicstaticvoidmain(String[]args)throwsException
{
writeObj();//要先写再读
readObj();
}
publicstaticvoidreadObj()throwsException
{
ObjectInputStreamois=newObjectInputStream(newFileInputStream("object.txt"));
Personp=(Person)ois.readObject();
System.out.println(p);
ois.close();
}
publicstaticvoidwriteObj()throwsIOException
{
ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream("object.txt"));
oos.writeObject(newPerson("zhangsan",13));
oos.close();
}
}
classPersonimplementsSerializable//必须要实现这个接口,是对象序列化
{
Stringname;
intage;
Person(Stringname,intage)
{
this.age=age;
this.name=name;
}
publicStringtoString()
{
returnname+":
:
"+age;
}
}
注意:
a)当我们该掉Person任何一个成员属性时,再读取就会出错,是因为java内部有个叫UID的长整型的编号将Person中的属性编号,无论改变成员变量值还访问权限,都会报错,读取失败,如果想改变而又不读取失败,可以加上这段代码:
ANY-ACCESS-MODIFIERstaticfinallongserialVersionUID=42L;红色的是任何访问修饰符。
、
b)我们想存储的对象的类必须要实现一个接口Serializable,是其对象序列化
c)要存储的对象类中成员属性不能是static修饰的,这样无法序列化,当然我们想让成员变量无法序列化也可在其加上transient
管道流(PipedStream)
管道流是IO中一个非常特殊的流,他是和多线程联系在一起的。
管道流输入输出是连接在一起的。
输入流:
PipedInputStream
输出流:
PipedOutputStream
管道流的输入输出连接是通过两种方法实现:
a)构造一个无参数的构造方法,使用connect()方法去连接输入和输出
b)构造一个有参数的构造方法,传入的是自己的输入或者输出流
我们基本演示下管道流的应用:
importjava.io.*;
classReadimplementsRunnable
{
PipedInputStreampis;
Read(PipedInputStreampis){
this.pis=pis;
}
publicvoidrun()
{
try
{
byte[]buf=newbyte[1024];
System.out.println("没有数据,线程没有阻塞");
intlen=pis.read(buf);
System.out.println("读取数据中。
。
阻塞结束");
Stringstr=newString(buf,0,len);
System.out.println(str);//打印读取到的数据
pis.close();
}
catch(Exceptione)
{
thrownewRuntimeException("管道流输入失败");
}
}
}
classWriteimplementsRunnable
{
PipedOutputStreampos;
Write(PipedOutputStreampos){
this.pos=pos;
}
publicvoidrun()
{
try{
System.out.println("开始写入数据,等待6秒后");
Thread.sleep(6000);
pos.write("haha,pioediscome".getBytes());
pos.close();
}catch(Exceptione){
thrownewRuntimeException("管道流输出失败");
}
}
}
classPipedIODemo
{
publicstaticvoidmain(String[]args)throwsException
{
PipedInputStreampis=newPipedInputStream();
PipedOutputStreampos=newPipedOutputStream();
pis.connect(pos);//连接输入和输出
newThread(newRead(pis)).start();//开启读取线程
newThread(newWrite(pos)).start();//开启写入线程
}
}
随机访问流(RandomAccessFile)
该类是随机访问文件的一个类,该类不能算是IO体系中子类,而是直接继承自Object,但是它是IO包中的成员,因为他具备读和写功能。
其内部封装了一个byte数组,对字节输出输入进行封装。
通过索引的方式对数组中的元素进行操作。
通过指针对数组的元素进行操作。
我们可以通过getFIlePointer获取指针位置。
同时可以通过seek改变指针的位置。
。
局限性:
只对文件操作。
随机访问的原理:
就是通过操作索引的方法对指针进行自定义的指定位置来进行读写
其实完成读写的原理就是内部封装了字节输入流和输出流。
但它有一个局限性就是通过构造方法可以看出,该类只能操作文件,而且操作文件还有模式。
模式:
a)r:
以只读方式打开
b)rw:
打开以便读取和写入
c)rws:
打开以便读取和写入
d)rwd:
打开以便读取和写入
如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现文件找不到(FileNotFoundException)异常。
如果模式为rw,操作的文件不存在,会自动创建,如果存在,不会覆盖。
而且该对象的构造函数要操作的文件不存在,会自动创建。
如果存在,不会覆盖。
我们基本演示下该类的用法:
importjava.io.*;
classRandomAccessFileDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
writeFile_2();
//readFile();
}
publicstaticvoidreadFile()throwsIOException
{
RandomAccessFileraf=newRandomAccessFile("ran.txt","r");
byte[]buf=newbyte[4];
//调整对象中的指针
//raf.seek(8);
//跳过指定的字节数
raf.skipBytes(8);
raf.read(buf);
Stringname=newString(buf);
System.out.println("name:
:
"+name);
intage=raf.readInt();
System.out.println("age:
:
"+age);
}
publicstaticvoidwriteFile()throwsIOException
{
RandomAccessFileraf=newRandomAccessFile("ran.txt","rw");
raf.write("张三".getBytes());
//写入Int类型,以免超出无法保存,一般开发够用了
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
/*
写入文件数据的随机性
*/
publicstaticvoidwriteFile_2()throwsIOException
{
RandomAccessFileraf=newRandomAccessFile("ran.txt","rw");
//可以随机控制要写入的字节位置
raf.seek(8*0);
raf.write("周期".getBytes());
raf.writeInt(101);
raf.close();
}
}
总结:
该类三种特殊的地方:
首先它有有一个模式控制文件的读写操作,然后它有一个seek方法控制写入字节的位置,最后他的写入读取有多种基本类型,我们常用的是writeInt方法。
该类经常用在文件的下载,我们要重点掌握。
基本数据类型流(DataStream)
其用于操作基本数据类型的流
输入流:
DataInputStream
输出流
DataOutputStream
我们通过代码演示,基本的了解下DataStream的用法:
importjava.io.*;
classDataStreamDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
//writeData();
readData();
}
publicstaticvoidwriteData()throwsIOException
{
DataOutputStreamdos=newDataOutputStream(newFileOutputStream("data.txt"));
//我们按照什么顺序写入什么基本类型数据
dos.writeInt(289);
dos.writeBoolean(true);
dos.writeDouble(988.26);
dos.close();
}
publicstaticvoidreadData()throwsIOException
{
DataInputStreamdis=newDataInputStream(newFileInputStream("data.txt"));
//我们就按照什么顺序读取什么基本类型。
必须按顺序,否则取出来乱码
intnum=dis.readInt();
Booleanb=dis.readBoolean();
Doubled=dis.readDouble();
System.out.println(num);
System.out.println(b);
System.out.println(d);
}
}
注意这两个类个分别有特殊的方法是专门用来输入和读取UTF的方法,我们只能对应的去取文件的数据。
这两个方法分别是readUTF(),writeUTF()。
我们演示下这两个方法的用法:
importjava.io.*;
classDataStreamDemo
{
publicstaticvoidmain(String[]args)throwsIOException
{
//writeUTFData();
readUTFData();
}
publicstaticvoidwriteUTFData()throwsIOException
{
DataOutputStreamdos=newDataOutputStream(newFileOutputStream("utfdata.txt"));
dos.writeUTF("你好");//writeUTF只能解析中文
dos.close();
}
publicstaticvoidreadUTFData()throwsIOException
{
DataInputStreamdis=newDataInputStream(newFileInputStream("utfdata.txt"));
Strings=dis.readUTF();
System.out.println(s);
}
}
基本数据类型数组流(ByteArrayStream)
ByteArrayStream是用来操作字节数组的流对象,是写入到内存的特殊的流
ByteArrayInputStream:
在构造的时候,需要接收数据源,而且数据源是一个字节数组。
构造方法:
ByteArrayInputStream(byte[]buf)
ByteArrayOutputStream:
在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地、
构造方法:
ByteArrayOutputStream()
常用的方法:
a)intsize:
返回缓冲区的当前数组大小
b)StringtoString:
将缓冲区内容转换为字符串
c)voidwriteTo(OutputStreamout):
将byte数组全部内容存到指定输入流文件中,这段代码需要抛IOException。
因为是两个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭,且没有涉及到文件或者键盘等操作,所以不用抛IOException。
这个类就是用流的读写思想操作数组
我们来通过代码基本演示下这个流:
importjava.io.*;
classArrayStreamDemo
{
publicstaticvoidmain(String[]args)
{
//数据源
ByteArrayInputStreambais=newByteArrayInputStream("ABCDEFG".getBytes());
//数据目的
ByteArrayOutputStreambaos=newByteArrayOutputStream();
inta=0;
while((a=bais.read())!
=-1)
{
baos.write(a);
}
System.out.println(baos.size());//缓冲区的大小
System.out.println(baos.toString());//唯一取出数组的方法
}
}
总结:
我们不仅有操作字节数组的,还有其他的基本类型数组操作,他们基本用法是一致的:
操作字符数组
CharArrayReader与CharArrayWrite
操作字符串
StringReader与StringWriter
字符编码
我们常用的编码表是UTF—8和GBK,UTF—-8是国际码表,一个汉字占三个字节,GBk是中国的码表,一个汉字占两个字节。
字节转换字符只能用IO流两个类
a)InputStreamReader和outputStrea
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IO 其他 功能 详解