java-IO流_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java-IO流

java-IO流

 2012/10/15 10:37:50  妩明宝宝  程序员俱乐部  我要评论(0)
  • 摘要:-94dc-b5cebca12fcb.jpg[/img]I/O:站在程序的角度看流!(程序员)1.流:完成当前程序和外设(网络,文件,其他程序)之间的数据交换我们可以认为在外设(网络,文件,其他程序)上面有两个管道,这两个管道可用于程序和外设之间的数据交换2.流的分类:按照流的流向:如上图:所有编号为奇数的流都是可以把外设中的数据输入到程序中,我们称为输入流所有编号为偶数的流都是可以把程序中的数据输出到外设中,我们称之为输出流按照流所处理的数据类型:字节流和字符流;只能用于处理(读取/写入
  • 标签:Java
-94dc-b5cebca12fcb.jpg[/img]

I/O:站在程序的角度看流!(程序员

1.流:完成当前程序和外设(网络,文件,其他程序)之间的数据交换
我们可以认为在外设(网络,文件,其他程序)上面有两个管道,这两个管道可用于程序和外设之间的数据交换



2.流的分类:
按照流的流向:
如上图:所有编号为奇数的流都是可以把外设中的数据输入到程序中,我们称为输入流
所有编号为偶数的流都是可以把程序中的数据输出到外设中,我们称之为输出流
按照流所处理的数据类型:字节流和字符流;
只能用于处理(读取/写入)字节流---我们称之为字节流
只能用于处理(读取/写入)字符(Unicode码)的流—我们称之为字符流
按照处理方式:节点流(低级流)和处理流(高级流)
从外设转换直接获取的流都是节点流;
对节点流进行封装,对其处理数据的方式进行改变,这个封装后的流我们称为处理流;






3.Input/OutStream流的子类方法:

//控制台输出
InputStream is=System.in;
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
System.out.println("请输出源文件目录:");
String s=br.readLine();
System.out.println("请输出目标文件目录:");
String s1=br.readLine();

FileIn/OutputStream:
FileOutputStream fos=new FileOutputStream(f);
// byte[] b="gjsajsahdk".getBytes();
// fos.write(b);

//int read():c从此输入流中读取一个字节
//如果读取到了字节则返回字节的ascii码,如果达到流的末尾(没有读取到数据)返回-1
//
FileInputStream fis=new FileInputStream(f);
//int read[byte[] b] :从流中读取数据,将读取到的数据存放到字节数组中
//如果字节数组的长度大于等于文件中字节个数,会一次性的将文件中的数据全部读取
//如果字节数组的长度小于文件中字节的个数,那么每一次读取都会将数组装满
//如果读取到了数据,则返回读取到得字节个数
//如果已经到达文件末尾则返回-1

//int read[byte[] b,int off,int len)
//从此输入流中将最多len个字节的数据读入一个byte数组中,从索引off开始存放
byte[] bu=new byte[20];
fis.read(bu, 3, 5);//通过fis从文件中读取到5个字符,放在bu中从索引为3的元素开始存放
System.out.write(bu);

//定义一个字节数组存放从流中读取到得文件中的数据
//通过流调用read()方法,将文件中的数据读取到数组中
// byte[] b=new byte[20];
// int j=fis.read(b);
// System.out.write(b,0,j);
// byte[] b=new byte[2];
// int i;
// while((i=fis.read(b))!=-1){
// String s=new String(b,0,i);
// System.out.println(s);
// System.out.write(b, 0, i);
// }
****************************************************************
FileInputStream fis=new FileInputStream(f);
byte[] b=new byte[2];
//流在当前位置还可以向读取到得字节数
int m=fis.available();
System.out.println(m);
int i=fis.read(b);
System.out.write(b);
//让文件指针向前/向后跳动指定字节数
fis.skip(-1);

System.out.println();
m=fis.available();
System.out.println(m);
i=fis.read(b);
System.out.write(b);
FilterIn/OutputStream(高级流):
子类---DataInputStream
//DataOutputStream :可以将程序中不同类型的数据写入到文件中
//DataInputStream 可以从数据源(外设)读入带有数据类型的数据(前提:外设存在带有数据类型的数据)

try {
//通过fos可以将数据写入文件
//通过dos也可以将数据写到文件,并且dos可以将带有类型的数据写到文件
FileOutputStream  fos = new FileOutputStream("D:/t.txt");
DataOutputStream dos=new DataOutputStream(fos);
dos.writeInt(123);
dos.writeBoolean(false);
dos.writeDouble(3.141592653);
dos.flush();
//对数据库流来说先关低级流,再关高级流
//对本地文件流反之---压缩文件实例!
fos.close();
dos.close();

FileInputStream fis=new FileInputStream("D:/t.txt");
DataInputStream dis=new DataInputStream(fis);

boolean b=dis.readBoolean();
System.out.println(b);

int i=dis.readInt();
System.out.println(i);

// double d=dis.readDouble();
// System.out.println(d);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BufferedIn/OutputStream类:
BufferedOutputStream:
byte[] b={97,98,99,100,101,102,103};
FileOutputStream fos=new FileOutputStream("D:/t.txt");
// fos.write(b);
//创建一个BufferedOutputStream对象--带有缓冲区的输出流
//当执行write方法时候把数据写入缓冲区,当执行flush方法时候才把数据写入文件中
//FileOutputStream可以直接把数据写入文件
BufferedOutputStream bos=new BufferedOutputStream(fos);
bos.write(b);
bos.flush();
LineNumberInputStream类:可以设置/获取当前的行号!


PrintStream类:
//对于低级输出流而言--只有最基本的write方法可以用来向外设写入数据
//参数类型比较单一(只能是字节,字节数组)
try {
FileOutputStream fos=new FileOutputStream("D:/hksadsa.txt");
// fos.write(97);
// fos.write("\r\n".getBytes());
// fos.write(98);

//PrintStream:
PrintStream ps=new PrintStream(fos,true);
ps.println("Long long ago");
ps.println("There is a shan and heshang");
ps.println("san name is xiaoxiong!");
ps.println("heshang's name is 石建雄!");
字符流-------------------------------------
//要读取文本文件我们必须创建一个流,指向文件
//如果要创建一个输入流指向文件,我们只能创建字节输入流
FileInputStream fis=new FileInputStream("D:/t.txt");
//针对文本文档,我们首选字符流来读取,但是我们只能创建文件的字节输入流
//所以我们要借助于InputStreamReader来将这个字节流转换成字符流
InputStreamReader isr=new InputStreamReader(fis);
// char[] c=new char[20];
// int len;
// while((len=isr.read(c))!=-1){
// for (int i = 0; i < len; i++) {
// System.out.print(c[i]);
// }
// }
//通过InputStreamReader对象进行读取,效率比较低,方法比较单一---所以我们要对其进行封装
//1.可以提高读取效率   2.扩展读取方法
BufferedReader br=new BufferedReader(isr);
//每次读取外设中的一行数据,赋值给str,如果没有读取到内容则str=null;
// String s=br.readLine();
// System.out.println(s);
String s=null;
while((s=br.readLine())!=null){
System.out.println(s);
}
特色流类:RandomAccessFile----------:
RandonAccessFile(字节):是一个文件流,可以用来自由的访问(读/写)文件
构造器
RandonAccessFile raf = new RandonAccessFile(File 访问的文件,String 模式);
RandonAccessFile raf = new RandonAccessFile(String 访问文件的路径,String 模式);
模式可供选择的有4种:“r”,“rw”,“rws”,“rwd”
如果模式指定为“r”:表示这个流只能用来读取文件内容
如果模式指定为“rw”:表示这个流既能将文件内容读入到程序,也能将程序中的数据写入到文件中

//构造器  参数 :"rw"-- r:可读   w:可写
RandomAccessFile raf=new RandomAccessFile("D:/t.txt","rwd");
// byte[] b="小熊你好色!".getBytes();
// raf.write(b);
//seek():将流的指针向前/后移动到相对文件开头后的n个字节处
// raf.seek(6);
// raf.seek(8);
// int j=raf.read();
// System.out.println(j);
String s="hhhhahha";
//length():返回对应文件的长度(字节数)
long i=raf.length();
raf.seek(6);
raf.writeBytes(s);
// System.out.println(i);
raf.close();

流的一般操作:

[img]http://dl.iteye.com/upload/attachment/0074/9909/dfc0d966-bb1a-3c11

压缩文件实例:
压缩与解压文件---ZipOutputStream    ZipInputStream
public class TestZipSingleFile {

public static void main(String[] args) {
try {
//将D:/鱼鱼鱼.mp3压缩

//1,找到源文件
String srcPath = "D:/abc.mp3";
//2,根据源文件的名字生成压缩文件的名字
int i = srcPath.lastIndexOf(".");
String zipPath = srcPath.substring(0,i)+".zip";

//3,创建一个输入流指向源文件,因为我们要读取源文件的内容
FileInputStream fis = new FileInputStream(srcPath);

//4,创建一个输出流指向压缩文件,因为我们要把读取到得源文件的数据写到压缩文件
FileOutputStream fos = new FileOutputStream(zipPath);
ZipOutputStream zos = new ZipOutputStream(fos);

//5,创建一个房间(压缩条目)
File f = new File(srcPath);
//条目的名字要和源文件的名字一致
ZipEntry ze = new ZipEntry(f.getName());
zos.putNextEntry(ze);

//6,通过fis读取源文件,通过zos将读取到得内容写到压缩文件中对应的条目
byte[] b = new byte[500];
int len = -1;
while((len = fis.read(b))!=-1){
zos.write(b, 0, len);
}

zos.close();
fos.close();
fis.close();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

}
public class UnZip {

/**
* 将指定的压缩文件,解压到C盘
* @param zipPath
*/
public void unZipFile(String zipPath){
try {
FileInputStream fis = new FileInputStream(zipPath);
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry ze = null;
while((ze=zis.getNextEntry())!=null){
String zeName = ze.getName();
String saveFile = "c:/"+zeName;
//保存当前文件,目录要存在
int n = saveFile.lastIndexOf("\\");
String dirPath = saveFile.substring(0,n);
File dir = new File(dirPath);
dir.mkdirs();
//通过zis读取到当前条目的数据,然后写到对用saveFile
FileOutputStream fos = new FileOutputStream(saveFile);
byte[] b = new byte[1000];
int len = -1;
while((len = zis.read(b))!=-1){
fos.write(b,0,len);
}
fos.close();
zis.closeEntry();
}
zis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}



public static void main(String[] args) {
String zipPath = "D:/Java/jdk1.6.0_02.zip";
new UnZip().unZipFile(zipPath);
}

}
public class TestZipDirectory{

/**
* 遍历文件夹
* @throws IOException
*/
public void bianLi(File f,ZipOutputStream zos,int index) throws IOException{
if(f.isFile()){
FileInputStream fis = new FileInputStream(f);
//为当前子文件创建条目:从第一级父目录开始
//截取当前子文件的条目路径
String zePath = f.getAbsolutePath().substring(index+1);
ZipEntry ze = new ZipEntry(zePath);
zos.putNextEntry(ze);
byte[] b = new byte[500];
int len = -1;
while((len = fis.read(b))!=-1){
zos.write(b, 0, len);
}
zos.closeEntry();
fis.close();
}else{
//不是文件则代表是目录,我们就要去到目录中所有的子文件
File[] files = f.listFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
bianLi(file,zos,index);
}
}
}


public static void main(String[] args) {
try {

File dir = new File("D:/Java/jdk1.6.0_02");
String srcPath = dir.getAbsolutePath();
int index = srcPath.lastIndexOf("\\");
System.out.println(index);
String zipPath = srcPath+".zip";
//创建一个zos流指向压缩文件
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath));
new TestZipDirectory().bianLi(dir,zos,index);
zos.close();


} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象序列化:-------------------
1, 对象序列化:将对象通过输出流保存到磁盘(文件)/网络
① 对象序列化的目的?
A> 将对象存放到磁盘中实现持久化(永久保存)
B> 将对象在网络中传输,实现信息交换
什么样的对象可以被序列化?
A> 这个对象所在的类实现了Serializable接口
B> 这个对象所在的类实现了Externalizable接口
③ 怎么样实现对象序列化?
借助于ObjectOutputStream(高级流),需要对低级流进行封装
public final void writeObject(Object obj)
④ 对象中的哪些元素可以被序列化?
对象类名和属性可以被序列,但是被static或者transient修饰的属性不能被
实例:
public class Person implements Serializable {

//一个类中如果实现Serializable接口,我们认为该类的对象可以被序列化
//但是如果该类可以被序列化的属性中有对象类型,那么这个对象的类也必须实现序列化接口


private String pname = "person";
//如果想保留对象的某个属性不被序列化,可以用transient修饰这个属性
//transient修饰的属性不会被序列化
transient String psex = "女";
protected int page = 22;
public String pinfo = "我真的是一个人";
public  Student s = new Student();

}
*******************************************************************************
public class Person implements Serializable {

//一个类中如果实现Serializable接口,我们认为该类的对象可以被序列化
//但是如果该类可以被序列化的属性中有对象类型,那么这个对象的类也必须实现序列化接口


private String pname = "person";
//如果想保留对象的某个属性不被序列化,可以用transient修饰这个属性
//transient修饰的属性不会被序列化
transient String psex = "女";
protected int page = 22;
public String pinfo = "我真的是一个人";
public  Student s = new Student();

}
public class TestObjectInputStream {

public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("D:/obj.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
while(1==1){
Object obj = ois.readObject();
if(obj instanceof Person){
Person p = (Person) obj;
System.out.println(p.psex);
System.out.println(p.page);
System.out.println(p.pinfo);
}else if(obj instanceof Student){
Student s = (Student) obj;

}

}

} catch (Exception e) {
System.out.println("对象读取结束!");
}
}

}
public class TestObjectOutputStream {


public static void main(String[] args) {

try {
Person p = new Person();
Student s = new Student();

String path = "D:/obj.txt";
FileOutputStream fos = new FileOutputStream(path);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
//oos.writeObject(s);
oos.flush();
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

}
小结
回顾:
流的定义:我们可以认为在所有的外设(文件、网络、其他程序)中都有两个“管道”,如果我们的程序想要和某个外设之间进行数据交换,那么我们的程序就要获得这两个“管道”。
流的分类:
按照流的方向:输入流和输出流
输入流:外设中的数据进入到程序中
输出流:程序中的数据写入到外设中
按照流处理的数据类型:字节流和字符流
字节流:只能处理字节类型数据的流
字符流:只能处理字符类型数据的流
按照流的处理方式:节点流(低级流)和处理流(高级流)
低级流:从外设中直接获取的流
高级流:由于低级流处理数据方式单一,使用起来就不够灵活,我们可以对低级流进行封装,封转之后的流我们称之为高级流。
字节输入流:InputStream
低级字节输入流:
?ByteArrayInputStream(以数组作为外设,可以将一个字节数组中的数据输入到程序中)
?FileInputStream(以文件作为外设,可以将各种类型文件的数据输入到程序中)
?StringBufferedInputStream(以字符串作为外设,可以将字符串中的数据读出来)
//InputStream is = net.getInputStream();
高级字节输入流:
?DataInputStream:可以读取带有数据类型的数据
?BufferedInputStream:提供了一个缓冲区,读取效率更高
?LineNumberInputStream:可以添加行标记实现对应行的读取
?ObjectInputStream:可以将一个对象保存到低级流指向的地方(对象序列化)

字节输出流:OutputStream
低级字节输出流:
?ByteArrayOutputStream(以数组作为外设,可以将程序中的数据写到数组中)
?FileOutputStream(以文件作为外设,可以将程序中的数据写入到文件中)
高级字节输出流:
?DataOutputStream:可以将带有类型的数据写到文件中
?BufferedOutputStream:提供了一个缓冲区,可以提供写入的效率(调用flush()方法)
?PrintStream: 扩展了很多方法(print(),println()…)

字符输入流:Reader
低级字符输入流:
?CharArrayReader:(将一个字符数组作为外设,可以将字符数组中的数据读到程序中)
?StringReader:(将字符串作为外设,可以将一个字符串的内容读取出来)
?FileReader:(继承了InputStreamReader,将文件作为外设,通常我们获取到得文件流都是字节流)
高级字符输入流:
?InputStreamReader 是字节流通向字符流的桥梁
?BufferedReader:带有缓冲区的字符输入流
?FilterReader


字符输出流:Writer
低级字符输出流:
?CharArrayWriter
?StringWriter
?FileWriter(继承OutputStreamWriter,以文件作为外设)
高级字符输出流:
?OutputStreamWriter:将字节输出流转换成字符输出流
?BufferedWriter:带有缓冲区的字符输出流
?FilterWriter
?PrintWriter:扩展了print/println(),更方便我们的输出操作

  • 大小: 26.2 KB
  • 大小: 30.2 KB
  • 大小: 89.8 KB
  • 大小: 85.5 KB
  • 大小: 42.4 KB
  • 大小: 45.8 KB
  • 查看图片附件
发表评论
用户名: 匿名