【十八掌●基本功篇】第一掌:Java之IO

这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌


系列文章:
【十八掌●基本功篇】第一掌:Java之IO
【十八掌●基本功篇】第一掌:Java之多线程–1-一些概念
【十八掌●基本功篇】第一掌:Java之多线程–2-join、同步、死锁、等待

一、 Java IO主要类结构图

这里写图片描述

二、 Java IO概述

1、 流的概念

在两个程序节点间传输的数据是流。

2、 字节流和字符流的区别
  • 字节流处理的单位是字节,长度为8位;字符流处理的单位是字符,长度为2个字节的Unicode字符,长度为16位。
  • 字节流可以处理任何格式的数据,比如字符串、图片、视频、音频数据,但是字符流只能处理字符串。
  • 字符流最终还是以字节的方式存盘,可以理解为字符流是字节流的封装,处理字符串应该优先考虑使用字符流。
3、 Java IO类结构规划

如上图所示,Java IO里主要分为字节流、字符流,而字节流和字符流都分为输入流和输出流。
(1) 字节流的输入流相关类都派生于InputStream,InputStream是抽象类,在各种不同的应用场景,又派生出不同的子类,如果FileInputStream子类适用于来自于文件的输入。
(2) 字节流的输出流相关类也派生于一个OutputStream抽象父类,各个场景下也派生出什么子类,各个输出流子类与输入流子类是一一对应的。
(3) 同字节流类似,字符流的输入流相关类,也有一个根类Reader,Reader也是个一个抽象类。
(4) 字符流的输出类都继承于根类Writer,各个输出流子类也与输入流的子类一一对应。

三、 字节流

1、 FileInputStream、FileOutputStream

(1) 应用场景

从文件中以二进制方式读取磁盘文件时使用,适合于对文件的简单的读写,当文件是非文本文件时,适合用FileInputStream、FileOutputStream,如果是文本文件,最好用字符流系列。

(2) 常用方法

read()从此输入流中读取下一个数据字节。
read(byte[] b)从此输入流中将byte.length个字节的数据读入到b字节数组中
read(byte[] b, int off, int len)从此输入流中将len个字节数据读入b数组中,写入b数组的开始位置为off。
close()关闭此输入流并释放此流相关的所有的系统资源。

(3) 代码示例

示例1:从文件中一个字节一个字节地读取数据,效率最低。
private static void FileInputStream1() throws FileNotFoundException {
    File file = new File("demo.data");
    FileInputStream fileInputStream = null;

    byte[] array = new byte[(int) file.length()];
    try {
        fileInputStream = new FileInputStream(file);
        int index = 0;
        int readval = fileInputStream.read();
        while (readval != -1) {
            array[index++] = (byte)readval;
            readval = fileInputStream.read();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

     System.out.println(new String(array));
}
示例2:以指定大小的字节数为单位,从文件中读取数据,可以批量读取,效率高,尤其在复制大文件时,比较适合,占内存较小。
private static void FileInputStream2() throws FileNotFoundException {
    File file = new File("demo.data");
    FileInputStream fileInputStream = null;

    byte[] tempByte = new byte[3];
    byte[] target=new byte[(int)file.length()];
    try {
        fileInputStream = new FileInputStream(file);
        int leng = fileInputStream.read(tempByte);
        int currindex=0;
        while (leng >0) {
            System.arraycopy(tempByte,0,target,currindex,leng);
            currindex=currindex+leng;
            leng = fileInputStream.read(tempByte);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println(new String(target));
}
示例3:以指定大小的字节数为单位,从文件中分批读取数据,适合操纵小文件。

private static void FileInputStream3() throws FileNotFoundException {
    File file = new File("demo.data");
    FileInputStream fileInputStream = null;

    byte[] target = new byte[(int) file.length()];
    try {
        int currindex = 0;
        int len = 10;
        fileInputStream = new FileInputStream(file);
        int readleng = fileInputStream.read(target, currindex, len);
        while (readleng > 0) {
            currindex = currindex + readleng;
            int count = (target.length - currindex) < len ? (target.length - currindex) : len;
            readleng = fileInputStream.read(target, currindex, count);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println(new String(target));
}
实例四、复制文件

private static void FileInputStream4() throws FileNotFoundException {
    File file = new File("demo.data");
    File targetfile=new File("demo2.data");
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream=null;

    byte[] tempByte = new byte[3];
    byte[] target = new byte[(int) file.length()];
    try {
        fileInputStream = new FileInputStream(file);
        fileOutputStream=new FileOutputStream(targetfile);
        int leng = fileInputStream.read(tempByte);
        int currindex = 0;
        while (leng > 0) {
            System.arraycopy(tempByte, 0, target, currindex, leng);

            fileOutputStream.write(tempByte);

            currindex = currindex + leng;
            leng = fileInputStream.read(tempByte);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println(new String(target));
}

2、 FilterInputStream、FilterOutputStream

(4) 应用场景

FilterInputStream 的作用是用来“封装其它的输入流,是抽象类,并为它们提供额外的功能”,是一个修饰类。
它的常用的子类有BufferedInputStream、DataInputStream、PushbakInputStream。

3、 BufferedInputStream、BufferedOutputStream

(5) 应用场景

在内存中提供了一个缓冲区,避免每次读取都进行实际的读操作,提高了效率。BufferedOutputStream是一个修饰后的OutputStream,它对数据流使用了缓冲技术,避免每次发送数据都要进行实际的写操作,可以调用flush()来清空缓冲区。

(6) 常用方法

flush()清空缓存中的数据
write(int b)将制定字节写入缓冲输出流
write(byte[] b,int off,int len)将指定byte数组中的从off个开始的len个字节写入此缓冲输出流。

(7) 代码示例


示例:复制文件
public boolean CopyFileToSource(String sourceFilePath, String targetdir, String targetFileName) {
    boolean isok = false;

    File file = new File(sourceFilePath);
    if (!file.exists()) {
        return false;
    }
    file = new File(targetdir);
    if (!file.exists() && !file.isDirectory()) {
        file.mkdirs();
    }
    BufferedInputStream inputStream = null;
    BufferedOutputStream outputStream = null;
    try {
        inputStream = new BufferedInputStream(new FileInputStream(new File(sourceFilePath)));
        outputStream = new BufferedOutputStream(new FileOutputStream(new File(targetdir + "\\" + targetFileName)));

        byte[] temp = new byte[1024];
        int count = inputStream.read(temp);
        while (count > 0) {
            outputStream.write(temp);
            count = inputStream.read(temp);
        }

        isok = true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return isok;
}
4、 DataInputStream、DataOutputStream

(8) 应用场景

可以将各种基本数据类型和String对象格式化输出到流中,应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型,当读取数据时,不必关心这个数值应当是哪种字节编码。
按类型读取和写入数据。

(9) 常用方法

writeBoolean写入一个Boolean值
writeByte写入一个字节值
writeInt写入一个Int值
writeUTF以UTF-8编码写入一个字符串
readBoolean读取一个Boolean值
readByte读取一个字节值
readInt读取一个Int值
readUTF以UTF-8编码读取一个字符串

(10) 代码示例

public class DataInput {
    static List<Person> list = null;
    public static void main(String[] args) {
        try {
            setList();
        } catch (ParseException e) {
            e.printStackTrace();
        }
       WriteData();
       Person[] plist= ReadData();
    }
    private static void setList() throws ParseException {
        list = new ArrayList<Person>();
        Person person = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        person = new Person();
        person.setId(1);
        person.setName("张三");
        person.setAge(18);
        person.setBrithday(dateFormat.parse("1970-06-28"));
        person.setIsjoin(true);
        person.setScore(89.5);
        list.add(person);

        person = new Person();
        person.setId(2);
        person.setName("李四");
        person.setAge(20);
        person.setBrithday(dateFormat.parse("1987-12-31"));
        person.setIsjoin(false);
        person.setScore(90.4);
        list.add(person);

        person = new Person();
        person.setId(3);
        person.setName("王五");
        person.setAge(22);
        person.setBrithday(dateFormat.parse("1984-08-04"));
        person.setIsjoin(true);
        person.setScore(75);
        list.add(person);
    }
    private static void WriteData() {
        DataOutputStream outputStream = null;
        try {
            outputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("DataOutput.dat")));
            for (Person p :
                    list) {
                outputStream.writeInt(p.getId());
                outputStream.writeUTF(p.getName());
                outputStream.writeInt(p.getAge());
                outputStream.writeBoolean(p.isjoin());
                outputStream.writeDouble(p.getScore());
            }
            outputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    private static Person[] ReadData() {
        DataInputStream datainput = null;
        try {
            datainput = new DataInputStream(new BufferedInputStream(new FileInputStream("DataOutput.dat")));
            list = new ArrayList<Person>();

            while(true)
            {
                Person person=new Person();
                person.setId(datainput.readInt());
                person.setName(datainput.readUTF());
                person.setAge(datainput.readInt());
                person.setIsjoin(datainput.readBoolean());
                person.setScore(datainput.readDouble());

                list.add(person);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                datainput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return list.toArray(new Person[0]);
    }
}
5、 PrintStream

(11) 应用场景

用于产生格式化输出。
与DataOutputStream区别:
DataOutputStream处理数据的存储;PrintStream处理显示。

(12) 常用方法

print()输出一个基本数据类型或者对象
printIn()写入一个行分隔符
append将制定字符添加到输出流
flush刷新流的缓存
6、 PushbakInputStream

(13) 应用场景

具有“能弹出一个字节的缓冲区”,因此可以将读到的最后一个字符回退。
可以试探性地读取一个字节,看是否符合要求,然后再回退回去一个字节后,再读取字节。

7、 ObjectInputStream、ObjectOutStream

(14) 应用场景

是专门对于对象读写的,要求类已经实现了Serializable接口。

(15) 代码示例

public class ObjectInputDemo {
    static List<Person> list = null;
    public static void main(String[] args) {
        try {
            setList();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        WriteData();
        Person[] pList= ReadData();
    }
    private static void setList() throws ParseException {
        list = new ArrayList<Person>();
        Person person = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        person = new Person();
        person.setId(1);
        person.setName("张三");
        person.setAge(18);
        person.setBrithday(dateFormat.parse("1970-06-28"));
        person.setIsjoin(true);
        person.setScore(89.5);
        list.add(person);

        person = new Person();
        person.setId(2);
        person.setName("李四");
        person.setAge(20);
        person.setBrithday(dateFormat.parse("1987-12-31"));
        person.setIsjoin(false);
        person.setScore(90.4);
        list.add(person);

        person = new Person();
        person.setId(3);
        person.setName("王五");
        person.setAge(22);
        person.setBrithday(dateFormat.parse("1984-08-04"));
        person.setIsjoin(true);
        person.setScore(75);
        list.add(person);
    }

    private static void WriteData() {
        ObjectOutputStream outputStream = null;
        try {
            outputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("data/object.dat")));
            for (Person p :
                    list) {
                outputStream.writeObject(p);
            }
outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    private static Person[] ReadData() {
        ObjectInputStream inputStream = null;
        try {
            inputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream("data/object.dat")));
            list = new ArrayList<Person>();
            while (true) {
                Person person = (Person) inputStream.readObject();
                list.add(person);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return list.toArray(new Person[0]);
    }
}
8、 PipedInputStream、PipedOutStream

(16) 应用场景

两个进程间读写数据

四、 字符流

11、 InputStreamReader、OutputStreamWriter

(17) 应用场景

这两个是最基础的读写字符流。

(18) 代码示例

实例一:复制文件
public boolean CopyFileToSource(String sourceFilePath, String targetdir, String targetFileName) {
    boolean isok = false;
    InputStreamReader reader=null;
    OutputStreamWriter writer=null;
    try {
        reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(new File(sourceFilePath))), "GBK");
         writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(targetdir + "\\" + targetFileName))));
        char[] temp = new char[3];
        int i = 0;
        while ((i = reader.read(temp)) != -1) {
            for (int j = 0; j < i; j++) {
                writer.write(temp[j]);
            }
        }
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        try {
            reader.close();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return isok;
}
12、 FileReader、FileWriter

(1) 应用场景

顾名思义,对文件进行读写时用。

(2) 代码示例

private static void   CopyFile() throws IOException {
   FileReader reader=new FileReader("src/test/java/Demo.java");
   FileWriter writer=new FileWriter("target.java");
   char[] temp=new char[2000];
   int len;
   try {
      while ((len=reader.read(temp,0,temp.length))!=-1)
      {
         writer.write(temp,0,len);
      }
      writer.flush();
   }
   catch (Exception ignored){
   }
   finally {
      reader.close();
      writer.close();
   }
}
13、 BufferedReader、BufferedWriter

(3) 应用场景

是包装流,为了提高效率。

(4) 代码示例

private static void CopyFile2() throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader("src/test/java/Demo.java"));
    BufferedWriter writer = new BufferedWriter(new FileWriter("target.java"));
    String temp;
    try {
        while ((temp = reader.readLine()) != null) {
            writer.write(temp);
            writer.newLine();
        }
        writer.flush();
    } catch (Exception ignored) {
    } finally {
        reader.close();
        writer.close();
    }
}
14、 PrinterWriter

(1) 应用场景

PrinterWriter用于输出打印对象的格式户形式。

(2) 代码示例

private static void WriterFile(String info) throws FileNotFoundException {
    PrintWriter writer=new PrintWriter("target2.java");
    try {
        writer.write(info);
        writer.write('\n');
        writer.println(info);

        writer.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        writer.close();
    }
}
15、 StringReader、StringWriter

(1) 应用场景

对字符串串的处理

(2) 代码示例

private static void transform(String str)
{
    StringReader reader=new StringReader(str);
    StringWriter writer=new StringWriter();
    char[] temp=new char[1024];
    int len;
    try {
        while((len=reader.read(temp,0,temp.length))!=-1)
        {
            writer.write(new String(temp));
        }
        writer.flush();
        System.out.println(writer.toString());
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:这里写图片描述大数据技术●降龙十八掌

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值