Java从入门到精通 第15章 I/O(输入/输出)

目录

输入/输出流

File类

文件输入/输出流

带缓存的输入/输出流

数据输入/输出流

ZIP压缩输入/输出流


输入/输出流

java定义了许多专门负责各种方式的输入/输出,都放在java.io包中

输入流:抽象类:InputStream(字节输入流),Reader(字符输入流)

输出流:抽象类:OutputStream(字节输出流),Writer(字符输出流)

  • read(); 从输入流中读取数据的下一个字节。返回0-255范围内的int字节值,没有可用的字节则返回值为-1
  • read(byte[] b); 从输入流中读取一定长度的字节,并以整数的形式返回字节数
  • mark(int readlimit); 在输入流的当前位置放一个标记,readlimit参数告知此输入流在标记位置失效前允许读取的字节数
  • reset(); 将输入指针返回到当前所做的标记处
  • skip(long n); 跳过输入流上的n个字节并返回实际跳过的字节
  • markSupport(); 如果当前流支持mark()/reset()操作就返回true
  • close(); 关闭此输入流并释放与该流关联的所有系统资源
    • 并不是所有的InputStream类都支持InputStream中定义的所有方法,如skip(),mark(),reset()等方法只对某些子类有用 

File类

  • File类是java.io包中唯一代表磁盘文件本身的对象
  • 构造方法有三种
    • new File(String);
    • new File(String father, String child);
    • new File(File f, String child);

package IO;

import java.io.File;

public class FileTest {
    public static void main(String[] args) {
        //使用路径创建File对象
        //File file = new File(String pathname)
//        File file = new File("D:\\word.txt");
        File file = new File("word.txt");

        //使用父路径、子路径创建
        //File file = new File(String father, String child)
//        String fatherPath = "D:\\";
//        String childPath = "word2.txt";
//        File file2 = new File(fatherPath, childPath);

        //使用父路径对象、子路径创建
        //File file = new File(File f, String child)
//        childPath = "word3.txt";
//        File file = new File(file2.getParent(), childPath);
        if (!file.exists()) {
//            file.delete();  //删除文件
//            System.out.println("文件已删除");
        } else {
            try {
                file.createNewFile();  //创建文件
                System.out.println("文件已创建");
                String name = file.getName();  //获取文件名称
                long length = file.length();  //获取文件长度
                boolean hidden = file.isHidden(); //判断是否是隐藏文件
                System.out.println("文件名称:" + name);
                System.out.println("文件长度:" + length);
                System.out.println("是否是隐藏文件:" + hidden);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

文件输入/输出流

  • FileInputStream与FileOutputStream类
    • 不足:这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占两个字节,使用字节流,读取不好会出现乱码,此时采用字符流可避免这种现象
  • FileReader与FileWriter类
//FileInputStream与FileOutputStream类
package IO;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileInputStreamFileOutputStream {
    public static void main(String[] agrs) {
        File file = new File("word.txt");

        //没有文件就创建
        if (file.exists()) {
            System.out.println("存在文件" + file.getPath());
        } else {
            try {
                file.createNewFile();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //写入字节流
        try {
            //创建FileOutputStream对象
            FileOutputStream outputStream = new FileOutputStream(file);
            //创建byte数组
            byte[] buy = "我有一只小毛驴,我从来也不骑。".getBytes();
            outputStream.write(buy);  //将数组中的信息写入到文件中
            outputStream.close();  //将流关闭
        } catch (Exception e) {
            e.printStackTrace();
        }

        //读出字节流
        try {
            //创建FileInputStream对象
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] byt = new byte[1024];  //创建数组
            int len = fileInputStream.read(byt);
            //将文件中的信息输出
            System.out.println("文件中的信息是:" + new String(byt, 0, len));
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

带缓存的输入/输出流

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

  • BufferedInputStream和BufferedOutputStream类
    • 可以对所有的InputStream类进行带缓存区的包装以达到性能的优化
    • 构造方法
    • BufferedInputStream(InputStream in, int size); size默认32字节
    • BufferedOutputStream(InputStream in, int size); size默认32字节
  • BufferedReader和BufferedWriter类
    • 分别继承Reader类和Writer类
    • 常用方法
    • BufferedReader
      • read(); 读取单个字符
      • readLine(); 读取一个文本行,返回字符串。无数据可读返回null
    • BufferedWriter
      • write(String s, int off, int len); 写入字符串的一部分
      • flush(); 刷新流的缓存
      • newLine(); 写入一个行分隔符
package IO;

import java.io.*;

public class students {
    public static void main(String[] agrs) {
        String[] contents = {"好久不见", "最近好吗", "常联系"};

        //写数据
        File file = new File("students.txt");  //创建File对象
        try {
            FileWriter fw = new FileWriter(file);  //创建FileWriter对象
            BufferedWriter bufw = new BufferedWriter(fw);
            for (int i = 0; i < contents.length; i++) {
                bufw.write(contents[i]);
                bufw.newLine();
            }
            bufw.close();
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //读数据
        try {
            FileReader fr = new FileReader(file);  //创建FileReader对象
            BufferedReader bufw = new BufferedReader(fr);
            String s = null;  //创建字符串对象
            int i = 0;
            //如果文件的文本行数不为null则进入循环
            while ((s = bufw.readLine()) != null) {
                i++;
                System.out.println("第" + i + "行:" + s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

数据输入/输出流

  • DataInputStream类和DataOutputStream类,允许以与机器无关的方式从底层输入流中读取基本的java数据类型
  • 构造方法
    • DataInputStream(InputStream in); 从指定的基础InputStream创建一个DataInputStream
    • DataOutputStream(OutStream out); 创建一个新的数据输出流,将数据写入指定基础输出流
      • writeBytes(String s); 由于java字符是unicode编码,双字节,只写入字节的低字节内容
      • writeChars(String s); 两个字节都写入
      • writeUTF(String s); 按照utf编码后的字节长度写入
package IO;

import java.io.*;

public class Example {
    public static void main(String[] args) {
        File file = new File("hi.txt");
        try {
            FileOutputStream fs = new FileOutputStream(file);
            DataOutputStream ds = new DataOutputStream(fs);
            ds.writeUTF("使用writeUTF()方法写入数据");  //使用这个写,可以读出来
            ds.writeBytes("使用writeBytes()方法写入数据");
            ds.writeChars("使用writeChars()方法写入数据");
            ds.close();  //关闭流

            FileInputStream fis = new FileInputStream(file);
            DataInputStream dis = new DataInputStream(fis);
            System.out.println(dis.readUTF());
            dis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

ZIP压缩输入/输出流

java的内置类提供了非常好用的相关类,java.util.zip包中的ZipOutputStream和ZipInputStream类实现文件的压缩/解压缩

  • ZipOutputStream类,可将文件压缩为.zip文件
    • 构造方法ZipOutputStream(OutputStream out);
  • ZipInputStream类可读取ZIP压缩格式的文件,包括已压缩和未压缩的条目entry
    • 构造方法ZipInputStream(InputStream in);

//压缩文件
package IO;

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

public class MyZip {
    private void zip(String zipFileName, File inputFile) throws Exception {
        //创建ZipOutputStream对象
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
        zip(out, inputFile, "");  //调用方法
        System.out.println("Ziping...");  //输出信息
        out.close();  //关闭流
    }

    private void zip(ZipOutputStream out, File f, String base) throws Exception {
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
//            if (base.length() != 0) {
//                out.putNextEntry(new ZipEntry(base + "\\")); //写入此目录的entry??
//            }
            for (int i = 0; i < fl.length; i++) {
                zip(out, fl[i], base + fl[i]);
            }
        } else {
            out.putNextEntry(new ZipEntry(base));  //创建新的进入点
            FileInputStream in = new FileInputStream(f);
            int b;
            System.out.println(base);
            while ((b = in.read()) != -1) {  //如果没有达到流的尾部
                out.write(b);                 //将自己写入当前ZIP条目
            }
            in.close();
        }
    }

    public static void main(String[] args) {
        MyZip book = new MyZip();
        try {
            book.zip("D:\\zi.zip", new File("src\\number"));
            System.out.println("done.");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
//解压缩
package IO;

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

public class MyZip2 {
    public static void main(String[] args) {
        File file = new File("D:\\zi.zip");  //当前压缩文件
        try {
            ZipFile zipFile = new ZipFile(file);  //创建压缩文件对象
            ZipInputStream zin = new ZipInputStream(new FileInputStream(file)); //创建ZipInputStream对象
            ZipEntry entry = zin.getNextEntry();  //跳过根目录,获取下一个ZipEntry
            while (((entry = zin.getNextEntry()) != null)
                    && !entry.isDirectory()) {  //entry不为空,并不在同一目录下
                File tmp = new File("D:\\" + entry.getName());  //解压出的文件路径
                if (!tmp.exists()) {
                    tmp.getParentFile().mkdirs();  //创建文件父类文件夹路径
                    OutputStream os = new FileOutputStream(tmp);  //将文件目录中的文件放入输出流
                    InputStream in = zipFile.getInputStream(entry);  //用输入流读取压缩文件中制定目录中的文件
                    int count = 0;
                    while ((count = in.read()) != -1) {  //如果有输入流可以读取到数值
                        os.write(count);                 //输入流写入
                    }
                    os.close();  //关闭输出流
                    in.close();  //关闭输入流
                }
                zin.closeEntry();  //关闭当前entry
                System.out.println(entry.getName() + " unzip successfully.");
            }
            zin.close();  //关闭流

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
发布了46 篇原创文章 · 获赞 0 · 访问量 1021

猜你喜欢

转载自blog.csdn.net/weixin_37680513/article/details/103492908
今日推荐