JAVA I/0流学习(二)

1.BufferedInputStream与BufferedOutputStream类

BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。

BufferedInputStream类有两个构造方法:

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int size)

第一种形式的构造方法创建了一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象位于InputStream类对象之前。

BufferedOutputStream的构造方法和BufferedInputSream类似

注意:flush()方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入外设。习惯上称这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效。当调用close()方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件中。

 2.BufferedReader与BufferedWriter类

BufferedReader类与BufferedWriter类分别继承Reader类和Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。

BufferedReader常用的方法如下:

int read()   读取单个字符。

int read(char[] cbuf,int off,int len)   将字符读入到数组的某一部分。返回读取的字符数。达到尾部 ,返回-1。

String readLine()   读取一个文本行。

 void close()   关闭该流。并释放与该流相关的所有资源。

BufferedWriter常用方法如下:

void write(char ch)   写入单个字符。

void write(char []cbuf,int off,int len)   写入字符数据的某一部分。

void write(String s,int off,int len)   写入字符串的某一部分。

void newLine()   写入一个行分隔符。

void flush()   刷新该流中的缓冲。将缓冲数据写到目的文件中去。

void close()   关闭此流,再关闭前会先刷新它。

import java.io.*;

public class BufferReader_and_BufferWriter {

public static void main(String[] args) {
    String content[]={"你站在桥上看风景", "看风景的人在楼上看你", "明月装饰了你的窗子", "你装饰了别人的梦" };
    File file=new File("C:\\Users\\liuyue\\Desktop\\test.txt");
    try {
        FileWriter fileWriter=new FileWriter(file);
        BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);
        for (int i=0;i<content.length;i++){
            bufferedWriter.write(content[i]);
            bufferedWriter.newLine();
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        fileWriter.close();
    }catch (Exception e){
        System.out.println(e);
    }
    try {
        FileReader fileReader=new FileReader(file);
        BufferedReader bufferedReader=new BufferedReader(fileReader);
        String s=null;
        int i=0;
        while ((s=bufferedReader.readLine())!=null){
            i++;
            System.out.println("第"+i+"行:"+s);
        }
        bufferedReader.close();
        fileReader.close();
    }catch (Exception e){
        System.out.println(e);
    }
}



}

3.DataInputSteam和DataOutputStream类

DataInputStream和DataOutputStream类允许应用程序以机器无光的方式从底层输入流中读取基本java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是哪种字节。

两者的构造方法也大同小异:

DataInputStream(InputStream in)

DataOutputStream(OutputStream out)

DataInputStream的主要方法有:

int read(byte[] b)   从输入流中读取一定的字节,存放到缓冲数组b中。返回缓冲区中的总字节数。

int read(byte[] buf,int off,int len)   从输入流中一次读入len个字节存放在字节数组中的偏移off个字节及后面位置。

String readUTF()   读入一个已使用UTF-8修改版格式编码的字符串

String readLine()   读入一行

boolean readBoolean   读取一个boolbean类型的值

int readInt()   读取一个int类型的值

byte readByte()   读取一个byte类型的值

char readChar()   读取一个char类型的值

DataOutputStream的方法主要有:

void write(byte[] b,int off,int len)   将byte数组off角标开始的len个字节写到OutputStream 输出流对象中。

void write(int b)   将指定字节的最低8位写入基础输出流。

void writeBoolean(boolean b)   将一个boolean值以1-byte形式写入基本输出流。

void writeByte(int v)   将一个byte值以1-byte值形式写入到基本输出流中。

void writeBytes(String s)   将字符串按字节顺序写入到基本输出流中。

void writeChar(int v)   将一个char值以2-byte形式写入到基本输出流中。先写入高字节。

void writeInt(int v)   将一个int值以4-byte值形式写入到输出流中先写高字节。

void writeUTF(String str)   以机器无关的的方式用UTF-8修改版将一个字符串写到基本输出流。该方法先用writeShort写入两个字节表示后面的字节数。

int size()   返回written的当前值。

在这里我写了一段程序来了解每个方法,在读取中文字符时需要小心一些避免出现乱码。

在使用循环读取的时候,当读到最后会抛出EOFException错误来提示你读完了。我注释的地方智能一部分一部分的解开,不然会发成错误,因为前面的方法把东西读完了后面的方法就无法读取到东西了

import java.io.*;

public class DataInputStream_and_DataOutputStream {
    public static void main(String[] args) {
        try {
            FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\liuyue\\Desktop\\test.txt");
            DataOutputStream dataOutputStream=new DataOutputStream(fileOutputStream);
            dataOutputStream.writeUTF("使用writeUTF()方法写入数据");
            dataOutputStream.writeChars("使用writeChars()方法写入数据");
            dataOutputStream.writeBytes("使用writeBytes()方法写入数据");
            dataOutputStream.writeBoolean(true);
            dataOutputStream.writeInt(666);
            dataOutputStream.write("使用write()方法写入数据".getBytes());
            dataOutputStream.close();
            fileOutputStream.close();

            FileInputStream fileInputStream=new FileInputStream("C:\\Users\\liuyue\\Desktop\\test.txt");
            DataInputStream dataInputStream=new DataInputStream(fileInputStream);

//            System.out.println(dataInputStream.readUTF());

//            char[] chars=new char[1024];
//            char c;
//            int i=0;
//            try {
//                while ((c=dataInputStream.readChar())!=-1) {
//                    chars[i]=c;
//                    i++;
//                }
//            }catch (EOFException e){
//                System.out.println("读完了!");
//            }
//            String string=new String(chars);
//            System.out.println(string);

//            byte[] bytes=new byte[1024];
//            byte b;
//            int i=0;
//            try {
//                while ((b=dataInputStream.readByte())!=-1){
//                    bytes[i]=b;
//                    i++;
//                }
//            }catch (EOFException e){
//                System.out.println("读完了!");
//            }
//            String s=new String(bytes);
//            System.out.println(s);

//            byte[] bytes=new byte[1024];
//            int len=0;
//            try {
//                len =dataInputStream.read(bytes);
//            }catch (EOFException e){
//                System.out.println("读完了");
//            }
//            System.out.println(new String(bytes,0,len));
            dataInputStream.close();
            fileInputStream.close();
        }catch (Exception e){
            System.out.println(e);
        }

    }
}

4.ZipInputStream和ZipOutputStream类

JAVA实现了I/O数据流与网络数据流的单一接口,因此数据的压缩、网络传输和解压缩的实现比较容易。ZipEntry类产生的对象是用来代表一个ZIP文件内的进入点。ZipInputStream类用来读去ZIP压缩格式的文件,所支持的包括已压缩及未压缩的进入点。ZipOutputStream类用来写出ZIP压缩格式的文件,而且所支持的包括已压缩及未压缩的进入点。

ZipOutputStream(OutputStream out)

常用方法有:

void putNexEntry(ZipEntry e)   开始写一个新的ZipEntry,并将流内的位置移至此entry所指数数据的开头

void write(byte[] b,int off,int len)   将字节数组写入当前ZIP条目数据

void finish()   完成写入ZIP输出流的内容,无需关闭它所配合的OutputStream

void setComment(String comment)   可设置此ZIP文件的注释文字

在写这个程序时,我碰到了一个坑,就是重复压缩长路径,压缩出来的文件是这样的:

后来写了一个方法改变压缩的路径名才得以解决:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipOutputStream_test {

    private void zip(String zipFileName, File inputFile) throws Exception{

        ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(zipFileName));
        zip(zipOutputStream,inputFile,"");
        zipOutputStream.flush();
        zipOutputStream.close();
    }

    private void zip(ZipOutputStream zipOutputStream, File inputFile, String base) throws Exception {
        if (inputFile.isDirectory()){
            File[] files=inputFile.listFiles();
            if (base.length()!=0){
                zipOutputStream.putNextEntry(new ZipEntry(base+"/"));
            }
            for (int i=0;i<files.length;i++){
                zip(zipOutputStream,files[i],base+getLocation(""+files[i]));
            }
        }else {
            zipOutputStream.putNextEntry(new ZipEntry(base));
            FileInputStream inputStream=new FileInputStream(inputFile);
            int b;
            System.out.println(base);
            while ((b=inputStream.read())!=-1){
                zipOutputStream.write(b);
            }
            inputStream.close();
        }
    }

    private String getLocation(String s){
        String[] stringList=s.replace("\\","/").split("/");
        int len=stringList.length;
        String string="\\"+stringList[len-1];
        return string;
    }


    public static void main(String[] args) {
        ZipOutputStream_test zipOutputStreamStreamTest=new ZipOutputStream_test();
        try {
            long oldTime=System.currentTimeMillis();
            zipOutputStreamStreamTest.zip("C:\\Users\\liuyue\\Desktop\\test.zip",new File("C:\\Users\\liuyue\\Desktop\\longfei"));
            long currentTime=System.currentTimeMillis();
            float time=(float)(currentTime-oldTime)/1000;
            System.out.println("压缩完成,耗时"+time+"s");
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

从这端程序可以看出,每一个ZIP文件中可能包含多个文件,使用ZipOutputStream类将文件写入目标ZIP时,必须先使用ZipOutputStream对象的putNexEntry()方法,写入个别文件的entry,将流内目标制定的位置移到该rntry所指的开头位置。

说完了压缩再来说解压缩,解压缩就简单了

ZipInputStream(InputStream in)

常用方法:

int read(byte[] b,int off,int len)   读取目标b数组内off偏移量的位置,长度是N的字节

int available()   判断是否已读完目前entry所指定的数据。已读完返回0,否则返回1

void closeEntry()   关闭当前ZIP条目并定位流以读取下一个目录

long skip(long n)   跳过当前ZIP条目中指定的字节数

ZipEntry getNexEntry()   读取下一个ZipEntry,并将流内的位置移至该entry所指数据的开头

ZipEntry createZipEntry(String name)   以指定的name参数新建一个ZipEntry对象

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class ZipInputStream_test {

    public static void main(String[] args) {
        File file=new File("C:\\Users\\liuyue\\Desktop\\test.zip");
        ZipInputStream zipInputStream;
        try {
            ZipFile zipFile=new ZipFile(file);
            zipInputStream=new ZipInputStream(new FileInputStream(file));
            ZipEntry zipEntry=zipInputStream.getNextEntry();
            while (((zipEntry=zipInputStream.getNextEntry())!=null)&&!zipEntry.isDirectory()){
                File tmp=new File("C:\\Users\\liuyue\\Desktop\\"+zipEntry.getName());
                if (!tmp.exists()){
                    tmp.getParentFile().mkdir();
                    OutputStream outputStream=new FileOutputStream(tmp);
                    InputStream inputStream=zipFile.getInputStream(zipEntry);
                    int count=0;
                    while ((count=inputStream.read())!=-1){
                        outputStream.write(count);
                    }
                    outputStream.close();
                    inputStream.close();
                }
                zipInputStream.closeEntry();
                System.out.println(zipEntry.getName()+"解压成功");
            }
            zipInputStream.close();
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幽蓝丶流月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值