JavaIO总结Demo大全(1)

流的概念和作用

学习Java IO,不得不提到的就是JavaIO流。

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流的分类

根据处理数据类型的不同分为:字符流和字节流

根据数据流向不同分为:输入流和输出流

字符流和字节流

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

输入流和输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

Java流操作有关的类或接口:

加载中...

Java流类图结构:

加载中...


Java IO流对象

1. 输入字节流InputStream

定义和结构说明:

从输入字节流的继承图可以看出:

InputStream 是所有的输入字节流的父类,它是一个抽象类。

ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。

ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。意思是FileInputStream类可以通过一个String路径名创建一个对象,FileInputStream(String name)。而DataInputStream必须装饰一个类才能返回一个对象,DataInputStream(InputStream in)。如下图示:

加载中...


实例操作演示:

【案例 】读取文件内容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * 字节流
  * 读文件内容
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        InputStream in= new FileInputStream(f);
        byte [] b= new byte [ 1024 ];
        in.read(b);
        in.close();
        System.out.println( new String(b));
     }
}

注意:该示例中由于b字节数组长度为1024,如果文件较小,则会有大量填充空格。我们可以利用in.read(b);的返回值来设计程序,如下案例:

【案例】读取文件内容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * 字节流
  * 读文件内容
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        InputStream in= new FileInputStream(f);
        byte [] b= new byte [ 1024 ];
        int len=in.read(b);
        in.close();
        System.out.println( "读入长度为:" +len);
        System.out.println( new String(b, 0 ,len));
     }
}

注意:观察上面的例子可以看出,我们预先申请了一个指定大小的空间,但是有时候这个空间可能太小,有时候可能太大,我们需要准确的大小,这样节省空间,那么我们可以这样做:

【案例】读取文件内容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * 字节流
  * 读文件内容,节省空间
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        InputStream in= new FileInputStream(f);
        byte [] b= new byte [( int )f.length()];
        in.read(b);
        System.out.println( "文件长度为:" +f.length());
        in.close();
        System.out.println( new String(b));
     }
}

【案例】逐字节读

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 字节流
  * 读文件内容,节省空间
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        InputStream in= new FileInputStream(f);
        byte [] b= new byte [( int )f.length()];
        for ( int i = 0 ; i < b.length; i++) {
            b[i]=( byte )in.read();
        }
        in.close();
        System.out.println( new String(b));
     }
}

注意:上面的几个例子都是在知道文件的内容多大,然后才展开的,有时候我们不知道文件有多大,这种情况下,我们需要判断是否独到文件的末尾。

【案例】字节流读取文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 字节流
  *读文件
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        InputStream in= new FileInputStream(f);
        byte [] b= new byte [ 1024 ];
        int count = 0 ;
        int temp= 0 ;
        while ((temp=in.read())!=(- 1 )){
            b[count++]=( byte )temp;
        }
        in.close();
        System.out.println( new String(b));
     }
}

注意:当读到文件末尾的时候会返回-1.正常情况下是不会返回-1的。

【案例】DataInputStream类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
  
public class DataOutputStreamDemo{
    public static void main(String[] args) throws IOException{
        File file = new File( "d:" + File.separator + "hello.txt" );
        DataInputStream input = new DataInputStream( new FileInputStream(file));
        char [] ch = new char [ 10 ];
        int count = 0 ;
        char temp;
        while ((temp = input.readChar()) != 'C' ){
            ch[count++] = temp;
        }
        System.out.println(ch);
     }
}

【案例】PushBackInputStream回退流操作

?
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
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PushbackInputStream;
  
/**
  * 回退流操作
  * */
public class PushBackInputStreamDemo{
     public static void main(String[] args) throwsIOException{
        String str = "hello,rollenholt" ;
        PushbackInputStream push = null ;
        ByteArrayInputStream bat = null ;
        bat = new ByteArrayInputStream(str.getBytes());
        push = new PushbackInputStream(bat);
        int temp = 0 ;
        while ((temp = push.read()) != - 1 ){
            if (temp == ',' ){
                 push.unread(temp);
                 temp = push.read();
                 System.out.print( "(回退" +( char ) temp + ") " );
            } else {
                 System.out.print(( char ) temp);
            }
        }
     }
}

2. 输出字节流OutputStream

定义和结构说明:

IO 中输出字节流的继承图可见上图,可以看出:

OutputStream 是所有的输出字节流的父类,它是一个抽象类。

ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。具体例子跟InputStream是对应的。

实例操作演示:

【案例】向文件中写入字符串

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * 字节流
  * 向文件中写入字符串
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        OutputStream out = new FileOutputStream(f);
        String str= "Hello World" ;
        byte [] b=str.getBytes();
        out.write(b);
        out.close();
     }
}

你也可以一个字节一个字节的写入文件:

【案例】逐字节写入文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 字节流
  * 向文件中一个字节一个字节的写入字符串
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        OutputStream out = new FileOutputStream(f);
        String str= "Hello World!!" ;
        byte [] b=str.getBytes();
        for ( int i = 0 ; i < b.length; i++) {
            out.write(b[i]);
        }
        out.close();
     }
}

【案例】向文件中追加新内容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
  * 字节流
  * 向文件中追加新内容:
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String fileName= "D:" +File.separator+ "hello.txt" ;
        File f= new File(fileName);
        OutputStream out = new FileOutputStream(f, true ); //true表示追加模式,否则为覆盖
        String str= "Rollen" ;
        //String str="\r\nRollen"; 可以换行
        byte [] b=str.getBytes();
        for ( int i = 0 ; i < b.length; i++) {
            out.write(b[i]);
        }
        out.close();
     }
}

【案例】复制文件

?
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
/**
  * 文件的复制
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        if (args.length!= 2 ){
            System.out.println( "命令行参数输入有误,请检查" );
            System.exit( 1 );
        }
        File file1= new File(args[ 0 ]);
        File file2= new File(args[ 1 ]);
         
        if (!file1.exists()){
            System.out.println( "被复制的文件不存在" );
            System.exit( 1 );
        }
        InputStream input= new FileInputStream(file1);
        OutputStream output= new FileOutputStream(file2);
        if ((input!= null )&&(output!= null )){
            int temp= 0 ;
            while ((temp=input.read())!=(- 1 )){
                 output.write(temp);
            }
        }
        input.close();
        output.close();
     }
}

【案例】使用内存操作流将一个大写字母转化为小写字母

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 使用内存操作流将一个大写字母转化为小写字母
  * */
import java.io.*;
class hello{
    public static void main(String[] args) throws IOException {
        String str= "ROLLENHOLT" ;
        ByteArrayInputStream input= new ByteArrayInputStream(str.getBytes());
        ByteArrayOutputStream output= new ByteArrayOutputStream();
        int temp= 0 ;
        while ((temp=input.read())!=- 1 ){
            char ch=( char )temp;
            output.write(Character.toLowerCase(ch));
        }
        String outStr=output.toString();
        input.close();
        output.close();
        System.out.println(outStr);
     }
}

【案例】验证管道流:进程间通信

?
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
  * 验证管道流
  * */
import java.io.*;
  
/**
  * 消息发送类
  * */
class Send implements Runnable{
    private PipedOutputStream out= null ;
    public Send() {
        out= new PipedOutputStream();
     }
    public PipedOutputStream getOut(){
        return this .out;
     }
    public void run(){
        String message= "hello , Rollen" ;
        try {
            out.write(message.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } try {
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
}
  
/**
  * 接受消息类
  * */
class Recive implements Runnable{
    private PipedInputStream input= null ;
    public Recive(){
        this .input= new PipedInputStream();
     }
    public PipedInputStream getInput(){
        return this .input;
     }
    public void run(){
        byte [] b= new byte [ 1000 ];
        int len= 0 ;
        try {
            len= this .input.read(b);
        } catch (Exception e) {
            e.printStackTrace();
        } try {
            input.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println( "接受的内容为 " +( new String(b, 0 ,len)));
     }
}
/**
  * 测试类
  * */
class hello{
    public static void main(String[] args) throws IOException {
        Send send= new Send();
        Recive recive= new Recive();
         try {
//管道连接
            send.getOut().connect(recive.getInput());
        } catch (Exception e) {
            e.printStackTrace();
        }
        new Thread(send).start();
        new Thread(recive).start();
     }
}

【案例】DataOutputStream类示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataOutputStreamDemo{
    public static void main(String[] args) throws IOException{
        File file = new File( "d:" + File.separator + "hello.txt" );
        char [] ch = { 'A' , 'B' , 'C' };
        DataOutputStream out = null ;
        out = new DataOutputStream( new FileOutputStream(file));
        for ( char temp : ch){
            out.writeChar(temp);
        }
        out.close();
     }
}

【案例】ZipOutputStream类

先看一下ZipOutputStream类的继承关系

java.lang.Object

java.io.OutputStream

java.io.FilterOutputStream

java.util.zip.DeflaterOutputStream

java.util.zip.ZipOutputStream

?
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
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
  
public class ZipOutputStreamDemo1{
    public static void main(String[] args) throws IOException{
        File file = new File( "d:" + File.separator + "hello.txt" );
        File zipFile = new File( "d:" + File.separator + "hello.zip" );
        InputStream input = new FileInputStream(file);
        ZipOutputStream zipOut = new ZipOutputStream( new FileOutputStream(
                 zipFile));
        zipOut.putNextEntry( new ZipEntry(file.getName()));
        // 设置注释
        zipOut.setComment( "hello" );
        int temp = 0 ;
        while ((temp = input.read()) != - 1 ){
            zipOut.write(temp);
        }
        input.close();
        zipOut.close();
     }
}

【案例】ZipOutputStream类压缩多个文件

?
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
33
34
35
36
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
  
/**
  * 一次性压缩多个文件
  * */
public class ZipOutputStreamDemo2{
    public static void main(String[] args) throws IOException{
        // 要被压缩的文件夹
        File file = new File( "d:" + File.separator + "temp" );
        File zipFile = new File( "d:" + File.separator + "zipFile.zip" );
        InputStream input = null ;
        ZipOutputStream zipOut = new ZipOutputStream( new FileOutputStream(
                 zipFile));
        zipOut.setComment( "hello" );
        if (file.isDirectory()){
            File[] files = file.listFiles();
            for ( int i = 0 ; i < files.length; ++i){
                 input = newFileInputStream(files[i]);
                 zipOut.putNextEntry(newZipEntry(file.getName()
                         + File.separator +files[i].getName()));
                int temp = 0 ;
                 while ((temp = input.read()) !=- 1 ){
                     zipOut.write(temp);
                 }
                 input.close();
            }
        }
        zipOut.close();
     }
}

【案例】ZipFile类展示

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipFile;
  
/**
  *ZipFile演示
  * */
public class ZipFileDemo{
    public static void main(String[] args) throws IOException{
        File file = new File( "d:" + File.separator + "hello.zip" );
        ZipFile zipFile = new ZipFile(file);
        System.out.println( "压缩文件的名称为:" + zipFile.getName());
     }
}

【案例】解压缩文件(压缩文件中只有一个文件的情况)

?
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
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
  
/**
  * 解压缩文件(压缩文件中只有一个文件的情况)
  * */
public class ZipFileDemo2{
    public static void main(String[] args) throws IOException{
        File file = new File( "d:" + File.separator + "hello.zip" );
        File outFile = new File( "d:" + File.separator + "unZipFile.txt" );
        ZipFile zipFile = new ZipFile(file);
        ZipEntry entry =zipFile.getEntry( "hello.txt" );
        InputStream input = zipFile.getInputStream(entry);
        OutputStream output = new FileOutputStream(outFile);
        int temp = 0 ;
        while ((temp = input.read()) != - 1 ){
            output.write(temp);
        }
        input.close();
        output.close();
     }
}

【案例】ZipInputStream类解压缩一个压缩文件中包含多个文件的情况

?
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
33
34
35
36
37
38
39
40
41
42
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
  
/**
  * 解压缩一个压缩文件中包含多个文件的情况
  * */
public class ZipFileDemo3{
    public static void main(String[] args) throws IOException{
         File file = new File( "d:" +File.separator + "zipFile.zip" );
        File outFile = null ;
        ZipFile zipFile = new ZipFile(file);
        ZipInputStream zipInput = new ZipInputStream( new FileInputStream(file));
        ZipEntry entry = null ;
         InputStream input = null ;
        OutputStream output = null ;
        while ((entry = zipInput.getNextEntry()) != null ){
            System.out.println( "解压缩" + entry.getName() + "文件" );
            outFile = new File( "d:" + File.separator + entry.getName());
            if (!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdir();
            }
            if (!outFile.exists()){
                 outFile.createNewFile();
            }
            input = zipFile.getInputStream(entry);
            output = new FileOutputStream(outFile);
            int temp = 0 ;
            while ((temp = input.read()) != - 1 ){
                 output.write(temp);
            }
            input.close();
            output.close();
        }
     }
}

3.字节流的输入与输出的对应图示

加载中...

图中蓝色的为主要的对应部分,红色的部分就是不对应部分。紫色的虚线部分代表这些流一般要搭配使用。从上面的图中可以看出Java IO 中的字节流是极其对称的。哲学上讲“存在及合理”,现在我们看看这些字节流中不太对称的几个类吧!



  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建型模式 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) 2 结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Filter、Criteria Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 代理模式(Proxy Pattern) 3 行为型模式 这些设计模式特别关注对象之间的通信。 责任链模式(Chain of Responsibility Pattern) 命令模式(Command Pattern) 解释器模式(Interpreter Pattern) 迭代器模式(Iterator Pattern) 中介者模式(Mediator Pattern) 备忘录模式(Memento Pattern) 观察者模式(Observer Pattern) 状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) 4 J2EE 模式 这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。 MVC 模式(MVC Pattern) 业务代表模式(Business Delegate Pattern) 组合实体模式(Composite Entity Pattern) 数据访问对象模式(Data Access Object Pattern) 前端控制器模式(Front Controller Pattern) 拦截过滤器模式(Intercepting Filter Pattern) 服务定位器模式(Service Locator Pattern) 传输对象模式(Transfer Object Pattern)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值