IO流之其他功能类详解.docx

上传人:b****8 文档编号:11358041 上传时间:2023-02-28 格式:DOCX 页数:21 大小:21.35KB
下载 相关 举报
IO流之其他功能类详解.docx_第1页
第1页 / 共21页
IO流之其他功能类详解.docx_第2页
第2页 / 共21页
IO流之其他功能类详解.docx_第3页
第3页 / 共21页
IO流之其他功能类详解.docx_第4页
第4页 / 共21页
IO流之其他功能类详解.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

IO流之其他功能类详解.docx

《IO流之其他功能类详解.docx》由会员分享,可在线阅读,更多相关《IO流之其他功能类详解.docx(21页珍藏版)》请在冰豆网上搜索。

IO流之其他功能类详解.docx

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

Vectorv=newVector();

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"));

Enumeratione=v.elements();

//创建一个合并流,且构造方法传入的必须是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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1