Java中的File类和IO流

File类

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

File的分隔符

import java.io.File;
public class DemoFile {public static void main(String[] args) {/*static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。static char pathSeparatorChar 与系统有关的路径分隔符。static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。static char separatorChar 与系统有关的默认名称分隔符。操作路径:路径不能写死了C:\develop\a\a.txt  windowsC:/develop/a/a.txt  linux"C:"+File.separator+"develop"+File.separator+"a"+File.separator+"a.txt"*/String pathSeparator = File.pathSeparator;System.out.println(pathSeparator);//路径分隔符 windows:分号;  linux:冒号:String separator = File.separator;System.out.println(separator);// 文件名称分隔符 windows:反斜杠\  linux:正斜杠/}}

File类的构造方法

public class DemoFile {public static void main(String[] args) {/*File类的构造方法*///show02("c:\\","a.txt");//c:\a.txt//show02("d:\\","a.txt");//d:\a.txtshow03();File f = new File("C:\\Users\\IdeaProjects\\shungyuan");long length = f.length();System.out.println(length);}/*File(File parent, String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。参数:把路径分成了两部分File parent:父路径String child:子路径好处:父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象*/private static void show03() {File parent = new File("c:\\");File file = new File(parent,"hello.java");System.out.println(file);//c:\hello.java}/*File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。参数:把路径分成了两部分String parent:父路径String child:子路径好处:父路径和子路径,可以单独书写,使用起来非常灵活;父路径和子路径都可以变化*/private static void show02(String parent, String child) {File file = new File(parent,child);System.out.println(file);//c:\a.txt}/*File(String pathname) 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。参数:String pathname:字符串的路径名称路径可以是以文件结尾,也可以是以文件夹结尾路径可以是相对路径,也可以是绝对路径路径可以是存在,也可以是不存在创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况*/private static void show01() {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan\\a.txt");System.out.println(f1);//重写了Object类的toString方法 C:\Users\itcast\IdeaProjects\shungyuan\a.txtFile f2 = new File("C:\\Users\\IdeaProjects\\shungyuan");System.out.println(f2);//C:\Users\IdeaProjects\shungyuanFile f3 = new File("b.txt");System.out.println(f3);//b.txt}
}

File类常用的方法

import java.io.File;/*File类获取功能的方法- public String getAbsolutePath() :返回此File的绝对路径名字符串。- public String getPath() :将此File转换为路径名字符串。- public String getName()  :返回由此File表示的文件或目录的名称。- public long length()  :返回由此File表示的文件的长度。*/
public class DemoFile {public static void main(String[] args) {show04();}/*public long length()  :返回由此File表示的文件的长度。获取的是构造方法指定的文件的大小,以字节为单位注意:文件夹是没有大小概念的,不能获取文件夹的大小如果构造方法中给出的路径不存在,那么length方法返回0*/private static void show04() {File f1 = new File("C:\\develop\\a\\1.jpg");long l1 = f1.length();System.out.println(l1);//780831字节File f2 = new File("C:\\develop\\a\\2.jpg");System.out.println(f2.length());//0File f3 = new File("C:\\develop\\a");System.out.println(f3.length());//0 文件夹没有大小概念的}/*public String getName()  :返回由此File表示的文件或目录的名称。获取的就是构造方法传递路径的结尾部分(文件/文件夹)*/private static void show03() {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan\\a.txt");String name1 = f1.getName();System.out.println(name1);//a.txtFile f2 = new File("C:\\Users\\IdeaProjects\\shungyuan");String name2 = f2.getName();System.out.println(name2);//shungyuan}/*public String getPath() :将此File转换为路径名字符串。获取的构造方法中传递的路径toString方法调用的就是getPath方法源码:public String toString() {return getPath();}*/private static void show02() {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan\\a.txt");File f2 = new File("a.txt");String path1 = f1.getPath();System.out.println(path1);//C:\Users\IdeaProjects\shungyuan\a.txtString path2 = f2.getPath();System.out.println(path2);//a.txtSystem.out.println(f1);//C:\Users\IdeaProjects\shungyuan\a.txtSystem.out.println(f1.toString());//C:\Users\IdeaProjects\shungyuan\a.txt}/*public String getAbsolutePath() :返回此File的绝对路径名字符串。获取的构造方法中传递的路径无论路径是绝对的还是相对的,getAbsolutePath方法返回的都是绝对路径*/private static void show01() {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan\\a.txt");String absolutePath1 = f1.getAbsolutePath();System.out.println(absolutePath1);//C:\Users\IdeaProjects\shungyuan\a.txtFile f2 = new File("a.txt");String absolutePath2 = f2.getAbsolutePath();System.out.println(absolutePath2);//C:\Users\IdeaProjects\shungyuan\a.txt}
}

File类判断功能的方法

import java.io.File;/*File类判断功能的方法- public boolean exists() :此File表示的文件或目录是否实际存在。- public boolean isDirectory() :此File表示的是否为目录。- public boolean isFile() :此File表示的是否为文件。*/
public class DemoFile {public static void main(String[] args) {show02();}/*public boolean isDirectory() :此File表示的是否为目录。用于判断构造方法中给定的路径是否以文件夹结尾是:true否:falsepublic boolean isFile() :此File表示的是否为文件。用于判断构造方法中给定的路径是否以文件结尾是:true否:false注意:电脑的硬盘中只有文件/文件夹,两个方法是互斥这两个方法使用前提,路径必须是存在的,否则都返回false*/private static void show02() {File f1 = new File("C:\\Users\\IdeaProjects\\shung");//不存在,就没有必要获取if(f1.exists()){System.out.println(f1.isDirectory());System.out.println(f1.isFile());}File f2 = new File("C:\\Users\\IdeaProjects\\shungyuan");if(f2.exists()){System.out.println(f2.isDirectory());//trueSystem.out.println(f2.isFile());//false}File f3 = new File("C:\\Users\\IdeaProjects\\shungyuan\\shungyuan.iml");if(f3.exists()){System.out.println(f3.isDirectory());//falseSystem.out.println(f3.isFile());//true}}/*public boolean exists() :此File表示的文件或目录是否实际存在。用于判断构造方法中的路径是否存在存在:true不存在:false*/private static void show01() {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan");System.out.println(f1.exists());//trueFile f2 = new File("C:\\Users\\IdeaProjects\\shung");System.out.println(f2.exists());//falseFile f3 = new File("shungyuan.iml");//相对路径 C:\Users\IdeaProjects\shungyuan\shungyuan.imlSystem.out.println(f3.exists());//trueFile f4 = new File("a.txt");System.out.println(f4.exists());//false}
}

File类创建删除功能的方法

import java.io.File;
import java.io.IOException;/*File类创建删除功能的方法- public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。- public boolean delete() :删除由此File表示的文件或目录。- public boolean mkdir() :创建由此File表示的目录。- public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。*/
public class DemoFile {public static void main(String[] args) throws IOException {show03();}/*public boolean delete() :删除由此File表示的文件或目录。此方法,可以删除构造方法路径中给出的文件/文件夹返回值:布尔值true:文件/文件夹删除成功,返回truefalse:文件夹中有内容,不会删除返回false;构造方法中路径不存在false注意:delete方法是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎*/private static void show03() {File f1 = new File("08_FileAndRecursion\\新建文件夹");boolean b1 = f1.delete();System.out.println("b1:"+b1);File f2 = new File("08_FileAndRecursion\\abc.txt");System.out.println(f2.delete());}/*public boolean mkdir() :创建单级空文件夹public boolean mkdirs() :既可以创建单级空文件夹,也可以创建多级文件夹创建文件夹的路径和名称在构造方法中给出(构造方法的参数)返回值:布尔值true:文件夹不存在,创建文件夹,返回truefalse:文件夹存在,不会创建,返回false;构造方法中给出的路径不存在返回false注意:1.此方法只能创建文件夹,不能创建文件*/private static void show02() {File f1 = new File("08_FileAndRecursion\\aaa");boolean b1 = f1.mkdir();System.out.println("b1:"+b1);File f2 = new File("08_FileAndRecursion\\111\\222\\333\\444");boolean b2 = f2.mkdirs();System.out.println("b2:"+b2);File f3 = new File("08_FileAndRecursion\\abc.txt");boolean b3 = f3.mkdirs();//看类型,是一个文件System.out.println("b3:"+b3);File f4 = new File("08_F\\ccc");boolean b4 = f4.mkdirs();//不会抛出异常,路径不存在,不会创建System.out.println("b4:"+b4);}/*public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。创建文件的路径和名称在构造方法中给出(构造方法的参数)返回值:布尔值true:文件不存在,创建文件,返回truefalse:文件存在,不会创建,返回false注意:1.此方法只能创建文件,不能创建文件夹2.创建文件的路径必须存在,否则会抛出异常public boolean createNewFile() throws IOExceptioncreateNewFile声明抛出了IOException,我们调用这个方法,就必须的处理这个异常,要么throws,要么trycatch*/private static void show01() throws IOException {File f1 = new File("C:\\Users\\IdeaProjects\\shungyuan\\08_FileAndRecursion\\1.txt");boolean b1 = f1.createNewFile();System.out.println("b1:"+b1);File f2 = new File("08_FileAndRecursion\\2.txt");System.out.println(f2.createNewFile());File f3 = new File("08_FileAndRecursion\\新建文件夹");System.out.println(f3.createNewFile());//不要被名称迷糊,要看类型File f4 = new File("08_FileAndRecursi\\3.txt");System.out.println(f4.createNewFile());//路径不存在,抛出IOException}
}

File类遍历(文件夹)目录功能

import java.io.File;/*File类遍历(文件夹)目录功能- public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。- public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。注意:list方法和listFiles方法遍历的是构造方法中给出的目录如果构造方法中给出的目录的路径不存在,会抛出空指针异常如果构造方法中给出的路径不是一个目录,也会抛出空指针异常*/
public class DemoFile {public static void main(String[] args) {show02();}/*public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。遍历构造方法中给出的目录,会获取目录中所有的文件/文件夹,把文件/文件夹封装为File对象,多个File对象存储到File数组中*/private static void show02() {File file = new File("C:\\Users\\IdeaProjects\\shungyuan\\08_FileAndRecursion");File[] files = file.listFiles();for (File f : files) {System.out.println(f);}}/*public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称存储到一个String类型的数组中*/private static void show01() {//File file = new File("C:\\Users\\IdeaProjects\\shungyuan\\08_FileAndRecursion\\1.txt");//NullPointerException//File file = new File("C:\\Users\\IdeaProjects\\shungyuan\\08_Fi");//NullPointerExceptionFile file = new File("C:\\Users\\IdeaProjects\\shungyuan\\08_FileAndRecursion");String[] arr = file.list();for (String fileName : arr) {System.out.println(fileName);}}
}

IO概述

生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了 ctrl+s ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为 输入input 和 输出output ,即流向内存是输入流,流出内存的输出流。
Java中I/O操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据

IO的分类
根据数据的流向分为:输入流和输出流。
输入流 :把数据从 其他设备 上读取到 内存 中的流。
输出流 :把数据从 内存 中写出到 其他设备 上的流。

格局数据的类型分为:字节流和字符流。
字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流。

OutputStream:字节输出流

import java.io.FileOutputStream;
import java.io.IOException;/*java.io.OutputStream:字节输出流此抽象类是表示输出字节流的所有类的超类。定义了一些子类共性的成员方法:- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。- public abstract void write(int b) :将指定的字节输出流。java.io.FileOutputStream extends OutputStreamFileOutputStream:文件字节输出流作用:把内存中的数据写入到硬盘的文件中构造方法:FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。参数:写入数据的目的String name:目的地是一个文件的路径File file:目的地是一个文件构造方法的作用:1.创建一个FileOutputStream对象2.会根据构造方法中传递的文件/文件路径,创建一个空的文件3.会把FileOutputStream对象指向创建好的文件写入数据的原理(内存-->硬盘)java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中*/
public class DemoOutputStream {public static void main(String[] args) throws IOException {//1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地FileOutputStream fos = new FileOutputStream("09_IOAndProperties\\a.txt");//2.调用FileOutputStream对象中的方法write,把数据写入到文件中//public abstract void write(int b) :将指定的字节输出流。fos.write(97);//3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)//fos.close();}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;/*一次写多个字节的方法:- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。*/
public class DemoOutputStream {public static void main(String[] args) throws IOException {//创建FileOutputStream对象,构造方法中绑定要写入数据的目的地FileOutputStream fos = new FileOutputStream(new File("09_IOAndProperties\\b.txt"));//调用FileOutputStream对象中的方法write,把数据写入到文件中//在文件中显示100,写个字节fos.write(49);fos.write(48);fos.write(48);/*public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。一次写多个字节:如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)*/byte[] bytes = {65,66,67,68,69};//ABCDE//byte[] bytes = {-65,-66,-67,68,69};//烤紻Efos.write(bytes);/*public void write(byte[] b, int off, int len) :把字节数组的一部分写入到文件中int off:数组的开始索引int len:写几个字节*/fos.write(bytes,1,2);//BC/*写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组byte[] getBytes()  把字符串转换为字节数组*/byte[] bytes2 = "你好".getBytes();System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67]fos.write(bytes2);//释放资源fos.close();}
}
import java.io.FileOutputStream;
import java.io.IOException;/*追加写/续写:使用两个参数的构造方法FileOutputStream(String name, boolean append)创建一个向具有指定 name 的文件中写入数据的输出文件流。FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。参数:String name,File file:写入数据的目的地boolean append:追加写开关true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据false:创建一个新文件,覆盖源文件写换行:写换行符号windows:\r\nlinux:/nmac:/r*/
public class DemoOutputStream {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("09_IOAndProperties\\c.txt",true);for (int i = 1; i <=10 ; i++) {fos.write("你好".getBytes());fos.write("\r\n".getBytes());}fos.close();}

InputStream:字节输入流

import java.io.FileInputStream;
import java.io.IOException;/*java.io.InputStream:字节输入流此抽象类是表示字节输入流的所有类的超类。定义了所有子类共性的方法:int read()从输入流中读取数据的下一个字节。int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。void close() 关闭此输入流并释放与该流关联的所有系统资源。java.io.FileInputStream extends InputStreamFileInputStream:文件字节输入流作用:把硬盘文件中的数据,读取到内存中使用构造方法:FileInputStream(String name)FileInputStream(File file)参数:读取文件的数据源String name:文件的路径File file:文件构造方法的作用:1.会创建一个FileInputStream对象2.会把FileInputStream对象指定构造方法中要读取的文件读取数据的原理(硬盘-->内存)java程序-->JVM-->OS-->OS读取数据的方法-->读取文件*/
public class DemoInputStream {public static void main(String[] args) throws IOException {//1.创建FileInputStream对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("09_IOAndProperties\\c.txt");//2.使用FileInputStream对象中的方法read,读取文件//int read()读取文件中的一个字节并返回,读取到文件的末尾返回-1/*int len = fis.read();System.out.println(len);//97 alen = fis.read();System.out.println(len);// 98 blen = fis.read();System.out.println(len);//99 clen = fis.read();System.out.println(len);//-1len = fis.read();System.out.println(len);//-1*//*发现以上读取文件是一个重复的过程,所以可以使用循环优化不知道文件中有多少字节,使用while循环while循环结束条件,读取到-1的时候结束布尔表达式(len = fis.read())!=-11.fis.read():读取一个字节2.len = fis.read():把读取到的字节赋值给变量len3.(len = fis.read())!=-1:判断变量len是否不等于-1*/int len = 0; //记录读取到的字节while((len = fis.read())!=-1){System.out.print(len);//abc}//3.释放资源fis.close();}
}
import java.io.FileInputStream;
import java.io.IOException;/*字节输入流一次读取多个字节的方法:int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。明确两件事情:1.方法的参数byte[]的作用?起到缓冲作用,存储每次读取到的多个字节数组的长度一把定义为1024(1kb)或者1024的整数倍2.方法的返回值int是什么?每次读取的有效字节个数String类的构造方法String(byte[] bytes) :把字节数组转换为字符串String(byte[] bytes, int offset, int length) 把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数*/
public class DemoInputStream {public static void main(String[] args) throws IOException {//创建FileInputStream对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("09_IOAndProperties\\b.txt");//使用FileInputStream对象中的方法read读取文件//int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。/*byte[] bytes = new byte[2];int len = fis.read(bytes);System.out.println(len);//2//System.out.println(Arrays.toString(bytes));//[65, 66]System.out.println(new String(bytes));//ABlen = fis.read(bytes);System.out.println(len);//2System.out.println(new String(bytes));//CDlen = fis.read(bytes);System.out.println(len);//1System.out.println(new String(bytes));//EDlen = fis.read(bytes);System.out.println(len);//-1System.out.println(new String(bytes));//ED*//*发现以上读取时一个重复的过程,可以使用循环优化不知道文件中有多少字节,所以使用while循环while循环结束的条件,读取到-1结束*/byte[] bytes = new byte[1024];//存储读取到的多个字节int len = 0; //记录每次读取的有效字节个数while((len = fis.read(bytes))!=-1){//String(byte[] bytes, int offset, int length) 把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数System.out.println(new String(bytes,0,len));}//释放资源fis.close();}
}

创建一个读写的流(案例)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*文件复制练习:一读一写明确:数据源: c:\\1.jpg数据的目的地: d:\\1.jpg文件复制的步骤:1.创建一个字节输入流对象,构造方法中绑定要读取的数据源2.创建一个字节输出流对象,构造方法中绑定要写入的目的地3.使用字节输入流对象中的方法read读取文件4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中5.释放资源*/
public class DemoCopyFile {public static void main(String[] args) throws IOException {long s = System.currentTimeMillis();//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("c:\\1.jpg");//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地FileOutputStream fos = new FileOutputStream("d:\\1.jpg");//一次读取一个字节写入一个字节的方式//3.使用字节输入流对象中的方法read读取文件/*int len = 0;while((len = fis.read())!=-1){//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中fos.write(len);}*///使用数组缓冲读取多个字节,写入多个字节byte[] bytes = new byte[1024];//3.使用字节输入流对象中的方法read读取文件int len = 0;//每次读取的有效字节个数while((len = fis.read(bytes))!=-1){//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中fos.write(bytes,0,len);}//5.释放资源(先关写的,后关闭读的;如果写完了,肯定读取完毕了)fos.close();fis.close();long e = System.currentTimeMillis();System.out.println("复制文件共耗时:"+(e-s)+"毫秒");}}

Reader:字符输入流

import java.io.FileReader;
import java.io.IOException;/*java.io.Reader:字符输入流,是字符输入流的最顶层的父类,定义了一些共性的成员方法,是一个抽象类共性的成员方法:int read() 读取单个字符并返回。int read(char[] cbuf)一次读取多个字符,将字符读入数组。void close() 关闭该流并释放与之关联的所有资源。java.io.FileReader extends InputStreamReader extends ReaderFileReader:文件字符输入流作用:把硬盘文件中的数据以字符的方式读取到内存中构造方法:FileReader(String fileName)FileReader(File file)参数:读取文件的数据源String fileName:文件的路径File file:一个文件FileReader构造方法的作用:1.创建一个FileReader对象2.会把FileReader对象指向要读取的文件*/
public class DemoReader {public static void main(String[] args) throws IOException {//1.创建FileReader对象,构造方法中绑定要读取的数据源FileReader fr = new FileReader("09_IOAndProperties\\c.txt");//2.使用FileReader对象中的方法read读取文件//int read() 读取单个字符并返回。/*int len = 0;while((len = fr.read())!=-1){System.out.print((char)len);}*///int read(char[] cbuf)一次读取多个字符,将字符读入数组。char[] cs = new char[1024];//存储读取到的多个字符int len = 0;//记录的是每次读取的有效字符个数while((len = fr.read(cs))!=-1){/*String类的构造方法String(char[] value) 把字符数组转换为字符串String(char[] value, int offset, int count) 把字符数组的一部分转换为字符串 offset数组的开始索引 count转换的个数*/System.out.println(new String(cs,0,len));}//3.释放资源fr.close();}
}

Writer:字符输出流

import java.io.FileWriter;
import java.io.IOException;/*java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类共性的成员方法:- void write(int c) 写入单个字符。- void write(char[] cbuf)写入字符数组。- abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。- void write(String str)写入字符串。- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。- void flush()刷新该流的缓冲。- void close() 关闭此流,但要先刷新它。java.io.FileWriter extends OutputStreamWriter extends WriterFileWriter:文件字符输出流作用:把内存中字符数据写入到文件中构造方法:FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象。FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。参数:写入数据的目的地String fileName:文件的路径File file:是一个文件构造方法的作用:1.会创建一个FileWriter对象2.会根据构造方法中传递的文件/文件的路径,创建文件3.会把FileWriter对象指向创建好的文件*/
public class DemoWriter {public static void main(String[] args) throws IOException {//1.创建FileWriter对象,构造方法中绑定要写入数据的目的地FileWriter fw = new FileWriter("09_IOAndProperties\\d.txt");//2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)//void write(int c) 写入单个字符。fw.write(97);//3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中//fw.flush();//4.释放资源(会先把内存缓冲区中的数据刷新到文件中)fw.close();}
}

flush方法和close方法

import java.io.FileWriter;
import java.io.IOException;/*flush方法和close方法的区别- flush :刷新缓冲区,流对象可以继续使用。- close:  先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。*/
public class DemoCloseAndFlush {public static void main(String[] args) throws IOException {//1.创建FileWriter对象,构造方法中绑定要写入数据的目的地FileWriter fw = new FileWriter("09_IOAndProperties\\e.txt");//2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)//void write(int c) 写入单个字符。fw.write(97);//3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中fw.flush();//刷新之后流可以继续使用fw.write(98);//4.释放资源(会先把内存缓冲区中的数据刷新到文件中)fw.close();//close方法之后流已经关闭了,已经从内存中消失了,流就不能再使用了fw.write(99);//IOException: Stream closed}
}

字符输出流的其他方法

import java.io.FileWriter;
import java.io.IOException;/*字符输出流写数据的其他方法- void write(char[] cbuf)写入字符数组。- abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。- void write(String str)写入字符串。- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。*/
public class DemoWriter {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("09_IOAndProperties\\f.txt");char[] cs = {'a','b','c','d','e'};//void write(char[] cbuf)写入字符数组。fw.write(cs);//abcde//void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。fw.write(cs,1,3);//bcd//void write(String str)写入字符串。fw.write("我是程序员");//我是程序员//void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。fw.write("程序员小白",2,3);//程序员小白fw.close();}
}
import java.io.FileWriter;
import java.io.IOException;/*续写和换行续写,追加写:使用两个参数的构造方法FileWriter(String fileName, boolean append)FileWriter(File file, boolean append)参数:String fileName,File file:写入数据的目的地boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写; false:创建新的文件覆盖源文件换行:换行符号windows:\r\nlinux:/nmac:/r*/
public class DemoWriter {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("09_IOAndProperties\\g.txt",true);for (int i = 0; i <10 ; i++) {fw.write("HelloWorld"+i+"\r\n");}fw.close();}
}

处理流中的异常

import java.io.FileWriter;
import java.io.IOException;/*在jdk1.7之前使用try catch finally 处理流中的异常*/
public class DemoTryCatch {public static void main(String[] args) {//提高变量fw的作用域,让finally可以使用//变量在定义的时候,可以没有值,但是使用的时候必须有值//fw = new FileWriter("09_IOAndProperties\\g.txt",true); 执行失败,fw没有值,fw.close会报错FileWriter fw = null;try{//可能会产出异常的代码fw = new FileWriter("w:\\09_IOAndProperties\\g.txt",true);for (int i = 0; i <10 ; i++) {fw.write("HelloWorld"+i+"\r\n");}}catch(IOException e){//异常的处理逻辑System.out.println(e);}finally {//一定会指定的代码//创建对象失败了,fw的默认值就是null,null是不能调用方法的,会抛出NullPointerException,需要增加一个判断,不是null在把资源释放if(fw!=null){try {//fw.close方法声明抛出了IOException异常对象,所以我们就的处理这个异常对象,要么throws,要么try catchfw.close();} catch (IOException e) {e.printStackTrace();}}}}
}

处理流中的异常-JDK7的新特性

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*JDK7的新特性在try的后边可以增加一个(),在括号中可以定义流对象那么这个流对象的作用域就在try中有效try中的代码执行完毕,会自动把流对象释放,不用写finally格式:try(定义流对象;定义流对象....){可能会产出异常的代码}catch(异常类变量 变量名){异常的处理逻辑}*/
public class DemoJDK7 {public static void main(String[] args) {try(//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("c:\\1.jpg");//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地FileOutputStream fos = new FileOutputStream("d:\\1.jpg");){//可能会产出异常的代码//一次读取一个字节写入一个字节的方式//3.使用字节输入流对象中的方法read读取文件int len = 0;while((len = fis.read())!=-1){//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中fos.write(len);}}catch (IOException e){//异常的处理逻辑System.out.println(e);}}
}

处理流中的异常-JDK9的新特性

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*JDK9新特性try的前边可以定义流对象在try后边的()中可以直接引入流对象的名称(变量名)在try代码执行完毕之后,流对象也可以释放掉,不用写finally格式:A a = new A();B b = new B();try(a,b){可能会产出异常的代码}catch(异常类变量 变量名){异常的处理逻辑}*/
public class DemoJDK9 {public static void main(String[] args) throws IOException {//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("c:\\1.jpg");//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地FileOutputStream fos = new FileOutputStream("d:\\1.jpg");try(fis;fos){//一次读取一个字节写入一个字节的方式//3.使用字节输入流对象中的方法read读取文件int len = 0;while((len = fis.read())!=-1){//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中fos.write(len);}}catch (IOException e){System.out.println(e);}//fos.write(1);//Stream Closed}
}

Properties集合

import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;/*java.util.Properties集合 extends Hashtable<k,v> implements Map<k,v>Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。Properties集合是一个唯一和IO流相结合的集合可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用属性列表中每个键及其对应值都是一个字符串。Properties集合是一个双列集合,key和value默认都是字符串*/
public class DemoProperties {public static void main(String[] args) throws IOException {show03();}/*可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用void load(InputStream inStream)void load(Reader reader)参数:InputStream inStream:字节输入流,不能读取含有中文的键值对Reader reader:字符输入流,能读取含有中文的键值对注意:1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取3.存储键值对的文件中,键与值默认都是字符串,不用再加引号*/private static void show03() throws IOException {//1.创建Properties集合对象Properties prop = new Properties();//2.使用Properties集合对象中的方法load读取保存键值对的文件prop.load(new FileReader("09_IOAndProperties\\prop.txt"));//prop.load(new FileInputStream("09_IOAndProperties\\prop.txt"));//3.遍历Properties集合Set<String> set = prop.stringPropertyNames();for (String key : set) {String value = prop.getProperty(key);System.out.println(key+"="+value);}}/*可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储void store(OutputStream out, String comments)void store(Writer writer, String comments)参数:OutputStream out:字节输出流,不能写入中文Writer writer:字符输出流,可以写中文String comments:注释,用来解释说明保存的文件是做什么用的不能使用中文,会产生乱码,默认是Unicode编码一般使用""空字符串*/private static void show02() throws IOException {//1.创建Properties集合对象,添加数据Properties prop = new Properties();prop.setProperty("张三","168");prop.setProperty("李四","165");prop.setProperty("王二","160");//2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地//FileWriter fw = new FileWriter("09_IOAndProperties\\prop.txt");//3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储//prop.store(fw,"save data");//4.释放资源//fw.close();prop.store(new FileOutputStream("09_IOAndProperties\\prop2.txt"),"");}/*使用Properties集合存储数据,遍历取出Properties集合中的数据Properties集合是一个双列集合,key和value默认都是字符串Properties集合有一些操作字符串的特有方法Object setProperty(String key, String value) 调用 Hashtable 的方法 put。String getProperty(String key) 通过key找到value值,此方法相当于Map集合中的get(key)方法Set<String> stringPropertyNames() 返回此属性列表中的键集,其中该键及其对应值是字符串,此方法相当于Map集合中的keySet方法*/private static void show01() {//创建Properties集合对象Properties prop = new Properties();//使用setProperty往集合中添加数据prop.setProperty("张三","168");prop.setProperty("李四","165");prop.setProperty("王二","160");//prop.put(1,true);//使用stringPropertyNames把Properties集合中的键取出,存储到一个Set集合中Set<String> set = prop.stringPropertyNames();//遍历Set集合,取出Properties集合的每一个键for (String key : set) {//使用getProperty方法通过key获取valueString value = prop.getProperty(key);System.out.println(key+"="+value);}}
}

缓冲流

缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

BufferedOutputStream:字节缓冲输出流

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;/*java.io.BufferedOutputStream extends OutputStreamBufferedOutputStream:字节缓冲输出流继承自父类的共性成员方法:- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。- public abstract void write(int b) :将指定的字节输出流。构造方法:BufferedOutputStream(OutputStream out)  创建一个新的缓冲输出流,以将数据写入指定的底层输出流。BufferedOutputStream(OutputStream out, int size)  创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。参数:OutputStream out:字节输出流我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率int size:指定缓冲流内部缓冲区的大小,不指定默认*/
public class DemoBufferedOutputStream {public static void main(String[] args) throws IOException {//1.创建FileOutputStream对象,构造方法中绑定要输出的目的地FileOutputStream fos = new FileOutputStream("10_IO\\a.txt");//2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率BufferedOutputStream bos = new BufferedOutputStream(fos);//3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中bos.write("我把数据写入到内部缓冲区中".getBytes());//4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中bos.flush();//5.释放资源(会先调用flush方法刷新数据,第4部可以省略)bos.close();}}

BufferedInputStream:字节缓冲输入流

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;/*java.io.BufferedInputStream extends InputStreamBufferedInputStream:字节缓冲输入流继承自父类的成员方法:int read()从输入流中读取数据的下一个字节。int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。void close() 关闭此输入流并释放与该流关联的所有系统资源。构造方法:BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。参数:InputStream in:字节输入流我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率int size:指定缓冲流内部缓冲区的大小,不指定默认*/public class DemoBufferedInputStream {public static void main(String[] args) throws IOException {//1.创建FileInputStream对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("10_IO\\a.txt");//2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率BufferedInputStream bis = new BufferedInputStream(fis);//3.使用BufferedInputStream对象中的方法read,读取文件//int read()从输入流中读取数据的下一个字节。/*int len = 0;//记录每次读取到的字节while((len = bis.read())!=-1){System.out.println(len);}*///int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。byte[] bytes =new byte[1024];//存储每次读取的数据int len = 0; //记录每次读取的有效字节个数while((len = bis.read(bytes))!=-1){System.out.println(new String(bytes,0,len));}//4.释放资源bis.close();}
}

BufferedWriter:字符缓冲输出流

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;/*java.io.BufferedWriter extends WriterBufferedWriter:字符缓冲输出流继承自父类的共性成员方法:- void write(int c) 写入单个字符。- void write(char[] cbuf)写入字符数组。- abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。- void write(String str)写入字符串。- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。- void flush()刷新该流的缓冲。- void close() 关闭此流,但要先刷新它。构造方法:BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。参数:Writer out:字符输出流我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率int sz:指定缓冲区的大小,不写默认大小特有的成员方法:void newLine() 写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符换行:换行符号windows:\r\nlinux:/nmac:/r*/
public class DemoBufferedWriter {public static void main(String[] args) throws IOException {//System.out.println();//1.创建字符缓冲输出流对象,构造方法中传递字符输出流BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\c.txt"));//2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中for (int i = 0; i <10 ; i++) {bw.write("我是程序员");//bw.write("\r\n");bw.newLine();}//3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中bw.flush();//4.释放资源bw.close();}
}

BufferedReader:字符缓冲输入流

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;/*java.io.BufferedReader extends ReaderBufferedReader:字符缓冲输入流继承自父类的共性成员方法:int read() 读取单个字符并返回。int read(char[] cbuf)一次读取多个字符,将字符读入数组。void close() 关闭该流并释放与之关联的所有资源。构造方法:BufferedReader(Reader in)  创建一个使用默认大小输入缓冲区的缓冲字符输入流。BufferedReader(Reader in, int sz)     创建一个使用指定大小输入缓冲区的缓冲字符输入流。参数:Reader in:字符输入流我们可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高FileReader的读取效率特有的成员方法:String readLine() 读取一个文本行。读取一行数据行的终止符号:通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。返回值:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null*/
public class DemoBufferedReader {public static void main(String[] args) throws IOException {//1.创建字符缓冲输入流对象,构造方法中传递字符输入流BufferedReader br = new BufferedReader(new FileReader("10_IO\\c.txt"));//2.使用字符缓冲输入流对象中的方法read/readLine读取文本/*String line = br.readLine();System.out.println(line);line = br.readLine();System.out.println(line);line = br.readLine();System.out.println(line);line = br.readLine();System.out.println(line);*//*发下以上读取是一个重复的过程,所以可以使用循环优化不知道文件中有多少行数据,所以使用while循环while的结束条件,读取到null结束*/String line;while((line = br.readLine())!=null){System.out.println(line);}//3.释放资源br.close();}
}

读写文件升级(案例)

import java.io.*;/*文件复制练习:一读一写明确:数据源: c:\\1.jpg数据的目的地: d:\\1.jpg文件的大小:780,831 字节一次读写一个字节:32毫秒使用数组缓冲读取多个字节,写入多个字节:5毫秒*/
public class DemoCopyFile {public static void main(String[] args) throws IOException {long s = System.currentTimeMillis();//1.创建字节缓冲输入流对象,构造方法中传递字节输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\1.jpg"));//2.创建字节缓冲输出流对象,构造方法中传递字节输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\1.jpg"));//3.使用字节缓冲输入流对象中的方法read,读取文件//一次读取一个字节写入一个字节的方式/*int len = 0;while((len = bis.read())!=-1){bos.write(len);}*///使用数组缓冲读取多个字节,写入多个字节byte[] bytes = new byte[1024];int len = 0;while((len = bis.read(bytes))!=-1){bos.write(bytes,0,len);}bos.close();bis.close();long e = System.currentTimeMillis();System.out.println("复制文件共耗时:"+(e-s)+"毫秒");}
}

转换流

字符编码和字符集

字符编码
计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本f符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。
字符编码 Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则。
字符集 Charset :也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。

ASCII字符集 :
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。

ISO-8859-1字符集:
拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。ISO-5559-1使用单字节编码,兼容ASCII编码。

GBxxx字符集:
GB就是国标的意思,是为了显示中文而设计的一套字符集GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。
GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。

Unicode字符集 :
Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。UTF-8编码,可以用来表Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:
1 128个US-ASCII字符,只需一个字节编码。
2. 拉丁文等字符,需要二个字节编码。
3. 大部分常用字(含中文),使用三个字节编码。
4. 其他极少使用的Unicode辅助字符,使用四字节编码

/*FileReader可以读取IDE默认编码格式(UTF-8)的文件FileReader读取系统默认编码(中文GBK)会产生乱码���*/
public class DemoFileReader {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("10_IO\\我是GBK格式的文本.txt");int len = 0;while((len = fr.read())!=-1){System.out.print((char)len);}fr.close();}
}

InputStreamReader类

转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*java.io.InputStreamReader extends ReaderInputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)继承自父类的共性成员方法:int read() 读取单个字符并返回。int read(char[] cbuf)一次读取多个字符,将字符读入数组。void close() 关闭该流并释放与之关联的所有资源。构造方法:InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。参数:InputStream in:字节输入流,用来读取文件中保存的字节String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8注意事项:构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码*/
public class DemoInputStreamReader {public static void main(String[] args) throws IOException {//read_utf_8();read_gbk();}/*使用InputStreamReader读取GBK格式的文件*/private static void read_gbk() throws IOException {//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称//InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"UTF-8");//???InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"GBK");//你好//2.使用InputStreamReader对象中的方法read读取文件int len = 0;while((len = isr.read())!=-1){System.out.println((char)len);}//3.释放资源isr.close();}/*使用InputStreamReader读取UTF-8格式的文件*/private static void read_utf_8() throws IOException {//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称//InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"),"UTF-8");InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8//2.使用InputStreamReader对象中的方法read读取文件int len = 0;while((len = isr.read())!=-1){System.out.println((char)len);}//3.释放资源isr.close();}
}

OutputStreamWriter类

转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;/*java.io.OutputStreamWriter extends WriterOutputStreamWriter: 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)继续自父类的共性成员方法:- void write(int c) 写入单个字符。- void write(char[] cbuf)写入字符数组。- abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。- void write(String str)写入字符串。- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。- void flush()刷新该流的缓冲。- void close() 关闭此流,但要先刷新它。构造方法:OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。参数:OutputStream out:字节输出流,可以用来写转换之后的字节到文件中String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8*/
public class DemoOutputStreamWriter {public static void main(String[] args) throws IOException {//write_utf_8();write_gbk();}/*使用转换流OutputStreamWriter写GBK格式的文件*/private static void write_gbk() throws IOException {//1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\gbk.txt"),"GBK");//2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)osw.write("你好");//3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)osw.flush();//4.释放资源osw.close();}/*使用转换流OutputStreamWriter写UTF-8格式的文件*/private static void write_utf_8() throws IOException {//1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"),"utf-8");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8//2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)osw.write("你好");//3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)osw.flush();//4.释放资源osw.close();}
}
import java.io.*;/*练习:转换文件编码将GBK编码的文本文件,转换为UTF-8编码的文本文件。*/
public class Demo04Test {public static void main(String[] args) throws IOException {//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBKInputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\我是GBK格式的文本.txt"),"GBK");//2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\我是utf_8格式的文件.txt"),"UTF-8");//3.使用InputStreamReader对象中的方法read读取文件int len = 0;while((len = isr.read())!=-1){//4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中osw.write(len);}//5.释放资源osw.close();isr.close();}
}

序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的类型 和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象中存储的数据 信息,都可以用来在内存中创建对象。
看图理解序列化:

ObjectOutputStream:对象的序列化流

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;/*java.io.ObjectOutputStream extends OutputStreamObjectOutputStream:对象的序列化流作用:把对象以流的方式写入到文件中保存构造方法:ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。参数:OutputStream out:字节输出流特有的成员方法:void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。*/
public class DemoObjectOutputStream {public static void main(String[] args) throws IOException {//1.创建ObjectOutputStream对象,构造方法中传递字节输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\person.txt"));//2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中oos.writeObject(new Person("小美女",18));//3.释放资源oos.close();}
}

ObjectInputStream:对象的反序列化流

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;/*java.io.ObjectInputStream extends InputStreamObjectInputStream:对象的反序列化流作用:把文件中保存的对象,以流的方式读取出来使用构造方法:ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。参数:InputStream in:字节输入流特有的成员方法:Object readObject() 从 ObjectInputStream 读取对象。readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)当不存在对象的class文件时抛出此异常反序列化的前提:1.类必须实现Serializable2.必须存在类对应的class文件*/
public class DemoObjectInputStream {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.创建ObjectInputStream对象,构造方法中传递字节输入流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\person.txt"));//2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件Object o = ois.readObject();//3.释放资源ois.close();//4.使用读取出来的对象(打印)System.out.println(o);Person p = (Person)o;System.out.println(p.getName()+p.getAge());}}

案例分析

import java.io.Serializable;/*序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。Serializable接口也叫标记型接口要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记有:就可以序列化和反序列化没有:就会抛出 NotSerializableException异常去市场买肉-->肉上有一个蓝色章(检测合格)-->放心购买-->买回来怎么吃随意static关键字:静态关键字静态优先于非静态加载到内存中(静态优先于对象进入到内存中)被static修饰的成员变量不能被序列化的,序列化的都是对象private static int age;oos.writeObject(new Person("小美女",18));Object o = ois.readObject();Person{name='小美女', age=0}transient关键字:瞬态关键字被transient修饰成员变量,不能被序列化private transient int age;oos.writeObject(new Person("小美女",18));Object o = ois.readObject();Person{name='小美女', age=0}*/
public class Person implements Serializable{private static final long serialVersionUID = 1L;private String name;//private static int age;//private transient int age;public int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}import java.io.*;
import java.util.ArrayList;/*练习:序列化集合当我们想在文件中保存多个对象的时候可以把多个对象存储到一个集合中对集合进序列化和反序列化*/
public class Demo03Test {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.定义一个存储Person对象的ArrayList集合ArrayList<Person> list = new ArrayList<>();//2.往ArrayList集合中存储Person对象list.add(new Person("张三",18));list.add(new Person("李四",19));list.add(new Person("王五",20));//3.创建一个序列化流ObjectOutputStream对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\list.txt"));//4.使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化oos.writeObject(list);//5.创建一个反序列化ObjectInputStream对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\list.txt"));//6.使用ObjectInputStream对象中的方法readObject读取文件中保存的集合Object o = ois.readObject();//7.把Object类型的集合转换为ArrayList类型ArrayList<Person> list2 = (ArrayList<Person>)o;//8.遍历ArrayList集合for (Person p : list2) {System.out.println(p);}//9.释放资源ois.close();oos.close();}
}

打印流

平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于java.io.PrintStream 类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

PrintStream类

import java.io.FileNotFoundException;
import java.io.PrintStream;/*java.io.PrintStream:打印流PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。PrintStream特点:1.只负责数据的输出,不负责数据的读取2.与其他输出流不同,PrintStream 永远不会抛出 IOException3.有特有的方法,print,printlnvoid print(任意类型的值)void println(任意类型的值并换行)构造方法:PrintStream(File file):输出的目的地是一个文件PrintStream(OutputStream out):输出的目的地是一个字节输出流PrintStream(String fileName) :输出的目的地是一个文件路径PrintStream extends OutputStream继承自父类的成员方法:- public void close() :关闭此输出流并释放与此流相关联的任何系统资源。- public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。- public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。- public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。- public abstract void write(int b) :将指定的字节输出流。注意:如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->a如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97*/
public class DemoPrintStream {public static void main(String[] args) throws FileNotFoundException {//System.out.println("HelloWorld");//创建打印流PrintStream对象,构造方法中绑定要输出的目的地PrintStream ps = new PrintStream("10_IO\\print.txt");//如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->aps.write(97);//如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97ps.println(97);ps.println(8.8);ps.println('a');ps.println("HelloWorld");ps.println(true);//释放资源ps.close();}
}

改变打印流的流向

import java.io.FileNotFoundException;
import java.io.PrintStream;/*可以改变输出语句的目的地(打印流的流向)输出语句,默认在控制台输出使用System.setOut方法改变输出语句的目的地改为参数中传递的打印流的目的地static void setOut(PrintStream out)重新分配“标准”输出流。*/
public class DemoPrintStream {public static void main(String[] args) throws FileNotFoundException {System.out.println("我是在控制台输出");PrintStream ps = new PrintStream("10_IO\\目的地是打印流.txt");System.setOut(ps);//把输出语句的目的地改变为打印流的目的地System.out.println("我在打印流的目的地中输出");ps.close();}
}

Java中的File类和IO流相关推荐

  1. Java学习笔记----File类与IO流

    第五章:File类与IO流 第一节:File类 1.1 概述 java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作 Java把电脑中的文件和文件夹(目录) ...

  2. java练气期(2)----java高级(File类与IO流)

    什么是File类 即Java文件类以抽象的方式代表文件名和目录路径名.该类主要用于文件和目录的创建.文件的查找和文件的删除等. File类常用方法 delete()删除此抽象路径名表示的文件和目录. ...

  3. Java基础:File类与IO流

    1. File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 1.2 构造方法 public File(String path ...

  4. 【Java笔记】File类与IO流(另添加NIO2使用)

    文章目录 本章专题与脉络 java.io.File类的使用 概述 构造器 常用方法 获取文件和目录基本信息 列出目录的下一级 File类的重命名功能 判断功能的方法 创建.删除功能 NIO2的使用 P ...

  5. JAVA基础-08.File类与IO流-21.【缓冲流、转换流、序列化流、打印流】

    01_缓冲流的原理 02_转换流的原理 03_序列化和反序列化的概述 04_序列号冲突异常的原理和解决方案 day10[缓冲流.转换流.序列化流] 主要内容 缓冲流 转换流 序列化流 打印流 教学目标 ...

  6. Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制)

    原文:Java 语言基础(异常机制和File类,IO流,多线程,网络编程,反射机制) 异常机制和File类 异常机制 基本概念 异常就是"不正常"的含义,在 Java 语言中主要指 ...

  7. Java语言高级(第四部分)File类与IO流 ->(个人学习记录笔记)

    文章目录 第六章 File类与IO流 1. File类 1.1 概述 1.2 构造方法 1.3 常用方法 获取功能的方法 绝对路径和相对路径 判断功能的方法 创建删除功能的方法 1.4 目录的遍历 2 ...

  8. JavaSE_第14章 File类与IO流

    第14章 File类与IO流 主要内容 File类 字节流 字符流 文件流 缓冲流 转换流 数据流 对象流 打印流 Scanner与System与IO流 教学目标 使用File类对象表示文件或目录 能 ...

  9. 第14章 File类与IO流

    第14章 File类与IO流 主要内容 File类 字节流 字符流 文件流 缓冲流 转换流 数据流 对象流 打印流 Scanner与System与IO流 教学目标 使用File类对象表示文件或目录 能 ...

最新文章

  1. 正在搜索需要的文件_装机必备!分享4个电脑软件,3分钟搞定文件管理难题!...
  2. java小程序连接数据库_Java程序连接各种数据库的方法
  3. Android之让EditText不被键盘挡住
  4. PHP获取字符串的所有子集,PHP Regexp(PCRE)-查找所有子字符串的集合
  5. 用位运算实现求绝对值-有效避开if-else判断
  6. linux下启动tomcat,Cannot find setclasspath.sh
  7. 计算机组装维护理论知识大全,计算机组装与维护知识汇总.docx
  8. 共享办公设备行业兴起,新宠“小熊U租”能否成为独角兽?
  9. curl命令查询IP和运营商
  10. python多进程协同_简单谈谈python中的多进程
  11. c语言将时速转换成配速,配速和时速换算(配速时速换算)
  12. 使用Manjaro作为OpenStreetMap瓦片服务器
  13. vivo是安卓手机吗_拜托你看看vivo手机自带的翻译功能,这么强大的功能浪费了合适吗...
  14. (三)Perl_列表与数组(元素访问、特殊索引$#、qw简写、列表赋值等)
  15. 可变悬挂调节软硬_大众cc可变悬架软硬调节是什么意思
  16. idea常用护眼色的RGB值调整
  17. 波斯语计算机语言,语言「波斯语」10句及词汇
  18. 3.20上午学习英语听力
  19. jsquery获取页面元素的html代码,【jQuery 使用】 利用jQuery.prop(outerHTML)获取包含自身在内的HTML元素的HTML代码...
  20. emnu8086快速指南

热门文章

  1. 网络编程——基础部分
  2. diff和patch
  3. 模拟量、数字量、开关量概述
  4. 改变vim配色:安装colorscheme【转】
  5. python 实现网站_python 实现网站_用web.py实现python网站版hello world网页
  6. iOS13上传相册视频Code=1 Operation not permitted
  7. Windows 包管理器 - Scoop
  8. JDBC 之ResultSetMetaData获取列名字
  9. python做平面设计有前途吗_月入 5K 和月入 2W 设计师的区别
  10. PHP审计方法与步骤