Java学习笔记——Java语言基础(十九)(转换流、数据输入输出流、内存操作流(练习合并音乐)打印流、键盘录入)

一、转换流

1.1 字符编码和字符集

字符编码:计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制
数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照
某种规则解析显示出来,称为解码 。字符编码就是一套自然语言的字符与二进制数之间的对应规则
字符集:编码表,是一个系统支持的所有字符的集合。
常见的字符集:ASCII字符集、GBK字符集、Unicode字符集等

3.2 字符转化流OutputStreamWriter

OutputStreamWriter将字符流转换为字节流。是字符流通向字节流的桥梁, 可使用指定的码表将要写入流中的字符编码成字节。
它使用的字符集可以由名称指定或者给定,否则则按平台的默认字符集
构造方法

//构造一个默认编码集的OutputStreamWriter类
OutputStreamWriter osw = new OutputStreamWriter(OutputStream out);
//构造一个指定编码集的OutputStreamWriter类。
OutputStreamWriter osw = new OutputStreamWriter(OutputStream out,String charsetName);

代码演示

public class OutPutStreamWriter {
   
    public static void main(String[] args) throws IOException {
        write_utf_8();
        write_gbk();
    }
        /*
         使用转换流OutputStreamWriter 写UTF-8格式的文件
         */
    private static void write_gbk() throws IOException {
        //指定编码集,写GBK格式的文件
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
        osw.write("你好");
        osw.flush();
        osw.close();
    }
    /*
    使用转换流OutputStreamWriter 写UTF-8格式的文件
     */
    private static void write_utf_8() throws IOException {
        //不指定编码集 默认使用utf-8
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("utf-8.txt"));
        osw.write("你好");
        osw.flush();
        osw.close();
    }
}

字符写入的时候,是将数据写入到内存缓冲区中(字符转换为字节),写入完成需要使用flush方法,把内存缓冲区的数据,刷新到文件中。
close方法会关闭资源前会将内存缓冲区的数据刷新到文件中。
同样想达到追加写入的文件时,只需在构造方法中传入的FileOutputStream类的一个对象,该类的构造方法增加一个参数true,打开追加写开关

//实现追加写
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt",true));

构造一个指定编码集的OutputStreamWriter类。
由于使用的是IDEA软件,默认编码集为UTF-8,所有在编码解码上面不存在问题。
指定编码集为GBK时,会出现乱码问题

1.3 转换流InputStreamReader类

InputStreamReader,是Reader的子类,是从字节流到字符流的桥梁。读取字节,并适用指定的字符集将读取的字节进行解码为字符。字符集可以由名称指定,也可以使用默认的字符集

1.3.1 构造方法
InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。 第二个参数参数为编码表名称

使用转换流InputStreamReader读取上面所写入的文件

public class InPutStreamReader {
    public static void main(String[] args) throws IOException {
        //读取utf-8编码的文件
        read_utf_8();
        //读取gbk编码的文件 由于IDEA默认使用utf-8,所以在项目目录打开的会是乱码
        read_gbk();
    }
    private static void read_gbk() throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("gbk.txt"),"gbk");
        int len=0;
        while ((len=isr.read())!=-1){
            System.out.println((char) len);
        }
        isr.close();
    }
    private static void read_utf_8() throws IOException {
        InputStreamReader isr=new InputStreamReader(new FileInputStream("utf-8.txt"),"utf-8");
        int len=0;
        while ((len=isr.read())!=-1){
            System.out.println((char) len);
        }
        isr.close();
    }
}

二、数据输入输出流

数据输入流:DataInputStream 。允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型
数据输出流:DataOutputStream。允许应用程序以适当方式将基本 Java 数据类型写入输出流中。
特点:可以写基本类型的数据,可以读取基本类型数据

public class DataDemo01 {
    public static void main(String[] args) throws IOException {
        //数据输出流
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("aa.txt"));
        dos.writeBoolean(true);//写入布尔值
        dos.writeDouble(3.14);//写入Double类型
        dos.writeInt(20);//写入int类型
        dos.writeUTF("字符串");//写入字符串类型
        dos.close();
        //数据输入流
        DataInputStream dis = new DataInputStream(new FileInputStream("aa.txt"));
        System.out.println(dis.readBoolean());//true
        System.out.println(dis.readDouble());//3.14
        System.out.println(dis.readInt());//20
        System.out.println(dis.readUTF());//字符串
        dis.close();
    }
}

**注意:**数据输出流输入流的读取顺序不能乱。怎么写的就怎么读取

三、内存操作流

3.1 操作字节数组

操作字节数组:ByteArrayOutputStream和ByteArrayInputStream
特点:不直接关联文件,只在内存中操作。底层维护的是一个字节数组
ByteArrayOutputStream

  • 此类实现了一个输出流,数据被写入到一个byte数组
  • 数组(缓冲区)会随着数据的写入而自动增长
  • 可以使用toByteArray方法和toString方法获取数据
  • 不用关闭流,因为这个流的方法在关闭之后仍然可以调用,且不会产生任何IOException
    ByteArrayInputStream 包含了一个内部缓冲区,该缓冲区包含了从流中读取的字节。同样也是关闭无效。
public class ByteDemo01 {
    public static void main(String[] args) throws IOException {
        //ByteArrayOutputStream 此流不许关闭
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write("你好".getBytes());
        bos.write("同学".getBytes());
        bos.write("学习".getBytes());
        //通过toByteArray()取出数据
        byte[] bytes = bos.toByteArray();
        System.out.println(new String(bytes));
        //通过toString()取出数据
        System.out.println(bos.toString());
        /*ByteArrayInputStream( byte[] buf
        创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。
        */
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        //取出数据
        int len=0;
        byte[] bytes1=new byte[1024];
        while ((len=bis.read(bytes1))!=-1){
            System.out.println(new String(bytes1,0,len));
        }
    }
}
3.2 操作字符数组

操作字符数组:CharArrayWrite和CharArrayReader
CharArrayWrite:此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。
CharArrayReader:此类实现一个可用作字符输入流的字符缓冲区。
可以使用toCharArray方法和toString方法获取数据 底层维护的是一个字符数组

public class CharDemo {
    public static void main(String[] args) throws IOException {
        CharArrayWriter out = new CharArrayWriter();
        out.write("aaaa");
        out.write("bbbb");
        out.write("cccc");
        /*char[] chars = out.toCharArray();
        String s = String.valueOf(chars);*/
        String string = out.toString();
        System.out.println(string);

        CharArrayReader charArrayReader = new CharArrayReader(out.toCharArray());
        int len=0;
        char[]  chars=new char[1024];
        while ((len=charArrayReader.read(chars))!=-1){
            System.out.println(new String(chars,0,len));
        }
    }
}
3.3 操作字符串

操作字符串:StringWriter和StringReader
StringWriter:一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。
StringReader:其源为一个字符串的字符流。
底层使用的是StringBuffer

public class StringDemo {
    public static void main(String[] args) throws IOException {
        StringWriter stringWriter = new StringWriter();
        stringWriter.write("abc");
        stringWriter.write("abc");
        stringWriter.write("abc");
        stringWriter.write("abc");
        String string = stringWriter.toString();
        System.out.println(string);
        StringReader stringReader = new StringReader(string);
        int len=0;
        char[]  chars=new char[1024];
        while ((len=stringReader.read(chars))!=-1){
            System.out.println(new String(chars,0,len));
        }
    }
}
3.4 练习:将两首音乐合并为一首
  • 利用内存操作流中的操作字节数组
public class mixMusic {
    public static void main(String[] args) throws IOException {
        //创建两首歌曲的文件字节输入流
        FileInputStream fis1 = new FileInputStream("C:\\Users\\asus\\Desktop\\许巍 - 蓝莲花.mp3");
        FileInputStream fis2 = new FileInputStream("C:\\Users\\asus\\Desktop\\许巍 - 曾经的你.mp3");
        //创建一个ArrayList集合 放入两首歌 读取到内存操作流
        ArrayList<FileInputStream> list = new ArrayList<>();
        list.add(fis1);
        list.add(fis2);
        //遍历集合 读取数据。写入到内存操作流
        int len=0;
        byte[] bytes=new byte[1024];
        //创建操作字节数组的内存操作流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        for (FileInputStream fis : list) {
            while ((len=fis.read(bytes))!=-1){
                bos.write(bytes,0,len);
            }
            fis.close();
        }
        //取出两首歌曲的字节数组
        byte[] byteArray = bos.toByteArray();
        //创建内存操作流读取数据 参数传递整个的字节数组
        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
        //创建文件字节输出流
        FileOutputStream fos = new FileOutputStream("C:\\Users\\asus\\Desktop\\许巍歌曲合集.mp3");
        int len2=0;
        byte[] bytes2=new byte[1024];
        while ((len2=bis.read(bytes2))!=-1){
            fos.write(bytes2,0,len2);
        }
        fos.close();
    }
}

四、打印流PrintStream

平时我们在控制台内进行打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于PrintStream 类,这个类能够方便打印各种数据类型的值,是一种便捷的输出方式。
特点:打印流只关联目的地,不关联源文件。不能读取,只能写入

4.1 字节打印流PrintStream
4.1.2 构造方法
PrintStream(File file) 	 创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(String fileName)   创建具有指定文件名称且不带自动行刷新的新打印流。
public class PrintStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //PrintStream(File file) 创建具有指定文件且不带自动行刷新的新打印流。
        PrintStream printStream = new PrintStream(new File("a.txt"));
        //父类方法
        printStream.write("你好".getBytes());
        printStream.write("\r\n".getBytes());
        printStream.write(97);
        /*特有方法 println方法 可以写入任意类型数据 并且换行
                 print 方法 ,写入任意类型数据,不换行*/
        printStream.println("你好");//字符串
        printStream.println(true);//布尔值
        printStream.print("print方法不换行");
        printStream.print(100);
        /*同样可以通过其他方法得到PrintStream,这样不一定会往文件中写入
            System.out的返回值是一个PrintStream,这样的话,输出流关联的就是控制台打印 */
        //out 标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出
        PrintStream out = System.out;
        out.print(50);
        out.write("Java".getBytes());
        out.println("大家好");
        System.out.println("平时采用的是链式编程");
    }
}
4.2 字符打印流PrintWriter
4.2.2 构造方法
PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。
PrintWriter(String fileName)  创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
PrintWriter(OutputStream out, boolean autoFlush)  通过现有的 OutputStream 创建新的 PrintWriter。
public class PrintWriterDemo01 {
    public static void main(String[] args) throws FileNotFoundException {
        //PrintWriter(File file) 使用指定文件创建不具有自动行刷新的新 PrintWriter。
        PrintWriter printWriter = new PrintWriter(new File("b.txt"));
        printWriter.write("你好");
        printWriter.write(98);
        //字符流必须刷新才能写入到文件中 必须手动刷新
        printWriter.flush();
        printWriter.close();//关闭流
        /*PrintWriter(OutputStream out, boolean autoFlush)  通过现有的 OutputStream 创建新的 PrintWriter。
        第二个参数 是选择自动刷新的开关
        创建一个能够启动自动刷新,只会在调用println、printf 或 format 方法中的一个方法的时候,会完成自动刷新
         */
        PrintWriter printWriter1 = new PrintWriter(new FileOutputStream("bb.txt"));
        printWriter1.println("自动刷新");
        printWriter1.print("需要手动刷新才能写入文件中");
        printWriter1.close();
    }
}

4.3 使用打印流复制文本文件

由于打印流只能写入数据,所以需要找寻另一个流(这里使用BufferedReader)配合,实现文本文件的复制。

public class CopyFile {
    public static void main(String[] args) throws IOException {
        //使用BufferedReader读取文本文件
        BufferedReader br = new BufferedReader(new FileReader("mixMusic.java"));
        //使用打印流PrintWriter写入文本文件的内容,开启自动刷新
        PrintWriter printWriter = new PrintWriter(new FileOutputStream("mixMusicCopy.java"), true);
        //读取数据,写入数据
        String line=null;
        while ((line=br.readLine())!=null){
            //写入数据,并且自动刷新
            printWriter.println(line);
        }
        printWriter.close();
        br.close();
    }
}

五、键盘录入并且写入文件

要求:做到将键盘录入的数据,写入到指定文件中,并且设定一个停止按钮结束键盘的录入

public class ScannerDemo {
    public static void main(String[] args) throws IOException {
       /* InputStream in = System.in;
        Scanner scanner = new Scanner(in);
        System.in的返回值是一个输入流,可以结合BufferedReader中的readLine方法
        从屏幕读取一行
        */
       //这个时候bufferedReader关联的文本文件就是键盘录入  System.in 可以实现键盘录入数据
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        //结合BufferedWriter,将BufferedReader读取键盘录入的数据,写入到BufferedWriter关联的文件中
        BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter("PrintDemo.txt"));
        while (true){
            System.out.println("请输入录入的数据");
            String line=null;
            while ((line=bufferedReader.readLine())!=null){
                //结束条件
                if (line.equals("stop")){
                    bufferedWriter.close();
                    bufferedReader.close();
                    break;
                }
                bufferedWriter.write(line);
                bufferedWriter.newLine();
                bufferedWriter.flush();
                System.out.println("控制台打印"+line);
            }
            break;
        }
    }
}
补充:创建Scanner对象时,参数传递一个文件

Scanner(File source) 构造一个新的 Scanner,它生成的值是从指定文件扫描的。
参数为文件类,读取关联文件的数据

public class ScannerDemo02 {
    public static void main(String[] args) throws FileNotFoundException {
        //使用Scanner关联文件
        Scanner scanner = new Scanner(new File("mixMusic.java"));
       /* //扫描文件
        while (scanner.hasNextLine()){
            String line = scanner.nextLine();
            System.out.println(line);//控制台打印文件的数据
        }*/
        //使用Scanner复制文件 开启自动刷新 第一个参数需要是FileOutputStream
        PrintWriter pw = new PrintWriter(new FileOutputStream("mixMusic3.java"),true);
        while (scanner.hasNextLine()){
            pw.println(scanner.nextLine());
            pw.flush();
        }
        //关闭流
        pw.close();
        scanner.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值