Java#33(IO流)

目录

一.IO流

作用: (对于程序而言)用于读写数据(本地数据, 网络数据)

二.IO流体系 

 1.字节输出流

2.字节输入流

 3.文件拷贝

 3.字符集

字符流

字符输入流

字符输出流

缓冲流

转换流 

序列化流 

​编辑反序列流

打印流


一.IO流

I: input     O: output     流: 想流水一样传输数据

作用: (对于程序而言)用于读写数据(本地数据, 网络数据)

(写)输出流(output):  程序-------->文件

(读)输入流(input):  文件--------->程序

IO流按照操作文件的类型可以分类为:

字节流: 可以操作所有类型的文件

字符流: 只能操作纯文本文件(用window系统自带的记事本打开并且能够读懂的文件)

二.IO流体系 

 1.字节输出流

FileOutputStream

代码示范:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IODemo1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("C:\\Users\\怪\\Desktop\\abc\\b.txt");
        fos.write(97);
        fos.close();
    }
}

结果展示:

注意:

(1)创建字节输出流对象, 参数可以是字符串代表的路径或File对象

(2)创建字节输出流对象, 如果文件不存在会创建一个新的文件,不过要保证父级路径存在

(3)创建字节输出流对象, 如果文件已经存在,会先清空文件

(4)在写数据时, write方法的参数时整数, 但实际上存进去的是ASCII码值对应的字符

(5)释放资源, 每次使用完流后都要释放资源

FileOutputStream写数据的3种方式
        方法名称                                                          说明
void write(int b)                                        一次写一个字节数据
void write(byte[ ] b)                                一次写一个字节数组数据
void write(byte[ ] b,int off,int len)    一次写一个字节数组的部分数据
代码示范: 

import java.io.FileOutputStream;
import java.io.IOException;

public class IODemo2 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\Java\\java\\Demo2_12_4\\src\\a.txt");
        //1.write(int b)
        //fos.write(97);
        //2.write(byte[])
        byte[] bt1 = {97,98,99,100,101,102};
        //fos.write(bt1);
        //3.write(byte[],int off,int len)
        //int off起始索引  int len 个数
        fos.write(bt1,0,3);
        fos.close();
    }
}

运行write(byte[ ] b)结果展示:运行write(byte[ ] b, int off, int len)结果展示: 

如何换行写?

代码示范: 

import java.io.FileOutputStream;
import java.io.IOException;

public class IODemo3 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\Java\\java\\Demo2_12_4\\src\\a.txt");
        //将字符串转化为字节类型
        String s1 = "abc";
        byte[] bytes1 = s1.getBytes();
        fos.write(bytes1);
        //换行操作
        String s2 = "\r\n";
        byte[] bytes2 = s2.getBytes();
        fos.write(bytes2);
        //在添加字符
        String s3 = "123";
        byte[] bytes3 = s3.getBytes();
        fos.write(bytes3);
        fos.close();
    }
}

结果展示:

如何实现续写? 

在创建FileOutputStream对象的第二个参数写上true(表示打开续写, 默认为false)

2.字节输入流

FileInputStream: 操作本地文件的字节输入流, 可以把本地文件的数据读取到程序中来

代码示范: 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IOStreamDemo1 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\Java\\java\\Demo1_12_5\\src\\IOStreamDemo\\b.txt");
        int read1 = fis.read();//返回的是对应的ASCII码值
        System.out.println(read1);
        int read2 = fis.read();
        System.out.println((char)read2);
        int read3 = fis.read();
        System.out.println((char)read3);
        int read4 = fis.read();
        System.out.println(read4);
        fis.close();
    }
}

结果展示:

 注意: 读到末尾就是-1

FileInputStream的循环读取

代码示范: 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IOStreamDemo2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\Java\\java\\Demo1_12_5\\src\\IOStreamDemo\\b.txt");
        //创建一个变量来存储
        int a = 0;
        //read: 读取数据,并将下标移动的下一位
        //利用末尾是-1来作为结束标志
        while((a = fis.read())!=-1){
            System.out.println((char)a);
        }
        fis.close();
    }
}

结果展示: 

 3.文件拷贝

核心思想: 边读边写

代码示范: 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOStreamDemo3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\怪\\Desktop\\abc\\aa.txt");
        FileOutputStream fos = new FileOutputStream("D:\\Java\\java\\Demo1_12_5\\src\\IOStreamDemo\\b.txt");
        int a = 0;
        while((a = fis.read()) != -1){
            fos.write(a);
        }
        //释放资源
        //先创建的后释放
        fos.close();
        fis.close();
    }

结果展示:

FileInputStream一次读取多个字节

代码示范: 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class IOStreamDemo4 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\Java\\java\\Demo1_12_5\\src\\IOStreamDemo\\b.txt");
        //一次读取多个字节数据,有数组长度决定
        byte[] by1 = new byte[2];
        //本次读取了多少个字节
        int len1 = fis.read(by1);
        System.out.println(len1);
        String str1 = new String(by1,0,len1);
        System.out.println(str1);

        int len2 = fis.read(by1);
        System.out.println(len2);
        String str2 = new String(by1,0,len2);
        System.out.println(str2);

        int len3 = fis.read(by1);
        System.out.println(len1);
        String str3 = new String(by1,0,len3);
        System.out.println(str3);
        fis.close();

    }
}

结果展示: 

 3.字符集

GBK字符集

1.在计算机中,任意数据都是以二进制的形式来存储的

2.计算机中最小的存储单元是一个字节
3.ASCII字符集中,一个英文占一个字节
4.简体中文版Windows,默认使用GBK字符集
5.GBK字符集完全兼容ASCII字符集
一个英文占一个字节,二进制第一位是0
一个中文占两个字节,二进制高位字节的第一位是1

Unicode字符集

1.Unicode字符集的UTF-8编码格式(UTF-8是Unicode中的一种编码方式,不是字符集)
一个英文占一个字节,二进制第一位是0,转成十进制是正数

一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数

产生乱码的原因:
1. 不要用字节流读取文本文件
2. 编码解码时使用同一个码表,同一个编码方式

编码和解码方法

编码
        String类中的方法                                                              说明
public byte[ ] getBytes()                                           使用默认方式进行编码
public byte[ ] getBytes(string charsetName)         使用指定方式进行编码
解码
        String类中的方法                                                              说明
string(byte[] bytes)                                                    使用默认方式进行解码
string(bytel] bytes,string charsetName)               使用指定方式进行解码
代码示范: 

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class Demo1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str1 = "ni们好";
        //默认UTF-8
        byte[] bytes1 = str1.getBytes();
        System.out.println(Arrays.toString(bytes1));
        //GBK
        byte[] bytes2 = str1.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));

        //解码
        //默认
        String str2 = new String(bytes1);
        System.out.println(str2);
        //GBK
        String str3 = new String(bytes1,"GBK");
        System.out.println(str3);//为什么会乱码?
                        //因为bytes1是用UTF-8进行编码的
                        //而str3是用GBK进行解码的,所以会乱码
    }
}

结果展示: 

字符流

字符流的底层其实就是字节流
字符流 = 字节流 + 字符集
特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节

输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
注意:
只能对纯文本文件进行读写操作

字符输入流

步骤:

第一步:创建对象
public FileReader(File file)            创建字符输入流关联本地文件

public FileReader(String pathname)创建字符输入流关联本地文件
第二步: 读取数据

public int read()            读取数据,读到末尾返回-1
public int read(char[] buffer)        读取多个数据,读到末尾返回-1
第三步:释放资源
public void close()            释放资源/关流

代码示范:无参read( )

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo1 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("D:\\Java\\java\\Demo1_12_6\\src\\c.txt");
        //读取数据
        int ch;
        while ((ch = fr.read()) != -1) {
            System.out.print((char)ch);
        }
        //释放资源
        fr.close();
    }
}

结果展示:

注意:ch表示的不是二进制的数值,而是对应十进制的数值

 代码示范: 有参read(char[ ] 变量名)

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo2 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("D:\\Java\\java\\Demo1_12_6\\src\\c.txt");
        //一次读取多个数据
        char[] ch1 = new char[3];
        int len;
        //有参read方法
        while ((len = fr.read(ch1)) != -1) {
            System.out.print(new String(ch1,0,len));
        }
        //释放资源
        fr.close();
    }
}

结果展示: 

字符输出流

步骤:

第一步:创建对象
public FileWriter(File file)                                               创建字符输出流关联本地文件
public Filewriter(String pathname)                                创建字符输出流关联本地文件
public FileWriter(File file, boolean append)              创建字符输出流关联本地文件, 可续写
public Filewriter(string pathname, boolean append)   创建字符输出流关联本地文件,可续写 
第二步:读取数据
void write(int c)                                                写出一个字符
void write(string str)                                      写出一个字符串
void write(String str, int off, int len)        写出一个字符串的一部分
void write(char[] cbuf)                                 写出一个字符数组   
void write(char[] cbuf, int off, int len)      写出字符数组的一部分
第三步:释放资源
public void close()                                           释放资源/关流

代码示范:

import java.io.FileWriter;
import java.io.IOException;

public class FileWriteDemo1 {
    public static void main(String[] args) throws IOException {
                                                                                    //true表示打开续写
        FileWriter fw = new FileWriter("D:\\Java\\java\\Demo1_12_6\\src\\c.txt",true);
        //写入数据
        fw.write("字节");
        char[] ch1 = {'1','a','c'};
        fw.write(ch1);
        //释放资源
        fw.close();
    }
}

结果展示: 

缓冲流

缓冲流可以提高性能,如何提高性能?

缓冲流自带8192的缓冲区

可以提高字节流的读写性能

对字符流就没有那么明显, 但有两个特有方法

字符输出流特有的方法: BufferedReader: readLine( )(读取一行代码, 没有数据可以读取就返回null)

字符输出流特有的方法: BufferedWriter: newLine( )(跨平台换行)

字节缓冲流拷贝文件

代码示范:

import java.io.*;

public class BufferedStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //利用字节缓冲流拷贝文件
        //创建对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Java\\java\\Demo1_12_7\\src\\BufferedInputStreamDemo1\\a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Java\\java\\Demo1_12_7\\src\\BufferedInputStreamDemo1\\copy.txt"));
        //循环读取
        int b = 0;
        while((b = bis.read()) != -1){
            bos.write(b);
        }
        //释放资源
        bos.close();
        bis.close();

    }
}

结果展示: 

字符缓冲流特有方法

readLine( )代码示范:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Test1 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\java\\Demo1_12_7\\src\\BufferedInputStreamDemo1\\a.txt"));

        String str = br.readLine();
        System.out.println(str);
        br.close();
    }
}

结果展示:

newLine( )代码示范:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Test2 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\Java\\java\\Demo1_12_7\\src\\BufferedInputStreamDemo1\\copy1.txt"));
        String s1 = "繁星";
        bw.write(s1);
        bw.newLine();
        String s2 = "春水";
        bw.write(s2);
        bw.newLine();
        bw.close();
    }
}

结果展示: 

转换流 

InputStreamReader

OutStreamWriter

作用: 让字节流可以使用字符流中的方法

代码示范: 让字节流使用字符缓冲流

import java.io.*;

public class Test2 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Java\\java\\Demo2_12_7\\src\\InputStreamReaderDemo1\\aa.txt")));
        String str = br.readLine();
        System.out.println(str);
        br.close();
    }
}

结果展示:

序列化流 

可以把Java中的对象写到本地文件中

构造方法
public Objectoutputstream(Outputstream out)  把基本流包装成高级流
成员方法
public final void writeobject(object obi)        把对象序列化(写出)到文件中去
代码示范:第一段是类的代码,第二段是测试代码

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test3 {
    public static void main(String[] args) throws IOException {
        Student stu = new Student("张三",65);
        //创建对象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Java\\java\\Demo2_12_7\\src\\InputStreamReaderDemo1\\a.txt"));
        //使用成员方法
        oos.writeObject(stu);
        //释放资源
        oos.close();
    }
}

结果展示:

 注意:

类要实现Serializable接口,不然就会报错(Serializable接口里面是没有抽象方法,是标记型接口
一旦实现了这个接口,那么就表示当前的类可以被序列化)


反序列流

构造方法
public objectInputstream(Inputstream out)    把基本流变成高级流
成员方法
public object readObject()                 把序列化到本地文件中的对象,读取到程序中来

代码示范:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Java\\java\\Demo2_12_7\\src\\InputStreamReaderDemo1\\a.txt"));
        //使用方法
        Object o1 = ois.readObject();
        System.out.println(o1);
        //释放资源
        ois.close();
    }
}

结果展示:

打印流

作用:打印流可以实现方便、高效的打印数据到文件中去

打印流一般是指: PrintStream,PrintWriter
可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。
PrintStream
                构造方法                                                          说明
public PrintStream(Outputstream os)         打印流直接通向字节输出流管道
public PrintStream(File f)                                 打印流直接通向文件对象
public PrintStream(String filepath)                 打印流直接通向文件路径
                 方法
public void print(Xxx xx)                           打印任意类型的数据出去 

代码示范:PrintStream( )

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.PrintWriter;

public class PrintStreamDemo1 {
    public static void main(String[] args) throws FileNotFoundException {
        //创建对象
        PrintStream ps = new PrintStream("D:\\Java\\java\\Demo3_12_7\\src\\a.txt");
        //添加数据
        ps.println(123);
        ps.println("abc");
        ps.println(123.456);
        ps.println(true);
        //释放资源
        ps.close();
    }
}

结果展示: 

 PrintWriter( )和PrintStream的打印基本一致

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值