目录:
一、什么是IO流
二、流的分类
1、节点流
2、处理流
2.1缓冲流
2.2转换流
2.3数据流
2.4Print流(打印流)
2.5 Object流(对象流)
一、什么是IO流
IO流即是输入(Input)输出(Output)流,输入和输出的方向是针对程序而言的,比如现在要读取文件内容,那么就是输入流,是对于程序而言的。流其实就是传输数据用的,流位于java.io包当中,最主要的就是字符流和字节流,Java当中字符是两个字节。关于流的类都继承自下面抽象类
注意这几个是抽象类,无法实例化。
二、流的分类
一般按照处理数据单位分为字节流和字符流,这里按照功能分类,分成节点流和处理流。
1、节点流
可以看到节点流有处理文件的,有处理内存数组(Memory Array)的,内存字符串的、以及Pipe管道的。
下面以处理File为例,先介绍字节流:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/** * 读取路径下的文件内容,显示在控制台 */ package com.zhoucy.io; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class TestFileInputStream { public static void main(String[] args) { int b = 0; FileInputStream in = null; try{ in = new FileInputStream("e:/java/io/DataTest.java"); } catch(FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } try{ long num = 0; while((b=in.read())!=-1){ System.out.print((char)(b)); num++; } System.out.println(); System.out.println("共读取了"+num+"个字节"); in.close(); } catch (IOException e) { System.out.println("文件读取错误"); System.exit(-1); } } }
输出结果就不贴了,就是将文件内容打印出来。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28/** * 输入参数args[0]、args[1],将前面的文件拷贝到后面的文件中 * 完成复制拷贝的功能 */ package com.zhoucy.io; import java.io.*; public class TsetFileOutputStream { public static void main(String[] args) { int b = 0; long num = 0L; FileInputStream in = null; FileOutputStream out = null; try{ in = new FileInputStream(args[0]); out = new FileOutputStream(args[1]); while((b=in.read())!=-1){ out.write(b); } in.close(); out.close(); } catch (IOException e) { System.out.println("something is wrong!"); System.exit(-1); } System.out.println("文件已复制"); } }
该例在eclipse中运行,先在 Run<<Run Configurations<<Arguments中设置好传给main的参数,多参数用空格隔开。运行结果是在指定的args[1]路径下复制一份args[0]路径下指定的文件。
下面用字符流完成相同拷贝功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.zhoucy.io; import java.io.*; public class TestFileReader { public static void main(String[] args) { int b = 0; FileReader fr = null; FileWriter fw = null; try{ fr = new FileReader(args[0]); fw = new FileWriter(args[1]); while((b=fr.read())!=-1){ fw.write(b); } fr.close(); fw.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); } catch (IOException e1) { System.out.println("文件读取错误"); } System.out.println("文件复制成功"); } }
同样是将指定路径下的文件复制一份到args[1]指定的路径下。
2、处理流
2.1 缓冲流
缓冲流要套接在相应的节点流上,对读写的数据提供缓冲的功能,提高读写效率,并且在缓冲流上,有一些新的方法可供使用。
BufferedReader提供了readLine方法,用以读取一行字符串,BufferedWriter提供了newLine用于写入一个行分隔符。对于输出的缓冲流,会将泻出去的数据先在内存中缓存,使用flush方法会使内存中的数据立刻写出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.zhoucy.io; import java.io.*; public class TestBufferStream { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("e:/java/io/test.java"); BufferedInputStream bis = new BufferedInputStream(fis); int c = 0; System.out.println((char)bis.read()); System.out.println((char)bis.read()); bis.mark(30);//做标记 for(int i=0;i<=10 && (c=bis.read())!=-1;i++){ System.out.print((char)c+" "); } System.out.println(); bis.reset();//回到做标记的地方(类似于C文件指针归位) for(int i=0;i<=10 && (c=bis.read())!=-1;i++){ System.out.print((char)c+" "); } bis.close(); } catch (IOException e) { e.printStackTrace(); } } }
上例是读取test.java这个文件里面的内容,使用缓冲流,套接在字节流上。其中mark和reset方法是成对使用的,mark先标记一下,类似于C语言的文件指针,先标记在调用mark的地方,后面调用reset的时候,使文件指针回到调用mark标记的地方,(java里应该不叫文件指针,但是原理感觉一样)mark后面的参数,是表示,标记以后,继续读取内容,但是不能超过mark的参数指定的字符数,超过以后,mark标记就失效了,reset也就没用了。
test.java内容是:
1
2
3
4
5
6
7
8
9
10class Animal { String name; Animal(String name) { this.name = name; } public void info() { System.out.println("I am Animal"); } }
读取的结果是:
下面举一个字符缓冲流例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package com.zhoucy.io; import java.io.*; public class TestBufferedReWr { public static void main(String[] args) { FileReader fr = null; FileWriter fw = null; try{ fr = new FileReader("e:/java/io/br.txt"); fw = new FileWriter("e:/java/io/br.txt"); BufferedReader br = new BufferedReader(fr); BufferedWriter bw = new BufferedWriter(fw); String s; for(int i=0;i<100;i++){ s = String.valueOf(Math.random()); bw.write(s); bw.newLine(); } bw.flush(); for(int i=0;i<10;i++) { s = br.readLine(); System.out.println(s); } } catch (IOException e) { e.printStackTrace(); } } }
该例是往br.txt文件当中写入100行随机数,再从br.txt文件当中读取10行打印到控制台。
执行完以后,br.txt有100行随机数据,打印台信息如下:
2.2 转换流
用于将字节数据转换成字符数据,下例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27/** * 输入英文字符串,转成大写输出 * 输入exit退出 */ package com.zhoucy.io; import java.io.*; public class TestTransForm { public static void main(String[] args) { try{ //从控制台输入 InputStreamReader isr = new InputStreamReader(System.in); //转成字符流 BufferedReader br = new BufferedReader(isr); String s; s = br.readLine(); while(s!=null) { if(s.equalsIgnoreCase("exit")) break; System.out.println(s.toUpperCase()); s = br.readLine(); } br.close(); } catch (IOException e) { e.printStackTrace(); } } }
2.3 数据流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.zhoucy.io; import java.io.*; public class TestDataArray { public static void main(String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); try { dos.writeDouble(Math.random()); dos.writeBoolean(true); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); //返回该字节数组剩余的字节数8+1等于9字节 System.out.println(bais.available()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); dos.close(); dis.close(); } catch (IOException e) { e.printStackTrace(); } } }
2.4 打印流
这两项的输出操作不会抛出异常,并且有自动flush功能。
例1:往指定文件打印
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package com.zhoucy.io; import java.io.*; public class TestPrintStream1 { public static void main(String[] args) { PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream("e:/java/io/dat1.txt"); ps = new PrintStream(fos); } catch (IOException e) { e.printStackTrace(); } if(ps != null){ System.setOut(ps);//往指定的流里面打印 } int ln = 0; for(char c = 0; c <= 100; c++){ System.out.print(c+ " "); if(ln++ >=30){ System.out.println(); ln = 0; } } } }
例2:打印指定文件的内容到控制台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//打印文件内容 package com.zhoucy.io; import java.io.*; public class TestPrintStream2 { public static void main(String[] args) { String filename = args[0]; if(filename!=null){ list(filename,System.out); } } public static void list(String f,PrintStream fs){ try { BufferedReader br = new BufferedReader(new FileReader(f)); String s = null; while((s=br.readLine())!=null){ fs.println(s); } br.close(); } catch (IOException e) { fs.println("无法读取文件"); } } }
结果就不贴了,把参数传给args[0]就行了。
例3:把用户在控制台所做的操作打印到日志文件当中去,程序功能还是输入字母串就输出大写字母串,但是把用户的所有输入和日期记录到后台日志文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//将控制台做的操作打印记录到log文件里面 package com.zhoucy.io; import java.util.*; import java.io.*; public class TestPrintStream3 { public static void main(String[] args) { String s = null; BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); try { FileWriter fw = new FileWriter ("e:/java/io/_log.log", true); //Log4J PrintWriter log = new PrintWriter(fw); while ((s = br.readLine())!=null) { if(s.equalsIgnoreCase("exit")) break; System.out.println(s.toUpperCase()); log.println("-----"); log.println(s.toUpperCase()); log.flush(); } log.println("==="+new Date()+"==="); log.flush(); log.close(); } catch (IOException e) { e.printStackTrace(); } } }
2.5 Object流(对象流)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import java.io.*; public class TestObjectIO { public static void main(String args[]) throws Exception { T t = new T(); t.k = 8; FileOutputStream fos = new FileOutputStream("d:/share/java/io/testobjectio.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(t); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("d:/share/java/io/testobjectio.dat"); ObjectInputStream ois = new ObjectInputStream(fis); T tReaded = (T)ois.readObject(); System.out.println(tReaded.i + " " + tReaded.j + " " + tReaded.d + " " + tReaded.k); } } class T implements Serializable//标记性接口,没有方法,告知编译器,表示该类可以被序列化 { int i = 10; int j = 9; double d = 2.3; //transient修饰的成员变量在序列化的时候不予考虑, //序列化之后输出对象,该值为0 transient int k = 15; }
最后
以上就是有魅力枕头最近收集整理的关于JavaSE学习笔记之-----IO流的全部内容,更多相关JavaSE学习笔记之-----IO流内容请搜索靠谱客的其他文章。
发表评论 取消回复