当前位置: 首页 > news >正文

Java基础——I/O

一、异常

异常是程序中可能出现的问题,它的父类是Exception。异常分为两类,编译时异常、运行时异常。

  • 编译时异常:没有继承RuntimeException的异常,直接继承于Exception。编译阶段就会错误提示。
  • 运行时异常:RuntimeException本身和子类。编译阶段没有错误提示,运行时有异常会提示。

JVM默认处理异常的方式:

1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
2.程序停止执行。异常下面的代码不会再执行。


public class ExceptionDemo6 {public static void main(String[] args) {/*自己处理(捕获异常)格式:try {可能出现异常的代码;} catch(异常类名 变量名) {异常的处理代码;}好处:可以让程序继续往下执行,不会停止*/int[] arr = {1, 2, 3, 4, 5, 6};try{//可能出现异常的代码;System.out.println(arr[10]);//此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象//new ArrayIndexOutOfBoundsException();//拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象//如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码//当catch里面所有的代码执行完毕,继续执行try...catch体系下面的其他代码}catch(ArrayIndexOutOfBoundsException e){//如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理System.out.println("索引越界了");}System.out.println("看看我执行了吗?");}
}

关于异常的四个问题:

1.如果try中没有遇到问题,怎么执行?
会把try里面所有的代码全部执行完毕,不会执行catch里面的代码
注意: 只有当出现了异常才会执行catch里面的代码

2.如果try中可能会遇到多个问题,怎么执行?
会写多个catch与之对应
细节: 如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
在JDK7之后,我们可以在catch中同时捕获多个异常,中间用|进行隔开
表示如果出现了A异常或者B异常的话,采取同一种处理方案
3.如果try中遇到的问题没有被捕获,怎么执行?
相当于try…catch的代码白写了,最终还是会交给虚拟机进行处理。
4. 如果try中遇到了问题,那么try下面的其他代码还会执行吗?
下面的代码就不会执行了,直接跳转到对应的catch当中,执行catch里面的语句体,但是如果没有对应catch与之匹配,那么还是会交给虚拟机进行处理

异常中的常见方法

  • public String getMessage() 返回此 throwable 的详细消息字符串
  • public String toString() 返回此可抛出的简短描述
  • public void printStackTrace() 在底层是利用System.err.println进行输出
    把异常的错误信息以红色字体输出在控制台
    细节:仅仅是打印信息,不会停止程序运行
int[] arr = {1, 2, 3, 4, 5, 6};try {System.out.println(arr[10]);} catch (ArrayIndexOutOfBoundsException e) {String message = e.getMessage();System.out.println(message);//Index 10 out of bounds for length 6String str = e.toString();System.out.println(str);//java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6e.printStackTrace();}System.out.println("看看我执行了吗?");//正常的输出语句//System.out.println(123);//错误的输出语句(而是用来打印错误信息)//System.err.println(123);}
}

抛出异常

  • throws:写在方法定义处,表示声明一个异常。告诉调用者,使用本方法可能会有哪些异常。
  • throw :写在方法内,结束方法。手动抛出异常对象,交给调用者。方法中下面的代码不再执行了。
public class ExceptionDemo12 {public static void main(String[] args) {
/*需求:定义一个方法求数组的最大值
*/int[] arr = null;int max = 0;try {max = getMax(arr);} catch (NullPointerException e) {System.out.println("空指针异常");} catch (ArrayIndexOutOfBoundsException e) {System.out.println("索引越界异常");}System.out.println(max);}public static int getMax(int[] arr)/* throws NullPointerException,ArrayIndexOutOfBoundsException*/{if(arr == null){//手动创建一个异常对象,并把这个异常交给方法的调用者处理//此时方法就会结束,下面的代码不会再执行了throw new NullPointerException();}if(arr.length == 0){//手动创建一个异常对象,并把这个异常交给方法的调用者处理//此时方法就会结束,下面的代码不会再执行了throw new ArrayIndexOutOfBoundsException();}System.out.println("看看我执行了吗?");int max = arr[0];for (int i = 1; i < arr.length; i++) {if(arr[i] > max){max = arr[i];}}return max;}
}

二、文件File

FIle概述和构造方法

1.File对象表示路径,可以是文件、也可以是文件夹。这个路径可以是存在的,也可以是不存在的
2.绝对路径带盘符,相对路径不带盘符,默认到当前项目下去找

public class FileDemo1 {public static void main(String[] args) {/*public File(String pathname)                根据文件路径创建文件对象public File(String parent, String child)    根据父路径名字符串和子路径名字符串创建文件对象public File(File  parent, String child)     根据父路径对应文件对象和子路径名字符串创建文件对象C:\Users\alienware\Desktop\:转义字符*///1.根据字符串表示的路径,变成File对象String str = "C:\\Users\\alienware\\Desktop\\a.txt";File f1 = new File(str);System.out.println(f1);//C:\Users\alienware\Desktop\a.txt//2.父级路径:C:\Users\alienware\Desktop//子级路径:a.txtString parent = "C:\\Users\\alienware\\Desktop";String child = "a.txt";File f2 = new File(parent,child);System.out.println(f2);//C:\Users\alienware\Desktop\a.txtFile f3 = new File(parent + "\\" + child);System.out.println(f3);//C:\Users\alienware\Desktop\a.txt//3.把一个File表示的路径和String表示路径进行拼接File parent2 = new File("C:\\Users\\alienware\\Desktop");String child2 = "a.txt";File f4 = new File(parent2,child2);System.out.println(f4);//C:\Users\alienware\Desktop\a.txt}
}

File的成员方法

public class FileDemo2 {public static void main(String[] args) throws IOException{/*public boolean isDirectory()        判断此路径名表示的File是否为文件夹public boolean isFile()             判断此路径名表示的File是否为文件public boolean exists()             判断此路径名表示的File是否存在*///1.对一个文件的路径进行判断File f1 = new File("D:\\aaa\\a.txt");System.out.println(f1.isDirectory());//falseSystem.out.println(f1.isFile());//trueSystem.out.println(f1.exists());//trueSystem.out.println("--------------------------------------");//2.对一个文件夹的路径进行判断File f2 = new File("D:\\aaa\\bbb");System.out.println(f2.isDirectory());//trueSystem.out.println(f2.isFile());//falseSystem.out.println(f2.exists());//trueSystem.out.println("--------------------------------------");//3.对一个不存在的路径进行判断File f3 = new File("D:\\aaa\\c.txt");System.out.println(f3.isDirectory());//falseSystem.out.println(f3.isFile());//falseSystem.out.println(f3.exists());//false//---------------------------------------------------------------------/*public long length()                返回文件的大小(字节数量)public String getAbsolutePath()     返回文件的绝对路径public String getPath()             返回定义文件时使用的路径public String getName()             返回文件的名称,带后缀public long lastModified()          返回文件的最后修改时间(时间毫秒值)*///1.length  返回文件的大小(字节数量)//细节1:这个方法只能获取文件的大小,单位是字节//如果单位我们要是M,G,可以不断的除以1024//细节2:这个方法无法获取文件夹的大小//如果我们要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加在一起。File f1 = new File("D:\\aaa\\a.txt");long len = f1.length();System.out.println(len);//12File f2 = new File("D:\\aaa\\bbb");long len2 = f2.length();System.out.println(len2);//0System.out.println("====================================");//2.getAbsolutePath 返回文件的绝对路径File f3 = new File("D:\\aaa\\a.txt");String path1 = f3.getAbsolutePath();System.out.println(path1);File f4 = new File("myFile\\a.txt");String path2 = f4.getAbsolutePath();System.out.println(path2);System.out.println("====================================");//3.getPath 返回定义文件时使用的路径File f5 = new File("D:\\aaa\\a.txt");String path3 = f5.getPath();System.out.println(path3);//D:\aaa\a.txtFile f6 = new File("myFile\\a.txt");String path4 = f6.getPath();System.out.println(path4);//myFile\a.txtSystem.out.println("====================================");//4.getName 获取名字//细节1://a.txt://      a 文件名//      txt 后缀名、扩展名//细节2://文件夹:返回的就是文件夹的名字File f7 = new File("D:\\aaa\\a.txt");String name1 = f7.getName();System.out.println(name1);File f8 = new File("D:\\aaa\\bbb");String name2 = f8.getName();System.out.println(name2);//bbbSystem.out.println("====================================");//5.lastModified  返回文件的最后修改时间(时间毫秒值)File f9 = new File("D:\\aaa\\a.txt");long time = f9.lastModified();System.out.println(time);//1667380952425
//---------------------------------------------------------------------/*public boolean createNewFile()      创建一个新的空的文件public boolean mkdir()              创建单级文件夹public boolean mkdirs()             创建多级文件夹public boolean delete()             删除文件、空文件夹*///1.createNewFile 创建一个新的空的文件//细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true//      如果当前路径表示的文件是存在的,则创建失败,方法返回false//细节2:如果父级路径是不存在的,那么方法会有异常IOException//细节3:createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件/*File f1 = new File("D:\\aaa\\ddd");boolean b = f1.createNewFile();System.out.println(b);//true*///2.mkdir   make Directory,文件夹(目录)//细节1:windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false//细节2:mkdir方法只能创建单级文件夹,无法创建多级文件夹。/*  File f2 = new File("D:\\aaa\\aaa\\bbb\\ccc");boolean b = f2.mkdir();System.out.println(b);*///3.mkdirs   创建多级文件夹//细节:既可以创建单级的,又可以创建多级的文件夹File f3 = new File("D:\\aaa\\ggg");boolean b = f3.mkdirs();System.out.println(b);//true
//---------------------------------------------------------------------/*public boolean delete()             删除文件、空文件夹细节:如果删除的是文件,则直接删除,不走回收站。如果删除的是空文件夹,则直接删除,不走回收站如果删除的是有内容的文件夹,则删除失败*///1.创建File对象File f1 = new File("D:\\aaa\\eee");//2.删除boolean b = f1.delete();System.out.println(b);//public File[] listFiles()       获取当前该路径下所有内容//1.创建File对象File f = new File("D:\\aaa");//2.listFiles方法//作用:获取aaa文件夹里面的所有内容,把所有的内容放到数组中返回File[] files = f.listFiles();for (File file : files) {//file依次表示aaa文件夹里面的每一个文件或者文件夹System.out.println(file);}
//---------------------------------------------------------------------/*public static File[] listRoots()                列出可用的文件系统根public String[] list()                          获取当前该路径下所有内容public String[] list(FilenameFilter filter)     利用文件名过滤器获取当前该路径下所有内容(掌握)public File[] listFiles()                获取当前该路径下所有内容public File[] listFiles(FileFilter filter)      利用文件名过滤器获取当前该路径下所有内容public File[] listFiles(FilenameFilter filter)  利用文件名过滤器获取当前该路径下所有内容*//*  //1.listRoots  获取系统中所有的盘符File[] arr = File.listRoots();System.out.println(Arrays.toString(arr));//2.list()    获取当前该路径下所有内容(仅仅能获取名字)File f1 = new File("D:\\aaa");String[] arr2 = f1.list();for (String s : arr2) {System.out.println(s);}*///3.list(FilenameFilter filter)  利用文件名过滤器获取当前该路径下所有内容//需求:我现在要获取D:\\aaa文件夹里面所有的txt文件File f2 = new File("D:\\aaa");//accept方法的形参,依次表示aaa文件夹里面每一个文件或者文件夹的路径//参数一:父级路径//参数二:子级路径//返回值:如果返回值为true,就表示当前路径保留//        如果返回值为false,就表示当前路径舍弃不要String[] arr3 = f2.list(new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {File src = new File(dir,name);return src.isFile() && name.endsWith(".txt");}});System.out.println(Arrays.toString(arr3));}
}//---------------------------------------------------------------------/*(掌握)public File[] listFiles()                获取当前该路径下所有内容public File[] listFiles(FileFilter filter)      利用文件名过滤器获取当前该路径下所有内容public File[] listFiles(FilenameFilter filter)  利用文件名过滤器获取当前该路径下所有内容*///1.创建File对象File f = new File("D:\\aaa");//2.需求:打印里面所有的txt文件File[] arr = f.listFiles();for (File file : arr) {//file依次表示aaa文件夹里面每一个文件或者文件夹的路径if(file.isFile() && file.getName().endsWith(".txt")){System.out.println(file);}}
//---------------------------------------------------------------------//创建File对象File f = new File("D:\\aaa");//调用listFiles(FileFilter filter)File[] arr1 = f.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {return pathname.isFile() && pathname.getName().endsWith(".txt");}});//调用listFiles(FilenameFilter filter)File[] arr2 = f.listFiles(new FilenameFilter() {@Overridepublic boolean accept(File dir, String name) {File src = new File(dir, name);return src.isFile() && name.endsWith(".txt");}});System.out.println(Arrays.toString(arr2));

三、I/O流(字节流、字符流)

I/O流是指存储和读取数据的解决方案:I表示input,O表示output。
I/O流用于读写数据,如本地文件、网络等。
输出流是从程序到文件,输入流是从文件到程序
I/O流分为字节流和字符流。
字节流:可以操作所有类型的文件
字符流:只能操作纯文本文件(用windows系统自带的记事本打开并且能读懂的文件,如txt文件,md文件,xml文件,lrc文件等)

字节输出流

字节输出流的基本用法

public class ByteStreamDemo1 {public static void main(String[] args) throws IOException {/** 演示:字节输出流FileOutputStream* 实现需求:写出一段文字到本地文件中。(暂时不写中文)** 实现步骤:*       创建对象*       写出数据*       释放资源* *///1.创建对象//写出 输出流 OutputStream//本地文件    FileFileOutputStream fos = new FileOutputStream("myio\\a.txt");//2.写出数据fos.write(97);//3.释放资源fos.close();}
}

字节输出流的细节

public class ByteStreamDemo2 {public static void main(String[] args) throws IOException {/*字节输出流的细节:1.创建字节输出流对象细节1:参数是字符串表示的路径或者是File对象都是可以的细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。细节3:如果文件已经存在,则会清空文件2.写数据细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符‘9’‘7’3.释放资源每次使用完流之后都要释放资源*///1.创建对象FileOutputStream fos = new FileOutputStream("myio\\a.txt");//2.写出数据fos.write(57);fos.write(55);//3.释放资源fos.close();while(true){}}
}

字节输出流写出数据三种方式

public class ByteStreamDemo3 {public static void main(String[] args) throws IOException {/*void write(int b)                       一次写一个字节数据void write(byte[] b)                    一次写一个字节数组数据void write(byte[] b, int off, int len)  一次写一个字节数组的部分数据参数一:数组参数二:起始索引  0参数三:个数      3*///1.创建对象FileOutputStream fos = new FileOutputStream("myio\\a.txt");//2.写出数据//fos.write(97); // a//fos.write(98); // bbyte[] bytes = {97, 98, 99, 100, 101};/* fos.write(bytes);*/fos.write(bytes,1,2);// b c//3.释放资源fos.close();}
}

换行和续写

public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {/*换行写:再次写出一个换行符就可以了windows: \r\nLinux:    \nMac:      \r细节:在windows操作系统当中,java对回车换行进行了优化。虽然完整的是\r\n,但是我们写其中一个\r或者\n,java也可以实现换行,因为java在底层会补全。建议:不要省略,还是写全了。续写:如果想要续写,打开续写开关即可开关位置:创建对象的第二个参数默认false:表示关闭续写,此时创建对象会清空文件手动传递true:表示打开续写,此时创建对象不会清空文件*///1.创建对象FileOutputStream fos = new FileOutputStream("myio\\a.txt",true);//2.写出数据String str = "kankelaoyezuishuai";byte[] bytes1 = str.getBytes();fos.write(bytes1);//再次写出一个换行符就可以了String wrap = "\r\n";byte[] bytes2 = wrap.getBytes();fos.write(bytes2);String str2 = "666";byte[] bytes3 = str2.getBytes();fos.write(bytes3);//3.释放资源fos.close();}
}

字节输入流

字节输入流的基本用法

public class ByteStreamDemo1 {public static void main(String[] args) throws IOException {/** 演示:字节输入流FileInputStream* 实现需求:读取文件中的数据。(暂时不写中文)** 实现步骤:*       创建对象*       读取数据*       释放资源* *///1.创建对象FileInputStream fis = new FileInputStream("myio\\a.txt");//2.读取数据int b1 = fis.read();System.out.println((char)b1);int b2 = fis.read();System.out.println((char)b2);int b3 = fis.read();System.out.println((char)b3);int b4 = fis.read();System.out.println((char)b4);int b5 = fis.read();System.out.println((char)b5);int b6 = fis.read();System.out.println(b6);//-1//3.释放资源fis.close();}
}

字节输入流的细节

public class ByteStreamDemo2 {public static void main(String[] args) throws IOException {/*字节输入流的细节:1.创建字节输入流对象细节1:如果文件不存在,就直接报错。Java为什么会这么设计呢?输出流:不存在,创建把数据写到文件当中输入流:不存在,而是报错呢?因为创建出来的文件是没有数据的,没有任何意义。所以Java就没有设计这种无意义的逻辑,文件不存在直接报错。程序中最重要的是:数据。2.写数据细节1:一次读一个字节,读出来的是数据在ASCII上对应的数字细节2:读到文件末尾了,read方法返回-1。3.释放资源细节:每次使用完流之后都要释放资源*///1.创建对象FileInputStream fis = new FileInputStream("myio\\b.txt");//2.读取数据int b1 = fis.read();System.out.println((char)b1);//3.释放资源fis.close();}
}

字节输入流循环读取

public class ByteStreamDemo3 {public static void main(String[] args) throws IOException {/*字节输入流循环读取*///1.创建对象FileInputStream fis = new FileInputStream("myio\\a.txt");//2.循环读取int b;while ((b = fis.read()) != -1) {System.out.println((char) b);}//3.释放资源fis.close();/* *//*** read :表示读取数据,而且是读取一个数据就移动一次指针** *//*FileInputStream fis = new FileInputStream("myio\\a.txt");//2.循环读取while ((fis.read()) != -1) {System.out.println(fis.read());//98  100  -1}//3.释放资源fis.close();*/}
}

文件拷贝基本代码

public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {/**   练习:*       文件拷贝*       把D:\movie.mp4拷贝到当前模块下。**   注意:*       选择一个比较小的文件,不要太大。****   课堂练习:*       要求统计一下拷贝时间,单位毫秒* */long start = System.currentTimeMillis();//1.创建对象FileInputStream fis = new FileInputStream("D:\\itheima\\movie.mp4");FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");//2.拷贝//核心思想:边读边写int b;while((b = fis.read()) != -1){fos.write(b);}//3.释放资源//规则:先开的最后关闭fos.close();fis.close();long end = System.currentTimeMillis();System.out.println(end - start);}
}

文件拷贝弊端和解决方案

将数据读到字节数组byte[]中,将byte[]转成字符串一定要带着后面的0,len两个参数。

public class ByteStreamDemo5 {public static void main(String[] args) throws IOException {/*public int read(byte[] buffer)      一次读一个字节数组数据*///1.创建对象FileInputStream fis = new FileInputStream("myio\\a.txt");//2.读取数据byte[] bytes = new byte[2];//一次读取多个字节数据,具体读多少,跟数组的长度有关//返回值:本次读取到了多少个字节数据int len1 = fis.read(bytes);System.out.println(len1);//2String str1 = new String(bytes,0,len1);System.out.println(str1);int len2 = fis.read(bytes);System.out.println(len2);//2String str2 = new String(bytes,0,len2);System.out.println(str2);int len3 = fis.read(bytes);System.out.println(len3);// 1String str3 = new String(bytes,0,len3);System.out.println(str3);// ed//3.释放资源fis.close();}
}

文件拷贝改写

public class ByteStreamDemo6 {public static void main(String[] args) throws IOException {/**   练习:*       文件拷贝*       把D:\movie.mp4 (16.8 MB) 拷贝到当前模块下。** */long start = System.currentTimeMillis();//1.创建对象FileInputStream fis = new FileInputStream("D:\\movie.mp4");FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");//2.拷贝int len;byte[] bytes = new byte[1024 * 1024 * 5];while((len = fis.read(bytes)) != -1){fos.write(bytes,0,len);}//3.释放资源fos.close();fis.close();long end = System.currentTimeMillis();System.out.println(end - start);}
}

I/O流不同版本捕获异常的方式

基本做法

public class ByteStreamDemo7 {public static void main(String[] args) {/***    利用try...catch...finally捕获拷贝文件中代码出现的异常*** *///1.创建对象FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream("D:\\movie.mp4");fos = new FileOutputStream("myio\\copy.mp4");//2.拷贝int len;byte[] bytes = new byte[1024 * 1024 * 5];while((len = fis.read(bytes)) != -1){fos.write(bytes,0,len);}} catch (IOException e) {//e.printStackTrace();} finally {//3.释放资源if(fos != null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}if(fis != null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}

JDK7方案

public class ByteStreamDemo8 {public static void main(String[] args) {/***    JDK7:IO流中捕获异常的写法**      try后面的小括号中写创建对象的代码,*          注意:只有实现了AutoCloseable接口的类,才能在小括号中创建对象。*     try(){**     }catch(){**     }** */try (FileInputStream fis = new FileInputStream("D:\\movie.mp4");FileOutputStream fos = new FileOutputStream("myio\\copy.mp4")) {//2.拷贝int len;byte[] bytes = new byte[1024 * 1024 * 5];while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}} catch (IOException e) {e.printStackTrace();}}
}

JDK9方案

public class ByteStreamDemo9 {public static void main(String[] args) throws FileNotFoundException {/***    JDK9:IO流中捕获异常的写法*** */FileInputStream fis = new FileInputStream("D:\\movie.mp4");FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");try (fis;fos) {//2.拷贝int len;byte[] bytes = new byte[1024 * 1024 * 5];while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}} catch (IOException e) {e.printStackTrace();}}
}

字符集

在计算机中,任何数据都是以二进制的形式来存储
ASCII字符集中,一个英文占一个字节
GBK字符集中,一个英文占一个字节,二进制第一位是0,一个中文占两个字节,二进制高位字节的第一位是1
Unicode字符集的UTF-8编码格式,一个英文占一个字节,二进制第一位是0,一个中文占三个字节,二进制第一位是1。

有乱码的原因

  • 读取数据时未读完整个汉字
  • 编码和解码的方式不统一

如何不产生乱码

  • 不要用字节流读取文本文件
  • 编码解码时用一个码表,同一个编码方式

编码和解码

public class CharSetDemo3 {public static void main(String[] args) throws UnsupportedEncodingException {/*Java中编码的方法public byte[] getBytes()                        使用默认方式进行编码public byte[] getBytes(String charsetName)      使用指定方式进行编码Java中解码的方法String(byte[] bytes)                            使用默认方式进行解码String(byte[] bytes, String charsetName)        使用指定方式进行解码*///1.编码String str = "ai你哟";byte[] bytes1 = str.getBytes();System.out.println(Arrays.toString(bytes1));byte[] bytes2 = str.getBytes("GBK");System.out.println(Arrays.toString(bytes2));//2.解码String str2 = new String(bytes1);System.out.println(str2);String str3 = new String(bytes1,"GBK");System.out.println(str3);}
}

字符输入流

字符流=字节流+字符集
输入流:一次读一个字节,遇到中文时,一个读多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中

使用场景为纯文本文件读写操作

无参read方法讲解

public class CharStreamDemo1 {public static void main(String[] args) throws IOException {/*第一步:创建对象public FileReader(File file)        创建字符输入流关联本地文件public FileReader(String pathname)  创建字符输入流关联本地文件第二步:读取数据public int read()                   读取数据,读到末尾返回-1public int read(char[] buffer)      读取多个数据,读到末尾返回-1第三步:释放资源public void close()                 释放资源/关流*///1.创建对象并关联本地文件FileReader fr = new FileReader("myio\\a.txt");//2.读取数据 read()//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节//read()细节://1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个//2.在读取之后,方法的底层还会进行解码并转成十进制。//  最终把这个十进制作为返回值//  这个十进制的数据也表示在字符集上的数字//  英文:文件里面二进制数据 0110 0001//          read方法进行读取,解码并转成十进制97//  中文:文件里面的二进制数据 11100110 10110001 10001001//          read方法进行读取,解码并转成十进制27721// 我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了int ch;while((ch = fr.read()) != -1){System.out.print((char)ch);}//3.释放资源fr.close();}
}

有参read方法讲解

public class CharStreamDemo2 {public static void main(String[] args) throws IOException {/*第一步:创建对象public FileReader(File file)        创建字符输入流关联本地文件public FileReader(String pathname)  创建字符输入流关联本地文件第二步:读取数据public int read()                   读取数据,读到末尾返回-1public int read(char[] buffer)      读取多个数据,读到末尾返回-1第三步:释放资源public void close()                 释放资源/关流*///1.创建对象FileReader fr = new FileReader("myio\\a.txt");//2.读取数据char[] chars = new char[2];int len;//read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中//空参的read + 强转类型转换while((len = fr.read(chars)) != -1){//把数组中的数据变成字符串再进行打印System.out.print(new String(chars,0,len));}//3.释放资源fr.close();}
}

相关文章:

Java基础——I/O

一、异常 异常是程序中可能出现的问题&#xff0c;它的父类是Exception。异常分为两类&#xff0c;编译时异常、运行时异常。 编译时异常&#xff1a;没有继承RuntimeException的异常&#xff0c;直接继承于Exception。编译阶段就会错误提示。运行时异常&#xff1a;RuntimeE…...

关于@hide的理解

在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler&#xff0c;但是我们不可能调用到它。因为这个方法用hide注释了 /*** return a shared {link Handler} associated with this thread* hide*/NonNullpublic Handler getT…...

使用python加密主机文件几种方法实现

本文主要介绍了使用python加密主机文件几种方法实现&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧数据加密是一种保护数据安全的技术&#xff0c;通过对数据进行编…...

西湖论剑 2023 比赛复现

WEB real_ez_node 在 route/index.js 中&#xff1a; router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…...

微信小程序更换管理员/重置管理员

方式1&#xff1a; 首先进入微信公众平台官网进入并登录后在管理中找到成员管理选项找到管理员点击后方的修改选项需要使用原管理员的微信进行扫码验证扫码后在手机上确认绑定新管理员&#xff0c;注意&#xff1a;如果是个人账号不可以更改成其他人。 方式2&#xff1a;原管…...

企业进存销管理系统

技术&#xff1a;Java、JSP等摘要&#xff1a;随着当今世界计算机技术的飞速发展&#xff0c;计算机在企业管理中应用的普及&#xff0c;利用计算机实现企业进销存管理势在必行。本系统结合公司实际的进销存制度&#xff0c;通过对本公司的供应商、客户、商品、进货、销售、进销…...

C++入门

变量变量创建的语法: 数据类型 变量名 变量初始值;int a 10;cout << a << endl;常量作用:用于记录程序中不可更改的教国C定义常量两种方式1).#define 宏常量:#define 常量名 常量值通常在文件上方定义。表示一个常量2).const 修饰的变量const 数据类型 常量名 常…...

视频知识点(20)- H264码流如何在SPS中获取宽高信息?

《音视频开发》系列-总览 前沿 了解H264视频编码格式的小伙伴都知道,H264编码中存在两个非常重要的参数集。没错,它们就是序列参数集(SPS)和图像参数集(PPS),而且通常情况下,PPS会依赖SPS中的部分参数信息,同时,视频码流的宽高信息也存储在SPS中。那么如何从中获取视…...

鲜花数据集实验结果总结

从read_split_data中得到&#xff1a;训练数据集&#xff0c;验证数据集&#xff0c;训练标签&#xff0c;验证标签。的所有的具体详细路径 数据集位置&#xff1a;https://download.csdn.net/download/guoguozgw/87437634 import os #一种轻量级的数据交换格式&#xff0c; …...

ElasticJob-Lite架构篇 - 认知分布式任务调度ElasticJob-Lite

前言 本文基于 ElasticJob-Lite 3.x 版本展开分析。 如果 Quartz 集群中有多个服务端节点&#xff0c;任务决定在哪个服务端节点上执行的呢&#xff1f; Quartz 采用随机负载&#xff0c;通过 DB 抢占下一个即将触发的 Trigger 绑定的任务的执行权限。 在 Quartz 的基础上&…...

【直击招聘C++】2.6 对象之间的复制

2.6 对象之间的复制一、要点归纳1. 对象之间的复制操作1.1 运算符1.2 拷贝构造函数2. 对象之间的浅复制和深复制2.1 对象的浅复制2.2 对象的深复制二、面试真题解析面试题1面试题2一、要点归纳 1. 对象之间的复制操作 同一个类的对象之间可以进行复制操作&#xff0c;即将一个…...

学了这么久python,不会连自己啥python版本都不知道吧?

人生苦短&#xff0c;我用Python 源码资料电子书:点击此处跳转文末名片获取 查看 Python 版本 我们可以在命令窗口(Windows 使用 winR 调出 cmd 运行框)使用以下命令查看我们使用的 Python 版本&#xff1a; python -V 或 python --version 以上命令执行结果如下&#xff1a; …...

Revive:从间谍软件进化成银行木马

2022 年 6 月&#xff0c;Cleafy 研究人员发现了一个新的安卓银行木马 Revive。之所以选择 Revive 这个名称&#xff0c;是因为恶意软件为防止停止工作启用的一项功能名为 revive。 Revive 属于持续潜伏的那一类恶意软件&#xff0c;因为它是为特定目标开发和定制的。这种类型…...

Python 之 NumPy 简介和创建数组

文章目录一、NumPy 简介1. 为什么要使用 NumPy2. NumPy 数据类型3. NumPy 数组属性4. NumPy 的 ndarray 对象二、numpy.array() 创建数组1. 基础理论2. 基础操作演示3. numpy.array() 参数详解三、numpy.arange() 生成区间数组四、numpy.linspace() 创建等差数列五、numpy.logs…...

与六年测试工程师促膝长谈,他分享的这些让我对软件测试工作有了全新的认知~

不知不觉已经从事软件测试六年了&#xff0c;2016年毕业到进入外包公司外包给微软做软件测试&#xff0c; 到现在加入著名的外企。六年的时间过得真快。长期的测试工作也让我对软件测试有了比较深入的认识。但是我至今还是一个底层的测试人员&#xff0c;我的看法都比较狭隘&am…...

裕太微在科创板上市:市值约186亿元,哈勃科技和小米基金为股东

2月10日&#xff0c;裕太微电子股份有限公司&#xff08;下称“裕太微”&#xff0c;SH:688515&#xff09;在上海证券交易所上市。本次上市&#xff0c;裕太微的发行价为92元/股&#xff0c;发行2000万股&#xff0c;发行市盈率不适用&#xff0c;发行后总股本8000万股。 根据…...

毕业后5年,我终于变成了月薪13000的软件测试工程师

我用了近2个月的时间转行&#xff0c;在今年1月底顺利入职了一家北京的互联网公司&#xff0c;从事的是软件测试的工作。 和大家看到的一样&#xff0c;我求职的时间花费的比较短&#xff0c;求职过程非常顺利&#xff0c;面试了一周就拿到了3家offer&#xff0c;3家offer的薪…...

实践指南|如何在 Jina 中使用 OpenTelemetry 进行应用程序的监控和跟踪

随着软件和云技术的普及&#xff0c;越来越多的企业开始采用微服务架构、容器化、多云部署和持续部署模式&#xff0c;这增加了因系统失败而给运维/ SRE / DevOps 团队带来的压力&#xff0c;从而增加了开发团队和他们之间的摩擦&#xff0c;因为开发团队总是想尽快部署新功能&…...

MySQL 创建数据表

在创建数据库之后&#xff0c;接下来就要在数据库中创建数据表。所谓创建数据表&#xff0c;指的是在已经创建的数据库中建立新表。 创建数据表的过程是规定数据列的属性的过程&#xff0c;同时也是实施数据完整性&#xff08;包括实体完整性、引用完整性和域完整性&#xff09…...

一文详解网络安全事件的防护与响应

网络安全事件的发生&#xff0c;往往意味着一家企业的生产经营活动受到影响&#xff0c;甚至数据资产遭到泄露。日益复杂的威胁形势使现代企业面临更大的网络安全风险。因此&#xff0c;企业必须提前准备好响应网络安全事件的措施&#xff0c;并制定流程清晰、目标明确的事件响…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...