IO包中的其他流:
1.打印流
a)PrintWriter(写-->print打印) 与PrintStream (字符流)
1 PrintWriter用法一:其实它是对一个Writer进行了封装
2 package com.javami.kudyTest;
3 import java.io.FileNotFoundException;
4 import java.io.PrintWriter;
5 public class PrintWriterTest {
6 /*
7 * PrintWriter 是对Writer 进行了一个封装
8 */
9 public static void main(String[]args) throws FileNotFoundException
10 {
11 PrintWriter pw = new PrintWriter("src/a.txt");
12 int num = 98; //char类型占了一个类型
13 // pw.write(num); //输出了一个char类型的
14 pw.print(num); //输出的是int类型的
15 /*
16 * 其实里面做的事情
17 * String str = str.valueOf(int) //转换成字符串 再转换为字节 98
18 * 而我们系统默认的字节编码格式每一个字符是占了1位的,所以显示出来的结果为是2bytes
19 * ---------------------------------
20 * String str = str.valueOf(num);
21 * byte[]buf = str.getBytes(); //转换成字节
22 * for(byte ch :buf)
23 * while(ch);
24 */
25 pw.close();
26
27 }
28 }
29 第二:PrintStream
30 是继承于OutputStream(输出流(字节流))
31 package com.javami.kudyTest;
32 import java.io.FileNotFoundException;
33 import java.io.PrintStream;
34 public class PrintStreamTest {
35 /*
36 * PrintStream 的应用:
37 * 这是一个字节流: 输出字节流
38 * (写数据)
39 * 继承于:OutputStream
40 */
41 public static void main(String[]args) throws FileNotFoundException
42 {
43 PrintStream ps = new PrintStream("src/b.txt");
44 // int num = 98;
45 // ps.write(num);
46
47 int num = 97;
48 ps.print(num); //本质上是没有区别.但是内部实现原理就有区别 (占了2个字节)
49
50 /*
51 * 实现原理和PrintWriter很想:
52 * String str = str.valueOf(num); //转换成字符
53 * byte[] buf = str.getBytes();
54 * for(byte b : buf)
55 * {
56 * 字节数现在为2 存入的是字节.之后系统会根据系统的编码格式进行了一个解码
57 * }
58 */
59 }
60 }
2.序列流
b)SequencelnputStream(假设我有多个文本.需要合并成一个文本)
1 package com.javami.kudyTest;
2
3 import java.io.FileInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.io.FileOutputStream;
8 import java.io.SequenceInputStream;
9 import java.util.Enumeration;
10 import java.util.Vector;
11 import java.util.Iterator;
12 public class SequenceInputStreamTest {
13 /*
14 * 序列流
15 */
16 public static void main(String[]args) throws IOException
17 {
18 /*
19 * 读取两个文本的方式
20 */
21 InputStream is1 = new FileInputStream("src/a.txt");
22 InputStream is2 = new FileInputStream("src/b.txt");
23 OutputStream os = new FileOutputStream("src/c.txt");
24 //读取两个参数
25 SequenceInputStream sis = new SequenceInputStream(is1,is2);
26 byte[] buf = new byte[1024];
27 int ch;
28 while((ch=sis.read(buf))!=-1)
29 {
30 os.write(buf,0,ch);
31 }
32
33 //关流,由于SequenceInputStream 是一个包装类.但把这个流关闭.会把底层的两个流也关
34 sis.close();
35 os.close();
36
37 /*
38 * 如果我有很多文本需要合并内容的,但是构造方法只能传递进去.这时候如果用到带两个参数的构造方法来传递就不是太方便啦~~
39 * 那么我可以使用使用到枚举+集合
40 */
41 InputStream isone = new FileInputStream("src/a.txt");
42 InputStream istwo = new FileInputStream("src/b.txt");
43 InputStream isthree = new FileInputStream("src/c.txt");
44 OutputStream osone = new FileOutputStream("src/happy.txt");
45 Vector<InputStream> v = new Vector<InputStream>();
46 v.add(isone);
47 v.add(istwo);
48 v.add(isthree);
49 /* //枚举里面我需要使用的是InputStream
50 Enumeration<InputStream> e = v.elements();
51 //读取枚举里面的内容.再写入到一个文本里面去
52 //里面只能放一个枚举类型.并且这个枚举类型的泛型是继承于InputStream的
53 SequenceInputStream sisone = new SequenceInputStream(e); //读写集合里面的内容.已经合并在一起啦
54 int len;
55 while((len=sisone.read())!=-1)
56 {
57 osone.write(len);
58 }
59 //关流
60 sisone.close(); //这个如果关流.已经把底层的三个流已经被关闭
61 osone.close();*/
62
63 //看第二种方式: 产生一个迭代器
64 final Iterator<InputStream> it = v.iterator();
65 SequenceInputStream sistwo =
66 new SequenceInputStream(new Enumeration<InputStream>(){
67
68 @Override
69 //这里面是否有更多的元素呢?
70 public boolean hasMoreElements() {
71
72 return it.hasNext();
73 }
74
75 @Override
76 //下一个元素为多少呢?
77 public InputStream nextElement() {
78 // TODO Auto-generated method stub
79 return it.next();
80 }
81
82 });
83 int len;
84 //一个字符一个字符读取进去的方式啊?没有包装的.哥们.难道你忘记啦?
85 //不读出来怎么写? 您教我.
86 while((len=sistwo.read())!=-1)
87 {
88 osone.write(len); //读一个字节.写一个字节
89 }
90
91 }
92 }
3.操作对象
c)ObjectinputStream与ObjectOutputStream(对象必须要实现Serializable这个接口,做为标记需要使用序列 或者序列化
1 package com.javami.kudyTest;
2 import java.io.FileInputStream;
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.io.ObjectInputStream;
6 import java.io.ObjectOutputStream;
7 import java.io.FileOutputStream;
8 import java.io.Serializable;
9
10 public class ObjectStreamTest {
11 /*
12 * 对象序列化:
13 * 有的时候我们需要找一种数据对内存中的对象进行描述.便于保存.这时,可能每个程序员都有自己的想法.
14 * 都会去使用自己习惯的方式,对象的序列化,就是按照java规定格式对对象转换成一种数据,编译保存.这个过程就是对象的序列化
15 * 将数据的格式转换成对象就是叫做反序列化
16 */
17 public static void main(String[]args) throws FileNotFoundException, IOException, ClassNotFoundException
18 {
19 /* Person p1 = new Person("张三",18);
20 Person p2 = new Person("王五",19);
21 Person p3 = new Person("李四",20);
22 Person p4 = new Person("大毛",21);*/
23
24 /*
25 ObjectOutputStream oos =
26 new ObjectOutputStream(new FileOutputStream("src/1.txt"));
27 oos.writeObject(p1); //父类型的引用可以指向子类型的对象
28 oos.writeObject(p2);
29 oos.writeObject(p3);
30 oos.writeObject(p4);
31 oos.close();
32 /1.对象的序列化的第一种方式
33 */
34
35 /*
36 * 假设我们已经序列化:现在需要反序列化>需要把对象里面的内容输出去
37 */
38 ObjectInputStream ois =
39 new ObjectInputStream(new FileInputStream("src/1.txt"));
40
41
42
43 while(true)
44 {
45 try
46 {
47 Person p =(Person)ois.readObject();
48 System.out.println(p);
49 }catch(IOException e)
50 {
51 return ;
52 }
53
54 //如果是异常的,咱们就不执行
55 }
56
57 }
58 }
59
60
61
62 /*
63 * 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
64 * 由于我们希望序列化的是Person 这个类.所以我们要实现这个接口
65 * 这个主要就是做一个下标识
66 * 但异常出现的错误为:NotSerializableException 就是说明了: 有一个类还没有被标记即将要序列化
67 */
68 class Person implements Serializable
69 {
70 private String name;
71 private int age;
72 Person(){}
73 Person(String name,int age)
74 {
75 this.name = name;
76 this.age = age;
77 }
78 @Override
79 public String toString()
80 {
81 return this.name +"@"+this.age;
82 }
83 }
84
85 第二种方式: 可以利用集合去做一个问题
86 (输入数据 通过集合读 通过遍历集合写.) 建议使用哦
87 package com.javami.kudyTest;
88
89 import java.io.FileInputStream;
90 import java.io.FileNotFoundException;
91 import java.io.FileOutputStream;
92 import java.io.IOException;
93 import java.io.ObjectInputStream;
94 import java.io.ObjectOutputStream;
95 import java.io.Serializable;
96 import java.util.ArrayList;
97
98 /*
99 * 可以通过集合去写入数据 ... 之后再通过集合遍历数据..
100 */
101 public class ObjetcStreamTest2 {
102 public static void main(String[]args) throws FileNotFoundException, IOException, ClassNotFoundException
103 {
104
105 /*
106 * 1.序列化
107
108 Person p1 = new Person("张三",18);
109 Person p2 = new Person("王五",19);
110 Person p3 = new Person("李四",20);
111 Person p4 = new Person("大毛",21);
112 ObjectOutputStream oos =
113 new ObjectOutputStream(new FileOutputStream("src/Object.txt"));
114 ArrayList<Person> al = new ArrayList<Person>();
115 al.add(p1);
116 al.add(p2);
117 al.add(p3);
118 al.add(p4);
119 oos.writeObject(al);
120 oos.close();*/
121
122 /*
123 * 反序列化
124 */
125 ObjectInputStream ois =
126 new ObjectInputStream(new FileInputStream("src/Object.txt"));
127 //要把这个类型强制转换
128 ArrayList<Person> al = (ArrayList<Person>)ois.readObject();
129 for(Person p : al)
130 {
131 System.out.println(p);
132 }
133 ois.close();
134 }
135 }
136
137 /*
138 * Person 实现一个接口,标记为即将序列化或者反序列化
139 */
140 class Person implements Serializable
141 {
142 private String name;
143 private int age;
144 Person(){}
145 Person(String name,int age)
146 {
147 this.name = name;
148 this.age = age;
149 }
150 @Override
151 public String toString()
152 {
153 return this.name +"@"+this.age;
154 }
155 }
将图片切割成若干份,每10k一个文件, 再使用序列流组合成图片(为什么第一张图片可以看得到呢.特征码的问题)
小练习:
1 package com.javami.kudyTest;
2 import java.io.File;
3 import java.io.FileInputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.SequenceInputStream;
9 import java.util.Enumeration;
10 import java.util.Vector;
11 public class PictureCut {
12
13
14 public static void main(String[] args) {
15 File file = new File("f:/a/1.jpg");
16 try
17 {
18 //cutPicture(file);
19 splicePicture();
20 }catch (IOException e) {
21 // TODO: handle exception
22 e.printStackTrace();
23 }
24 }
25 /**
26 * 将图片分成若干份,每10K一份,再使用序列流组合图片
27 * 思路: 需要定义一个FileinputStream 读取一个图片. 再写入到一个FileInputStream里面去
28 * 定义一个byte[] buf = new byte[1024]; //缓冲区定义成1k
29 * int count = 0; //标记循环10次.也就是10K
30 * int num = 1; //标记图片命名
31 * int len ; //返回的字符
32 * 循环读取一个图片.当读取到10K的时候.咱们就写入到一个新的字节流里面去..
33 * 注意count每一次标记一下.当count等于10的时候.咱们要重新清空一下.
34 *
35 *
36 */
37 private static void cutPicture(File file) throws IOException
38 {
39 FileInputStream fis = null;//输入
40 FileOutputStream fos = null; //输出流
41 try
42 {
43 fis = new FileInputStream(file);
44 fos = new FileOutputStream("f:/a/a1.jpg"); //写入到这个文本里面去
45 byte[] buf = new byte[1024]; //1K的大小
46 int count = 0; //标记如果是读到10K就是一个图片
47 int len;
48 int num = 1; //等待给一个图片标号
49 while((len=fis.read(buf))!=-1) //意思: 从缓冲区读取10K的字节内容赋给len 0,len最大字符数
50 {
51 //每次从缓冲区那里边读取1K
52 if(count==10)
53 {
54 count=0; //清空一下.
55 fos.close(); //关闭上一次的流
56 fos = new FileOutputStream("f:/a/a"+(++num)+".jpg");
57 }
58 //从缓冲区里面写入buf 0 ,len的内容 .是不是刚好1K的内容
59 fos.write(buf,0,len); //把10K内容写入进去 //0-9 刚好10次
60 //标记是否是10次 0 - 9 刚好10次 10 -19 刚好10次 ...
61 count++;
62 }
63
64 }finally
65 {
66 try
67 {
68 if(fis!=null)
69 fis.close();
70 }finally
71 {
72 if(fos!=null)
73 fos.close();
74 }
75 }
76 }
77
78
79
80 /*
81 * 并且一个图片,咱们可以先读取一个图片
82 * 可以所以用到枚举
83 */
84 private static void splicePicture() throws IOException
85 {
86 /*
87 * Vector是一个集合
88 */
89
90 Vector<InputStream> v = new Vector<InputStream>(); //读取图片
91 SequenceInputStream sis = null;
92 FileOutputStream fos = null;
93 v.add(new FileInputStream("F:/a/a1.jpg"));
94 v.add(new FileInputStream("F:/a/a2.jpg"));
95 v.add(new FileInputStream("F:/a/a3.jpg"));
96 v.add(new FileInputStream("F:/a/a4.jpg"));
97 v.add(new FileInputStream("F:/a/a5.jpg"));
98 v.add(new FileInputStream("F:/a/a6.jpg"));
99 v.add(new FileInputStream("F:/a/a7.jpg"));
100 v.add(new FileInputStream("F:/a/a8.jpg"));
101 v.add(new FileInputStream("F:/a/a9.jpg"));
102 Enumeration<InputStream> e = v.elements(); //枚举类型
103 try
104 {
105 sis = new SequenceInputStream(e);
106 fos = new FileOutputStream("src/dj.jpg");
107 int ch;
108 while((ch=sis.read())!=-1)
109 {
110 //写入字节流
111 fos.write(ch);
112 }
113 }finally
114 {
115 try
116 {
117 if(sis!=null)
118 sis.close();
119 }
120 finally
121 {
122 if(fos!=null)
123 fos.close();
124 }
125 }
126
127
128 }
129
130 }
4.操作基本数据类型
d)DataInputStream 与DataOutputStream
1 package com.javami.kudyTest;
2 import java.io.DataOutputStream;
3 import java.io.DataInputStream;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 public class DataStreamTest {
9
10 /**
11 * 操作基本数据类型:
12 * 格式化数据类型: int类型占了4个字节.写在文本里面也是占了4个字节
13 * @throws IOException
14 */
15 public static void main(String[] args) throws IOException
16 {
17 /*DataInputStream dis =
18 new DataInputStream(new FileInputStream("src.ohoh.txt"));
19 int num = 98;*?里面有98给我读取吗?*/
20
21 /*DataOutputStream dos =
22 new DataOutputStream(new FileOutputStream("src/ohoh.txt")); //写入数据
23 int num = 98;
24 //dos.writeInt(num); 是以int类型所占的字节写入进去,4个字节
25 String str = "abc中国人";
26 dos.writeUTF(str);//是以UTF编码写入进去 汉字占3个字节
27 */
28 //读
29 DataInputStream dis = new DataInputStream(new FileInputStream("src/ohoh.txt"));
30 /*
31 * 是与UTF编码写进去的,咱们就用相同的码表去解码
32 */
33 String datat = dis.readUTF();
34 System.out.println(datat);
35 dis.close();
36 /*
37 * 将一个 int 值以 4-byte 值形式写入基础输出流中,先写入高字节。如果没有抛出异常,则计数器 written 增加 4。
38 *
39 */
40
41 }
42
43 }
5.操作内存缓冲数组
e)ByteArrayStream与CharArrayReader
1 package com.javami.kudyTest;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.IOException;
8
9
10 public class ByteArrayStream {
11
12 /*
13 * ByteArrayInputStream 读取字节
14 * ByteArrayOutputStream 写入字节
15 */
16 public static void main(String[]args) throws IOException
17 {
18 String chinese = "我是中国人.钓鱼岛是咱们中国的同胞的.jb帝国主义滚~~~";
19
20 byte[] buf = chinese.getBytes(); //获取到字节数组
21
22 //读取字节包装流
23 ByteArrayInputStream bais = new ByteArrayInputStream(buf);
24 int len = bais.available(); //获取到字节里面有多少个字节
25 byte[] bufs = new byte[len]; //自定义大小做缓冲区.为什么这样做.以为我们这样做.可以节省内存空间.
26 bais.read(bufs); //我们把定义存储到自定义缓冲区里面去
27 String happy = new String(bufs);
28 System.out.println(happy);
29 bais.close();
30
31 //写入字节包装类
32 ByteArrayOutputStream bos =
33 new ByteArrayOutputStream();
34 bos.write("jb滚出钓鱼钓".getBytes());
35 byte[] jbs = bos.toByteArray(); //获取里面的数据
36 System.out.println(new String(jbs));
37 bos.close();
38 }
39 /*
40 * 一般的用法:
41 * DataoutputStream dos = new DataOutputStream(new ByteArrayOutputStream());
42 */
43
44 }
6.管道流
PipedinputStream与PipedOutputStream
1 package com.javami.kudyTest;
2
3 import java.io.IOException;
4 import java.io.PipedInputStream;
5 import java.io.PipedOutputStream;
6
7 public class PipedStreamTest {
8 public static void main(String[]args) throws IOException
9 {
10 //1.输入流读
11 PipedInputStream pis = new PipedInputStream();
12 //2.输出流写
13 PipedOutputStream pos = new PipedOutputStream();
14
15 //3.输入流连接输出流
16 pis.connect(pos);
17
18 //从服务器的角度来说:向用户发出信息 发出的字节
19 pos.write("欢迎来到本站".getBytes());
20
21 int len = pis.available();
22 byte[] buf = new byte[len]; //获取到一个自定义缓冲区大小数组
23 //自定义一个缓冲区大小.把内容读取到这边来
24 pis.read(buf); //把内容读取到一个buf里面去
25 //已经被独到了buf里面去
26 String user = new String(buf);
27 System.out.println(user);
28 pis.close();
29 pos.close();
30 }
31 }
7.RandomAccessFile 实现了该类的实例支持对随机文件的读取和写入
1 package com.javami.kudyTest;
2 import java.io.IOException;
3 import java.io.RandomAccessFile;
4
5 public class RandomAccessFileTest {
6
7 /**
8 * 编写一个程序,记录该程序运行次数,运行满足30day.就提示软件到期
9 * @throws IOException
10 * @throws NumberFormatException
11 */
12 public static void main(String[] args) throws IOException
13 {
14 //打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
15 //读一次.写一次.读一次.写一次.
16 RandomAccessFile raf = new RandomAccessFile("src/count.txt","rw");
17 int count = Integer.parseInt(raf.readLine()); //转换成int类型
18 count++;
19 if(count>10)
20 {
21 System.out.println("软件已经到期");
22 return ; //结束整个循环
23 }
24 System.out.println("已经使用了"+count+"次,请马上续费~~");
25 String str = String.valueOf(count);
26 //再写入进去.就是一读一些的概念啦
27 /*
28 * 注意这个偏移量的问题.如果我们不设置偏移量的时候.
29 * 他执行的顺序是: 012 那么程序判断成12就结束啦..
30 * 设置偏移量为零:
31 * 位置是不会懂的0
32 * 1
33 * 2
34 * 3...这样
35 */
36 raf.seek(0);
37 raf.write(str.getBytes()); //把字节写进去 把字节写进去.
38 raf.close();
39
40 }
41
42 }
这个学习的说好不好,说坏不坏.但是在休息中浪费的时间比较多..
希望以后好好努力..加油..
posted on 2012-08-14 13:10
、小细 阅读(135)
评论(0) 编辑 收藏