【JAVA学习笔记】65 - 文件类,IO流--节点流、处理流、对象流、转换流、打印流

项目代码

https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter19/src/com/yinhai

文件

一、文件,流

文件,对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文件,excel文件..都是文件。它既可以保存一张图片, 也可以保持视频,声

文件在程序中是以流的形式来操作的

流:数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

二、常用的文件操作

1.创建文件对象相关构造器

        new File(String pathname) //根据路径构建一个File对象

        new File(File parent,String child) //根据父目录文件+子路径构建

        new File(String parent,String child) //根据父目录+子路径构建

public class FileCreate {public static void main(String[] args) {}//1 new File (String pathname)@Testpublic void create01(){String filePath = "e:\\new1.txt";File file = new File(filePath);try {file.createNewFile();System.out.println("文件创建成功");} catch (IOException e) {e.printStackTrace();}}//new File(File parent,String child) //根据父目录文件+子路径构建@Testpublic void create02(){File parentFile = new File("e:\\");String fileName = "new2.txt";File file = new File(parentFile, fileName);try {file.createNewFile();System.out.println("创建成功");} catch (IOException e) {e.printStackTrace();}}@Testpublic void create03(){String parentPath = "e:\\";String filePath = "news3.txt";File file = new File (parentPath,filePath);try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}
}

2.获取文件的相关信息

public class FileInformation {public static void main(String[] args) {}public void info(){File file = new File("e\\new1.txt");System.out.println(file.getName());//调用相应的方法,得到对应信息//获取文件名字getNameSystem.out.println("文件名字=" + file.getName());//文件绝对路径getAbsolutePathSystem.out.println("文件绝对路径=" + file.getAbsolutePath());//文件父级目录getParentSystem.out.println("文件父级目录=" + file.getParent());//文件大小(字节)lengthSystem.out.println("文件大小(字节)=" + file.length());//文件是否存在existsSystem.out.println("文件是否存在=" + file.exists());//T//是不是一个文件isFileSystem.out.println("是不是一个文件=" + file.isFile());//T//是不是一个目录isDirectorySystem.out.println("是不是一个目录=" + file.isDirectory());//F}
}

3.目录的操作和文件删除

public class Directory_ {public static void main(String[] args) {//}//判断 d:\\news1.txt 是否存在,如果存在就删除@Testpublic void m1() {String filePath = "e:\\new1.txt";File file = new File(filePath);if (file.exists()) {if (file.delete()) {System.out.println(filePath + "删除成功");} else {System.out.println(filePath + "删除失败");}} else {System.out.println("该文件不存在...");}}//判断 D:\\demo02 是否存在,存在就删除,否则提示不存在//这里我们需要体会到,在java编程中,目录也被当做文件@Testpublic void m2() {String filePath = "D:\\demo02";File file = new File(filePath);if (file.exists()) {if (file.delete()) {System.out.println(filePath + "删除成功");} else {System.out.println(filePath + "删除失败");}} else {System.out.println("该目录不存在...");}}//判断 D:\\demo\\a\\b\\c 目录是否存在,如果存在就提示已经存在,否则就创建@Testpublic void m3() {String directoryPath = "E:\\demo\\a\\b\\c";File file = new File(directoryPath);if (file.exists()) {System.out.println(directoryPath + "存在..");} else {if (file.mkdirs()) { //"E:\demo"创建一级目录使用mkdir() ,创建多级目录使用mkdirs()System.out.println(directoryPath + "创建成功..");} else {System.out.println(directoryPath + "创建失败...");}}}
}

IO流

一、IO流原理及流的分类

IO流的原理

1. I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。

2. Java程序中,对于数据的输入/输出操作以”流(stream)"的方式进行。

3. java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过方法输入或输出数据

4.输入input:读取外部数据(磁盘、 光盘等存储设备的数据)到程序(内存)中。

5.输出output:将程序(内存) 数据输出到磁盘、光盘等存储设备中

流的分类

按操作数据单位不同分为:字节流(8 bit),字符流(按字符,对应几个字节根据编码决定大小)

按数据流的流向不同分为:输入流,输出流

按流的角色的不同分为:节点流,处理流/包装流

1) Java的I0流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的。

2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

二、节点流

1.字节节点FileInputStream和FileOutputStream

1.文件字节输入流FileInputStream

InputStream抽象类是所有类字节输入流的超类

InputStream 常用的子类

1. FileInputStream:文件输入流

2. BufferedInputStream:缓冲字节输入流

3. ObjectInputStream:对象字节输入流

public class FileInputStream_ {public static void main(String[] args) {}@Testpublic void readFile01() {String filePath = "e:\\hello.txt";FileInputStream fileInputStream = null;int readDate = 0;try {fileInputStream = new FileInputStream(filePath);//如何返回-1,表示读取完毕while ((readDate = fileInputStream.read()) != -1) {System.out.print((char) readDate);}} catch (IOException e) {e.printStackTrace();} finally {try {fileInputStream.close();} catch (Exception e) {e.printStackTrace();}}}
@Testpublic void readFile02() {String filePath = "e:\\hello.txt";FileInputStream fileInputStream = null;int readDate = 0;byte[] buf = new byte[8];int readLen = 0;try {fileInputStream = new FileInputStream(filePath);//如何返回-1,表示读取完毕while ((readLen = fileInputStream.read(buf)) != -1) {System.out.print(new String(buf, 0, readLen));}} catch (IOException e) {e.printStackTrace();} finally {try {fileInputStream.close();} catch (Exception e) {e.printStackTrace();}}}
}
2.文件字节输出流FileOutputStream

public class FileOutputStream01 {public static void main(String[] args) {}/*** 演示使用FileOutputStream 将数据写到文件中,* 如果该文件不存在,则创建该文件*/@Testpublic void writeFile() {//创建 FileOutputStream对象String filePath = "e:\\a.txt";FileOutputStream fileOutputStream = null;try {//得到 FileOutputStream对象 对象//1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容//2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面fileOutputStream = new FileOutputStream(filePath,true);//写入一个字节fileOutputStream.write('H');////写入字符串String str = "hello,world!";//str.getBytes() 可以把 字符串-> 字节数组//fileOutputStream.write(str.getBytes());/*write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流*/fileOutputStream.write(str.getBytes(), 0, str.length());} catch (IOException e) {e.printStackTrace();} finally {try {fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}}}
}
3.使用FileInput和FileOutput完成文件拷贝

        

public class FileCopy_ {public static void main(String[] args) {String filePath = "e:\\test\\miku.jpg";String destFilePath = "e:\\\\mikucopy.jpg";//将该文件复制到e:\\miku.jpgFileInputStream fileInputStream =null;FileOutputStream fileOutputStream =null;try {fileInputStream = new FileInputStream(filePath);fileOutputStream = new FileOutputStream(destFilePath);//定义一个字节数组提高读取效率byte[] buf = new byte[1024];int readLen = 0;while ((readLen = fileInputStream.read(buf)) != -1){//读取到后就写入文件fileOutputStream.write(buf,0,readLen);//readLen接受到的是当前读取的长度//fileOutputStream.write(buf);//不能使用该方法,会导致及使不够也会抓到1024的长度的内容}System.out.println("拷贝完成");} catch (IOException e) {e.printStackTrace();}finally {try {//关闭输入流和输出流if(fileInputStream != null){fileInputStream.close();}if(fileOutputStream != null){fileOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}}
}

        

2.字符节点流FileReader和FileWriter

FileReader和FileWriter 是字符流,即按照字符来操作io

FileReader常用方法:

        1) new FileReader(File/String)

        2) read:每次读取单个字符,返回该字符,如果到文件末尾返回-1

        3) read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1

相关API:

        1) new String(char[]):将char[]转换成String

        2) new String(char[],off,len):将char[的指定部分转换成String

FileReader应用案例

public class FileReader_ {public static void main(String[] args) {}/*** 单个字符读取文件*/@Testpublic void readFile01() {String filePath = "e:\\test\\story.txt";FileReader fileReader = null;int data = 0;//1. 创建FileReader对象try {fileReader = new FileReader(filePath);//循环读取 使用read, 单个字符读取while ((data = fileReader.read()) != -1) {System.out.print((char) data);}} catch (IOException e) {e.printStackTrace();} finally {try {if (fileReader != null) {fileReader.close();}} catch (IOException e) {e.printStackTrace();}}}/*** 字符数组读取文件*/@Testpublic void readFile02() {System.out.println("~~~readFile02 ~~~");String filePath = "e:\\story.txt";FileReader fileReader = null;int readLen = 0;char[] buf = new char[8];//1. 创建FileReader对象try {fileReader = new FileReader(filePath);//循环读取 使用read(buf), 返回的是实际读取到的字符数//如果返回-1, 说明到文件结束while ((readLen = fileReader.read(buf)) != -1) {System.out.print(new String(buf, 0, readLen));}} catch (IOException e) {e.printStackTrace();} finally {try {if (fileReader != null) {fileReader.close();}} catch (IOException e) {e.printStackTrace();}}}}

FileWriter常用方法:

        1) new FileWriter(File/String) : 覆盖模相当于流的指针在首端

        2) new FileWriter(File/String.true) :追加模式,相当于流的指针在尾端

        3) write(int):写入单个字符

        4) write(char[]):写入指定数组

        5) write(charD,offlen):写入指定数组的指定部分

        6) write (string) :写入整个字符串

        7) write(string,off,len):写入字符串的指定部分

相关API: String类: toCharArray:将String转换成char[]

注意:FileWriter使用后,必须要关闭(close)或刷新(flush), 否则写入不到指定的文件!

public class FileWriter_ {public static void main(String[] args) {String filePath = "e:\\note.txt";//创建FileWriter对象FileWriter fileWriter = null;char[] chars = {'a', 'b', 'c'};try {fileWriter = new FileWriter(filePath);//默认是覆盖写入
//            3) write(int):写入单个字符fileWriter.write('H');
//            4) write(char[]):写入指定数组fileWriter.write(chars);
//            5) write(char[],off,len):写入指定数组的指定部分fileWriter.write("韩顺平教育".toCharArray(), 0, 3);
//            6) write(string):写入整个字符串fileWriter.write(" 你好北京~");fileWriter.write("风雨之后,定见彩虹");
//            7) write(string,off,len):写入字符串的指定部分fileWriter.write("上海天津", 0, 2);//在数据量大的情况下,可以使用循环操作.} catch (IOException e) {e.printStackTrace();} finally {try {//fileWriter.flush();//关闭文件流,等价 flush() + 关闭fileWriter.close();//对应FileWriter , 一定要关闭流,或者flush才能真正的把数据写入到文件//老韩看源码就知道原因./*看看代码private void writeBytes() throws IOException {this.bb.flip();int var1 = this.bb.limit();int var2 = this.bb.position();assert var2 <= var1;int var3 = var2 <= var1 ? var1 - var2 : 0;if (var3 > 0) {if (this.ch != null) {assert this.ch.write(this.bb) == var3 : var3;} else {this.out.write(this.bb.array(), this.bb.arrayOffset() + var2, var3);}}this.bb.clear();}*/} catch (IOException e) {e.printStackTrace();}}System.out.println("程序结束...");}
}

三、处理流

1.基本介绍

        1)节点流可以从一个特定的数据源读写数据,如FileReader、 FileWriter [源码]

                

        2)处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader. BufferedWriter [源码]

                

2.节点流和处理流的区别和联系

        1)节点流是底层流/低级流,直接跟数据源相接。

        2)处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。(面向对象,存进去后就只调用BufferedReader即可)

        3)处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连(模拟修饰器设计模式

处理流的功能主要体现在以下两个方面:

        1)性能的提高:主要以增加缓冲的方式来提高输入输出的效率。

        2)操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

public class Test_ {public static void main(String[] args) {BufferedReader_ bufferedReader = new BufferedReader_(new FileReader_());BufferedReader_ bufferedReader1 = new BufferedReader_(new StringReader_());bufferedReader.readFile(5);bufferedReader.readString(5);}
}
public class BufferedReader_ extends Reader_{private Reader_ reader_;public BufferedReader_(Reader_ reader_) {this.reader_ = reader_;}//让方法更灵活多次读取public void readFile(int num){for (int i = 0; i < num; i++) {reader_.readFile();}}public void readString(int num){for (int i = 0; i < num; i++) {reader_.readString();}}
}public abstract class Reader_ {//抽象类public void readString(){}public void readFile(){}
}
public class StringReader_ extends Reader_{public void readString(){}
}
public class FileReader_  extends Reader_{public void readFile(){}
}

3.字符处理流BufferedReader和BufferedWriter

BufferedReader

BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的关闭时处理流,只需要关闭外层流印可

        1)使用BufferedReader读取文本文件,并显示在控制台

public class BufferedReader_ {public static void main(String[] args) throws Exception {String filePath = "e:\\test\\BufferedReader_.java";//创建bufferedReaderBufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));//读取String line; //按行读取, 效率高//说明//1. bufferedReader.readLine() 是按行读取文件//2. 当返回null 时,表示文件读取完毕while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}//关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流//FileReader。/*public void close() throws IOException {synchronized (lock) {if (in == null)return;try {in.close();//in 就是我们传入的 new FileReader(filePath), 关闭了.} finally {in = null;cb = null;}}}*/bufferedReader.close();}
}

BufferedWriter
public class BufferedWriter_ {public static void main(String[] args) throws IOException {String filePath = "e:\\test\\testBufferedWriter_.txt";//创建BufferedWriter//说明://1. new FileWriter(filePath, true) 表示以追加的方式写入//2. new FileWriter(filePath) , 表示以覆盖的方式写入BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath/*,true*/));bufferedWriter.write("hello, 韩顺平教育!");bufferedWriter.newLine();//插入一个和系统相关的换行bufferedWriter.write("hello2, 韩顺平教育!");bufferedWriter.newLine();bufferedWriter.write("hello3, 韩顺平教育!");bufferedWriter.newLine();//说明:关闭外层流即可 , 传入的 new FileWriter(filePath) ,会在底层关闭bufferedWriter.close();}
}

                 

使用BufferedReader和BufferedWriter完成拷贝
public class BufferedCopy_ {public static void main(String[] args) {//Buffered是字符流 所以不要去操作二进制文件[声音,视频,doc,pdf等等]String srcFilePath = "e:\\test\\story.txt";String destFilePath = "e:\\test\\testBufferedCopy.txt";String line;BufferedReader bufferedReader = null;BufferedWriter bufferedWriter = null;try {bufferedReader = new BufferedReader(new FileReader(srcFilePath));bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));//读取写入 readLine是读取一行的内容,但是没有换行while ((line = bufferedReader.readLine()) != null) {//每读取一行就写入bufferedWriter.write(line);bufferedWriter.newLine();}} catch (IOException e) {e.printStackTrace();} finally {try {if (bufferedReader != null) {bufferedReader.close();}if (bufferedWriter != null) {bufferedWriter.close();}} catch (IOException e) {e.printStackTrace();}}}
}

4.字节处理流BufferedInputStream和BufferedOutputStream

BufferedInputStream是字节流在创建BufferedInputStream会创建一个内部缓冲区数组.

BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

public class BufferedCopy02 {public static void main(String[] args) {//        String srcFilePath = "e:\\Koala.jpg";
//        String destFilePath = "e:\\hsp.jpg";
//        String srcFilePath = "e:\\0245_韩顺平零基础学Java_引出this.avi";
//        String destFilePath = "e:\\hsp.avi";String srcFilePath = "e:\\a.java";String destFilePath = "e:\\a3.java";//创建BufferedOutputStream对象BufferedInputStream对象BufferedInputStream bis = null;BufferedOutputStream bos = null;try {//因为 FileInputStream  是 InputStream 子类bis = new BufferedInputStream(new FileInputStream(srcFilePath));bos = new BufferedOutputStream(new FileOutputStream(destFilePath));//循环的读取文件,并写入到 destFilePathbyte[] buff = new byte[1024];int readLen = 0;//当返回 -1 时,就表示文件读取完毕while ((readLen = bis.read(buff)) != -1) {bos.write(buff, 0, readLen);}System.out.println("文件拷贝完毕~~~");} catch (IOException e) {e.printStackTrace();} finally {//关闭流 , 关闭外层的处理流即可,底层会去关闭节点流try {if(bis != null) {bis.close();}if(bos != null) {bos.close();}} catch (IOException e) {e.printStackTrace();}}}
}

四、对象流

看一个需求

1.将int num = 100这个int数据保存到文件中,注意不是100数字,而是int 100,并且,能够从文件直接恢复int 100

2.将Dog dog = new Dog(”小黄”, 3)这个dog对象保存到文件中,并且能够从文件恢复,

3.上面的要求, 就是能够将基本数据类型或者对象进行序列化和反序列化操作

序列化和反序列化

1.序列化就是在保存数据时,保存数据的值和数据类型

2.反序列化就是在恢复数据时,恢复数据的值和数据类型

3.需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之-:

        Serializable //这是一 个标记接口(推荐使用该接口)

        Externalizable //该接口有两个方法需要实现

功能:提供了对基本类型或对象类型的序列化和反序列化的方法

1. ObjectOutputStream 提供序列化功能

2. ObjectInputStream 提供反序列化功能

1. ObjectOutputStream 序列化

Dog类需要放在可以引用的位置 不然反序列化调用不到

public class ObjectOutStream_ {public static void main(String[] args) throws Exception {//序列化后,保存的文件格式,不是存文本,而是按照他的格式来保存String filePath = "e:\\test\\objectData.dat";ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));//序列化数据到 e:\data.datoos.writeInt(100);// int -> Integer (实现了 Serializable)oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)oos.writeChar('a');// char -> Character (实现了 Serializable)oos.writeDouble(9.5);// double -> Double (实现了 Serializable)oos.writeUTF("韩顺平教育");//String(实现了 Serializable)//保存一个dog对象oos.writeObject(new Dog("旺财", 10, "日本", "白色"));oos.close();System.out.println("数据保存完毕(序列化形式)");}
}
class Dog implements Serializable {private String name;private int age;private String form;private String color;public Dog(String name, int age, String form, String color) {this.name = name;this.age = age;this.form = form;this.color = color;}
}

2. ObjectInputStream 反序列化

public class ObjectInputStream_ {public static void main(String[] args) throws IOException, ClassNotFoundException {//指定反序列化的文件String filePath = "e:\\test\\objectData.dat";ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));//读取//1. 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致//2. 否则会出现异常System.out.println(ois.readInt());System.out.println(ois.readBoolean());System.out.println(ois.readChar());System.out.println(ois.readDouble());System.out.println(ois.readUTF());//dog 的编译类型是 Object , dog 的运行类型是 DogObject dog = ois.readObject();System.out.println("运行类型=" + dog.getClass());System.out.println("dog信息=" + dog);//底层 Object -> Dog//这里是特别重要的细节://1. 如果我们希望调用Dog的方法, 需要向下转型//2. 需要我们将Dog类的定义,放在到可以引用的位置,Dog类公有化Dog dog2 = (Dog)dog;System.out.println(dog2.getName()); //旺财..//关闭流, 关闭外层流即可,底层会关闭 FileInputStream 流ois.close();}
}

3.注意事项和细节说明

        1)读写顺序要一致

        2)要求实现序列化或反序列化对象,需要实现Serializable

        3)序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性

        4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员

        5)序列化对象时,要求里面属性的类型也需要实现序列化接口

        6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

五、标准输入输出流

public class InputAndOutput {public static void main(String[] args) {//System 类 的 public final static InputStream in = null;// System.in 编译类型   InputStream// System.in 运行类型   BufferedInputStream// 表示的是标准输入 键盘System.out.println(System.in.getClass());//1. System.out public final static PrintStream out = null;//2. 编译类型 PrintStream//3. 运行类型 PrintStream//4. 表示标准输出 显示器System.out.println(System.out.getClass());//传统方法System.out.println(); 是使用out对象将数据输出到显示器System.out.println("hello, 韩顺平教育~");//传统的方法,Scanner是从标准输入键盘接收数据Scanner scanner = new Scanner(System.in);System.out.println("输入内容");String next = scanner.next();System.out.println("next=" + next);}
}

六、转换流

1.引入

public class CodeQuestion {public static void main(String[] args) throws IOException {//读取e:\\a.txt 文件到程序//思路//1.  创建字符输入流 BufferedReader [处理流]//2. 使用 BufferedReader 对象读取a.txt//3. 默认情况下,读取文件是按照 utf-8 编码,但可能不一定是utf-8编码,就会出现乱码情况String filePath = "e:\\a.txt";BufferedReader br = new BufferedReader(new FileReader(filePath));String s = br.readLine();System.out.println("读取到的内容: " + s);br.close();}
}

                

2.介绍

1. InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)成Reader(字符流)

2. OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)

3.当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流

4.可以在使用时指定编码格式(比如utf-8, gbk, gb2312, IS08859-1等)

3.InputStreamReader使用

public class InputStreamReader_ {public static void main(String[] args) throws IOException {String filePath = "e:\\a.txt";//解读//1. 把 FileInputStream 转成 InputStreamReader//2. 指定编码 gbk//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");//3. 把 InputStreamReader 传入 BufferedReader//BufferedReader br = new BufferedReader(isr);//将2 和 3 合在一起BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "gbk"));//4. 读取String s = br.readLine();System.out.println("读取内容=" + s);//5. 关闭外层流br.close();}
}

4.OutputStreamWriter的使用

public class OutputStreamWriter_ {public static void main(String[] args) throws IOException {String filePath = "e:\\test\\nihao.txt";String charSet = "utf-8";BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath), charSet));bufferedWriter.write("hi, 你好");bufferedWriter.close();System.out.println("按照 " + charSet + " 保存文件成功~");}
}

                

七、打印流(只有输出流,没有输入流)

1.PrintStream的使用

public class PrintStream_ {public static void main(String[] args) throws IOException {PrintStream out = System.out;//在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器/*public void print(String s) {if (s == null) {s = "null";}write(s);}*/out.print("john, hello");//因为print底层使用的是write , 所以我们可以直接调用write进行打印/输出out.write("韩顺平,你好".getBytes());out.close();//我们可以去修改打印流输出的位置/设备//1. 输出修改成到 "e:\\f1.txt"//2. "hello, 韩顺平教育~" 就会输出到 e:\f1.txt//3. public static void setOut(PrintStream out) {//        checkIO();//        setOut0(out); // native 方法,修改了out//   }System.setOut(new PrintStream("e:\\test\\f1.txt"));System.out.println("hello, 韩顺平教育~");}
}

2.PrintWriter的使用

        ​​​​​​​        

public class PrintWriter_ {public static void main(String[] args) throws IOException {//PrintWriter printWriter = new PrintWriter(System.out);//打印到显示器 标准输出PrintWriter printWriter = new PrintWriter(new FileWriter("e:\\f2.txt"));printWriter.print("hi, 北京你好~~~~");printWriter.close();//flush + 关闭流, 才会将数据写入到文件..}
}

八、Properties类

1.引入

如下一个配置文件mysql.properties

        ip = 192.168.0.13

        user = root

        pwd = 12345

请问编程读取ip、user 和pwd的值是多少

分析

1. 传统的方法

2. 使用Properties类可以方便实现

2.介绍

1)专门用于读写配置文件的集合类

配置文件的格式:

        键=值

        键=值

2)注意:键值对不需要有空格,值不需要用引号一起来。 默认类型是String

3) Properties的常见方法

        load:加载配置文件的键值对到Properties对象

        list:将数据显示到指定设备/流对象

        getProperty(key):根据键获取值

        setProperty(key,value);:设置键值对到Properties对象

        store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码

3.应用

1.使用Properties类完成对mysql.properties的读取,看老师代码演示

public class Properties02 {public static void main(String[] args) throws IOException {//使用Properties 类来读取mysql.properties 文件//1. 创建Properties 对象Properties properties = new Properties();//2. 加载指定配置文件properties.load(new FileReader("src\\mysql.properties"));//3. 把k-v显示控制台properties.list(System.out);//4. 根据key 获取对应的值String user = properties.getProperty("user");String pwd = properties.getProperty("pwd");System.out.println("用户名=" + user);System.out.println("密码是=" + pwd);}
}

2.使用Proper ties类添加key-val到新文件mysql2.properties中

3.使用Properties类完成对mysql2.properties的读取,并修改某个key-val

public class Properties03 {public static void main(String[] args) throws IOException {//使用Properties 类来创建 配置文件, 修改配置文件内容Properties properties = new Properties();//创建//1.如果该文件没有key 就是创建//2.如果该文件有key ,就是修改/*Properties 父类是 Hashtable , 底层就是Hashtable 核心方法public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) {throw new NullPointerException();}// Makes sure the key is not already in the hashtable.Entry<?,?> tab[] = table;int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;@SuppressWarnings("unchecked")Entry<K,V> entry = (Entry<K,V>)tab[index];for(; entry != null ; entry = entry.next) {if ((entry.hash == hash) && entry.key.equals(key)) {V old = entry.value;entry.value = value;//如果key 存在,就替换return old;}}addEntry(hash, key, value, index);//如果是新k, 就addEntryreturn null;}*/properties.setProperty("charset", "utf8");properties.setProperty("user", "汤姆");//注意保存时,是中文的 unicode码值properties.setProperty("pwd", "888888");//底层就是hashTable,所以set就是替换K-V//将k-v 存储文件中即可properties.store(new FileOutputStream("src\\mysql2.properties"), "hello,world");//comments代表注释System.out.println("保存配置文件成功~");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/135169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MongoDB】索引 - 数组字段的多键索引

数组字段创建索引时&#xff0c;MongoDB会为数组中的每个元素创建索引键&#xff08;多键索引&#xff09;&#xff0c;多键索引支持数组字段的高效查询。 一、准备工作 这里准备一些数据 db.shop.insertMany([{_id: 1, name: "水果店1", fruits: ["apple&qu…

Python测试框架之pytest快速入门

pytest是一种流行的Python测试框架&#xff0c;支持创建简单的单元测试&#xff0c;也支持创建复杂的功能和集成测试。它提供了一系列有用的功能&#xff0c;能够方便地编写&#xff0c;组织和运行测试用例&#xff0c;并生成丰富的测试报告。 pytest的主要特点包括&#xff1…

智能网联汽车有哪些信息安全场景

目录 1.车内安全通信 2.车云安全通信 3.安全启动 4.车载应用程序保护 5.入侵检测防御与日志管理系统 在聊完车载信息安全需求之后&#xff0c;势必要去看看​应用场景有哪些。根据之前的开发经验简单聊一下我知道的&#xff0c;还有很多没有讲&#xff0c;比如说车云之间具…

基于springboot+vue开发的教师工作量管理系

教师工作量管理系 springboot31 源码合集&#xff1a;www.yuque.com/mick-hanyi/javaweb 源码下载&#xff1a;博主私 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了教师工作量管理系统的开发全过程。通过…

基于Qt窗口文件新建_编辑_打开_保存_另存_剪切和复制和粘贴项目(文件操作直接套源码)

# .pro文件 QT += widgetsrequires(qtConfig(filedialog))​HEADERS = mainwindow.hSOURCES = main.cpp \ mainwindow.cppRESOURCES = sdi.qrc​# installtarget.path = $$[QT_INSTALL_EXAMPLES]/widgets/mainwindows/sdiINSTALLS += target​…

元宇宙是否为噱头?若不是,什么是元宇宙?他的概念、技术、应用和影响是什么?

文章来源&#xff1a;元宇宙的概念、技术、应用与影响——一项系统性文献综述 - 中国知网 (cnki.net) 摘要 [目的/意义]系统综述与分析当前国内外的元宇宙研究现状&#xff0c;有利于准确把握元宇宙发展方向&#xff0c;强化元宇宙基础研究&#xff0c;争取元宇宙建构权。[方法…

SpringBoot案例学习(黑马程序员day10,day11)

1 环境准备&#xff1a; 1.idea 创建spring项目&#xff0c;选择springweb,mybatis framework ,sql drive框架 2.添加pom.xml依赖&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependen…

SQL SERVER Inregration Services-OLE DB、Oracle和ODBC操作

OLE DB链接器 OLE DB插件下载&#xff1a;https://learn.microsoft.com/zh-cn/sql/connect/oledb/download-oledb-driver-for-sql-server?viewsql-server-ver16 配置OLE DB Connection Manager 在点击“新建”时&#xff0c;会弹出警告信息“不支持指定的提供程序&#xff0…

【mysql】CommunicationsException: Communications link failure

CommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. 通信异常&#xff1a;通信链路故障 最后一个成功发送到服务器的数据包是0毫秒前…

数据结构-双向链表

目录 1.带头双向循环链表&#xff1a; 2. 带头双向循环链表的实现&#xff1a; 双向链表初始化&#xff1a; 双向链表打印&#xff1a; 开辟节点函数&#xff1a; 双向链表头插&#xff1a; 双向链表尾插&#xff1a; 双向链表头删&#xff1a; 双向链表尾删&#xff…

HMM与LTP词性标注之马尔科夫模型(HMM原理剖析)

文章目录 问题描述viterbi算法联合概率与条件概率维特比算法实例 问题描述 viterbi算法 联合概率与条件概率 维特比算法实例

界面控件DevExpress WPF PDF Viewer,更快实现应用的PDF文档浏览

DevExpress WPF PDF Viewer控件可以轻松地直接在Windows应用程序中显示PDF文档&#xff0c;而无需在最终用户的机器上安装外部PDF查看器。 P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress…

【寒武纪(3)】媒体处理系统的系统控制、视频输入和后处理子系统

系统控制 文章目录 系统控制1、配置视频缓存池Video Pool2、配置硬件IP为在线工作&#xff08;不通过DDR数据交互&#xff09;/ 离线工作&#xff08;写入DDR&#xff09;模式3、硬IP可以使用 非Video Block &#xff08;VB&#xff09;内存4、配置是否启动内存传递的压缩 视频…

【Hadoop】YARN容量调度器详解

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&am…

Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

[架构之路-244]:目标系统 - 设计方法 - 软件工程 - 软件开发方法:结构化、面向对象、面向服务、面向组件的开发方法

目录 前言&#xff1a; 一、概述: 软件聚合的程度由简单到复杂 二、主要开发方法详见 2.1 结构化的开发方法 2.2 面对对象的开发方法 2.3 面向服务的开发方法 2.4 面向组件的开发方法 三、不同开发方法比较 3.1 结构化开发方法 3.2 面向对象(OOP)开发方法 3.3 面向服…

【计算机网络】网络层IP协议

文章目录 1. IP协议介绍2. IP报头3. IP的分片和组装4. IP地址网段划分特殊的IP地址子网、局域网、网段的区别IP地址的数量限制 5. 公网IP和私有IP6. NAT技术7. 路由Route 1. IP协议介绍 IP协议&#xff08;Internet Protocol&#xff09;是一种最常用的网络层协议&#xff0c;…

CSS 边框、轮廓线

一、CSS边框&#xff1a; CSS边框属性允许指定一个元素边框的样式和颜色。 1&#xff09;、边框样式&#xff1a;border-style属性用来定义边框的样式&#xff0c;border-style值&#xff1a; 2&#xff09;、边框宽度&#xff1a;border-width属性用于指定边框宽度。指定变宽…

2023-11-07 C语言链接库编译命令

点击 <C 语言编程核心突破> 快速C语言入门 C语言链接库编译命令 前言一、引入库文件, 包括头文件和lib库二、简单示例总结 前言 要解决问题: 一般没有给新手的链接库编译命令学习资料, 然而, 不解决这个问题, 调用库就能折腾到劝退, 我近日回答一个问题, 很简单, 调用…

【 Docker: 数据卷挂载】

背景 Docker只提供了容器运行的必备依赖&#xff0c;但是一些编辑等操作的依赖是不支持的&#xff0c;如vi操作容器内部文件、将静态资源拷贝到容器内来等。 docker pull nginx docker run -d -p 81:80 --namemynginx -v D:/docker/nginx/www:/usr/share/nginx/www -v D:/dock…