JavaI/O系统的类实在是太多了这里我们只学习一些基本的和常用的相信能够掌握这些就可以解决我们以后的普通应用了
什么是数据流?
数据流是指所有的数据通信通道
有两类流InputStreamandOutputStreamJava中每一种流的基本功能依赖于它们
InputStream用于readOutputStream用于write读和写都是相对与内存说的读就是从其他地方把数据拿进内存写就是把数据从内存推出去
这两个都是抽象类不能直接使用
InputStream的方法有read()从流中读入数据有中方式
intread()一次读一个字节
intread(byte[])读多个字节到数组中
intread(byte[]intoffintlen)指定从数组的哪里开始读多长
skip()跳过流中若干字节
available()返回流中可用字节数但基于网络时无效返回
markSupported()判断是否支持标记与复位操作
mark()在流中标记一个位置要与markSupported()连用
reset()返回标记过的位置
close()关闭流
OutputStream的方法:
write(int)写一个字节到流中
write(byte[])将数组中的内容写到流中
write(byte[]intoffintlen)将数组中从off指定的位置开始len长度的数据写到流中
close()关闭流
flush()将缓沖区中的数据强制输出
File类
File可以表示文件也可以表示目录File类控制所有硬盘操作
构造器
File(FileparentStringchild)用父类和文件名构造
File(Stringpathname)用绝对路径构造
File(StringparentStringchild)用父目录和文件名构造
File(URIuri)用远程文件构造
常用方法
booleancreateNewFile();
booleanexists();
例子
//建立testtxt文件对象判断是否存在不存在就创建
importjavaio*;
publicclassCreateNewFile{
publicstaticvoidmain(Stringargs[]){
Filef=newFile(testtxt);
try{
if(!fexists())
fcreateNewFile();
else
Systemoutprintln(exists);
}catch(Exceptione){
eprintStackTrace();
}
}
}
booleanmkdir()/mkdirs()
booleanrenameTo(Filedestination)
例子//看一下这mkdir()/mkdirs()的区别和renameTo的用法
importjavaio*;
publicclassCreateDir{
publicstaticvoidmain(Stringargs[]){
Filef=newFile(testtxt);
Filef=newFile(Dir);
Filef=newFile(Top/Bottom);
Filef=newFile(newTesttxt);
try{
frenameTo(f);
fmkdir();
fmkdirs();
}catch(Exceptione){
eprintStackTrace();
}
}
}
StringgetPath()/getAbsolutePath()
StringgetParent()/getName()
例子//硬盘上并没有parent目录和testtxt文件但我们仍然可以操作因为我们创建了他们的对象是对对象进行操作
importjavaio*;
publicclassTest{
publicstaticvoidmain(Stringargs[]){
Filef=newFile(parent/testtxt);
Filef=newFile(newTesttxt);
try{
Systemoutprintln(fgetParent());
Systemoutprintln(fgetName());
Systemoutprintln(fgetPath());
Systemoutprintln(fgetAbsolutePath());
}catch(Exceptione){
eprintStackTrace();
}
}
}
Stringlist[]//显示目录下所有文件
longlastModified()//返回到最后修改时间的秒数
booleanisDirectory()
例子//列出目录下的所有文件和目录最后修改时间是目录的后面标出<DIR>是文件的后面标出文件长度
importjavaio*;
importjavautil*;
publicclassDir{
publicstaticvoidmain(Stringargs[]){
Filef=newFile(Dir);
String[]listAll=null;
Filetemp=null;
try{
listAll=flist();
for(inti=;i<listAlllength;i++){
temp=newFile(listAll<i>);
Systemoutprint(listAll<i>+\t);
if(tempisDirectory())
Systemoutprint(\t<DIR>\t);
else
Systemoutprint(templength()+\t);
Systemoutprintln(newDate(templastModified()));
}
}catch(Exceptione){
eprintStackTrace();
}
}
}
文件流的建立
Filef=newFile(temptxt);
FileInputStreamin=newFileInputStream(f);
FileOutputStreamout=newFileOutputStream(f);
例子文件拷贝
importjavaio*;
publicclassCopy{
publicstaticvoidmain(Stringargs[]){
FileInputStreamfis=null;
FileOutputStreamfos=null;
try{
fis=newFileInputStream(cgif);
fos=newFileOutputStream(c_copygif);
intc;
while((c=fisread())!=)
foswrite(c);
}catch(Exceptione){
eprintStackTrace();
}finally{
if(fis!=null)try{fisclose();}catch(Exceptione){eprintStackTrace();}
if(fos!=null)try{fosclose();}catch(Exceptione){eprintStackTrace();}
}
}
}
缓沖区流
BufferedInputStream
BufferedOutputStream
他们是在普通文件流上加了缓沖的功能所以构造他们时要先构造普通流
例子文件拷贝的缓沖改进
importjavaio*;
publicclassCopy{
publicstaticvoidmain(Stringargs[]){
BufferedInputStreambis=null;
BufferedOutputStreambos=null;
bytebuf[]=newbyte[];
try{
bis=newBufferedInputStream(newFileInputStream(persiamp));
bos=newBufferedOutputStream(newFileOutputStream(persia_copymp));
intlen=;
while(true){
len=bisread(buf);
if(len<=)break;
boswrite(buflen);
}
bosflush();//缓沖区只有满时才会将数据输出到输出流用flush()将未满的缓沖区中数据强制输出
}catch(Exceptione){
eprintStackTrace();
}finally{
if(bis!=null)try{bisclose();}catch(Exceptione){eprintStackTrace();}
if(bos!=null)try{bosclose();}catch(Exceptione){eprintStackTrace();}
}
}
}
原始型数据流
DataInputStream
DataOutputStream
他们是在普通流上加了读写原始型数据的功能所以构造他们时要先构造普通流
方法
readBoolean()/writeBoolean()
readByte()/writeByte()
readChar()/writeByte()
例子//这个流比较简单要注意的就是读时的顺序要和写时的一样
importjavaio*;
publicclassDataOut{
publicstaticvoidmain(Stringargs[]){
DataOutputStreamdos=null;
try{
dos=newDataOutputStream(newFileOutputStream(dataouttxt));
doswriteInt();
doswriteBoolean(true);
doswriteLong(L);
doswriteChar(a);
}catch(Exceptione){
eprintStackTrace();
}finally{
if(dos!=null)
try{
dosclose();
}catch(Exceptione){
}
}
}
}
importjavaio*;
publicclassDataIn{
publicstaticvoidmain(Stringargs[]){
DataInputStreamdis=null;
try{
dis=newDataInputStream(newFileInputStream(dataouttxt));
Systemoutprintln(disreadInt());
Systemoutprintln(disreadBoolean());
Systemoutprintln(disreadLong());
Systemoutprintln(disreadChar());
}catch(Exceptione){
eprintStackTrace();
}finally{
if(dis!=null)
try{
disclose();
}catch(Exceptione){
}
}
}
}
对象流
串行化对象通过写出描述自己状态的数值来记述自己的过程叫串行话
对象流能够输入输出对象的流
将串行化的对象通过对象流写入文件或传送到其他地方
对象流是在普通流上加了传输对象的功能所以构造对象流时要先构造普通文件流
注意只有实现了Serializable接口的类才能被串行化
例子
importjavaio*;
classStudentimplementsSerializable{
privateStringname;
privateintage;
publicStudent(Stringnameintage){
thisname=name;
thisage=age;
}
publicvoidgreeting(){
Systemoutprintln(hellomynameis+name);
}
publicStringtoString(){
returnStudent[+name++age+];
}
}
publicclassObjectOutTest{
publicstaticvoidmain(Stringargs[]){
ObjectOutputStreamoos=null;
try{
oos=newObjectOutputStream(
newFileOutputStream(studenttxt));
Students=newStudent(Jerry);
Students=newStudent(Andy);
ooswriteObject(s);
ooswriteObject(s);
}catch(Exceptione){
eprintStackTrace();
}finally{
if(oos!=null)
try{
oosclose();
}catch(Exceptione){
eprintStackTrace();
}
}
}
}
importjavaio*;
publicclassObjectInTest{
publicstaticvoidmain(Stringargs[]){
ObjectInputStreamois=null;
Students=null;
try{
ois=newObjectInputStream(
newFileInputStream(studenttxt));
Systemoutprintln();
s=(Student)oisreadObject();
Systemoutprintln(s);
sgreeting();
Systemoutprintln();
s=(Student)oisreadObject();
Systemoutprintln(s);
sgreeting();
}catch(Exceptione){
eprintStackTrace();
}finally{
if(ois!=null)
try{
oisclose();
}catch(Exceptione){
eprintStackTrace();
}
}
}
}
字符流InputStreamReader/OutputStreamWriter
上面的几种流的单位是byte所以叫做字节流写入文件的都是二进制字节我们无法直接看下面要学习的是字节流
Java采用Unicode字符集每个字符和汉字都采用个字节进行编码ASCII码是Unicode编码的自集
InputStreamReader是字节流到字符桥的桥梁(byte>char读取字节然后用特定字符集编码成字符)
OutputStreamWriter是字符流到字节流的桥梁(char>byte)
他们是在字节流的基础上加了桥梁作用所以构造他们时要先构造普通文件流
我们常用的是:
BufferedReader方法readLine()
PrintWriter方法println()
例子
importjavaio*;
publicclassPrintWriterTest{
publicstaticvoidmain(Stringargs[]){
PrintWriterpw=null;
try{
pw=newPrintWriter(
newOutputStreamWriter(
newFileOutputStream(bufferedwritertxt)));
pwprintln(helloworld);
}catch(Exceptione){
eprintStackTrace();
}finally{
if(pw!=null)
try{
pwclose();
}catch(Exceptione){
eprintStackTrace();
}
}
}
}
importjavaio*;
publicclassBufferedReaderTest{
publicstaticvoidmain(Stringargs[]){
BufferedReaderbr=null;
try{
br=newBufferedReader(
newInputStreamReader(
newFileInputStream(bufferedwritertxt)));
Systemoutprintln(brreadLine());
}catch(Exceptione){
eprintStackTrace();
}finally{
if(br!=null)
try{
brclose();
}catch(Exceptione){
eprintStackTrace();
}
}
}
}
随机存取文件RandomAccessFile
可同时完成读写操作
支持随机文件操作的方法:
readXXX()/writeXXX()
seek()将指针调到所需位置
getFilePointer()返回指针当前位置
length()返回文件长度
例子把若干个位的整数写到一个名为temptxt的文件中然后利用seek方法以相反的顺序再读取这些数据
importjavaio*;
publicclassRandomFile{
publicstaticvoidmain(Stringargs[]){
RandomAccessFileraf=null;
intdata[]={};
try{
raf=newRandomAccessFile(temptxtrw);
for(inti=;i<datalength;i++)
rafwriteInt(data<i>);
for(inti=datalength;i>=;i){
rafseek(i*);
Systemoutprintln(rafreadInt());
}
}catch(Exceptione){
egetMessage();
}finally{
if(raf!=null)
try{
rafclose();
}catch(Exceptione){
egetMessage();
}
}
}
}
小结
这部分的难点就是类比较复杂尤其是每个类的构造方式我认为记住下面这个图比记类的继承关系更好些
a字节流
InputStream
|FileInputStream(基本文件流)
|BufferedInputStream
|DataInputStream
|ObjectInputStream
OutputStream同上图
BufferedInputStreamDataInputStreamObjectInputStream只是在FileInputStream上增添了相应的功能构造时先构造FileInputStream
b字符流
Reader
|InputStreamReader(byte>char桥梁)
|BufferedReader(常用)
Writer
|OutputStreamWriter(char>byte桥梁)
|BufferedWriter
|PrintWriter(常用)
c随机存取文件RandomAccessFile