java中的IO流的讲解
1:File对象的认识(创建三种file的构造方法)
public static void main(String[] args) { //创建文件的三种构造方法 //1:file(String filePath) 通过将指定的路径名字字符串转换为抽象路径来创建新的file实例 File f1 = new File("D:\\MyFile\\test.txt"); System.out.println(f1); //2:file(String parent,String child) 从父路径和子路径的字符创建新的file实例 File f2 = new File("D:\\MyFile", "test.txt"); System.out.println(f2); //3:file(File parent,String child)从父的抽象路径和子路径创建新的file实例 File file = new File("D:\\MyFile"); File f3 = new File(file, "test.txt"); System.out.println(f3); }
2:file类的创建功能
public static void main(String[] args) throws IOException { //:需求1 在D盘下的MyFile创建test.txt File file = new File("D:\\MyFile\\test.txt"); //若为true 证明创建成功 file.createNewFile:(1)如果文件不存在,就创建文件,返回true。(2)若文件存在,则不创建,返回false System.out.println(file.createNewFile()); //:需求2 在D盘下MyFile下创建test目录:(1)如果目录不存在,就创建文件,返回true。(2)若目录存在,则不创建,返回false File file1 = new File("D:\\MyFile\\test"); System.out.println(file1.mkdir()); //:需求3 在D盘下的MyFile中创建多级目录(D:\\MyFile\\test01\\testChild)同理 File file2 = new File("D:\\MyFile\\test01\\testChild"); //mkdirs:创建多级目录 System.out.println(file2.mkdirs()); //注意:不能通过文件名来判断我们创建的是一个文件还是一个目录,应该根据我们调用的方法判断创建的是目录还是文件 }
3:file类的判断和获取功能
public class TestFileThree { public static void main(String[] args) { //1:public boolean isDirectory() 判断次抽象路径名表示的file是否为目录 File f1 = new File("D:\\MyFile\\test.txt"); System.out.println(f1.isDirectory());//false //2:public boolean isFile() 判断此抽象路径名表示的file是否是文件 System.out.println(f1.isFile());//true //3:public boolean exists() 判断次抽象路径名表示的file是否存在 System.out.println(f1.exists());//true //4:public String getAbsolutePath() 返回此抽象路径名的绝对路径名字字符串 System.out.println(f1.getAbsolutePath()); //5:public String getPath()将此抽象路径名转换为路径名字字符串 System.out.println(f1.getPath()); //6:public String getName()返回此抽象路径名的文件或者文件目录名字 System.out.println(f1.getName()); //7:public String list()返回此抽象路径表示的目录和文件的字符串数组 File file = new File("D:\\MyFile"); String[] list = file.list(); for (String s : list) { System.out.println(s); } System.out.println("========================="); //8:public File[] listFiles()返回此抽象路径名表示的目录中的文件和目录的file数组 File[] files = file.listFiles(); for (File file1 : files) { //可用于判断是否是文件 if(file1.isFile()){ System.out.println(file1.getName()); } } } }
4:File的删除方法
public static void main(String[] args) throws IOException { //public boolean delete() 表示删除由此抽象路径的文件或者文件目录 File file = new File("D:\\MyFile\\test.txt"); //若删除成功,则返回true 若失败,则返回false System.out.println(file.delete()); //绝对路径:完整的路径名,不需要任何信息就可以定位他所表示的位置 例如:D:\MyFile\test.txt //相对路径:必须要使用取自其他路径名的解释信息 File file1 = new File("test.txt"); file1.createNewFile(); file1.delete(); //在当前模块下创建目录test File file2 = new File("test"); System.out.println(file2.mkdir()); System.out.println(file2.delete()); //创建目录test 并在目录下创建test.txt File file3 = new File("test"); file2.mkdir(); //在该目录下创建(注意:在创建文件的时候必须创建文件目录。否则会找不到路径) File file4 = new File("test\\test.txt"); file4.createNewFile(); //删除这个文件(删除的目录下如果存在内容,则需要先删除目录下的文件再删除这个目录) file4.delete(); file3.delete(); } }
5:递归调用输入该目录下所有文件的绝对路径
public class DgTestFile { public static void main(String[] args) { File file = new File("D:\\MyFile"); DgTestFile.getAllFilePath(file); } //获取文件的绝对路径 public static void getAllFilePath(File file){ File[] files = file.listFiles(); if(files!=null){ for (File file1 : files) { //判断是不是目录 if(file1.isDirectory()){ //递归 getAllFilePath(file1); }else{ System.out.println(file1.getAbsolutePath()); } } } } }
6:IO流的概括和分类
按照数据的流向
(1)输入流:读数据
(2)输出流:写数据
按照类型来分
(1)字节流:字节输入流,字节输出流
(2)字符流:字符出入流,字符输出流
使用字节输出流写数据
public static void main(String[] args) throws IOException { //(1)调用系统功能,创建了文件(2)创建了字节输入对象(3)让字节输入流对象指向了该文件 FileOutputStream fos = new FileOutputStream("fos.txt"); //通过写入方法将字节写入文件中 fos.write(97); //所有和io相关的资源都需要关闭:关闭此输入流兵释放与此流相关联系的任何资源 fos.close(); }
7:字节流写输入的三种方式
public class FileOutStreamTestTwo { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt",true); // //写数据的第一种方式 fos.write(97); fos.write(98); fos.write(99); fos.write(100); //写数据的第二种方式 void write(byte[] b)通过数据的形式从指定的字节流写入此文件输出流 byte[] b = {97, 98, 99, 100}; //可以通过字符串转换成字节数组 byte[] bytes = "abcdef".getBytes(); fos.write(bytes); //写入数据的第三种方式 void write (byte[] b,int off,int len)从off索引位置开始 指定写len个 fos.write(bytes, 1, 3);//bcd //补充说明 /** * *1:字节流写入数据如何换行?不同操作系统实现换行的方式不同 * windows:\r\n * linux:\n * mac:\r */ /** * 2:字节流写数据如何实现追加写入? * 在创建字节输出流的时候,在创建的时候加一个true 如果为true:则表示在后面追加写入,如果没有加,则表示从头写 */ for (int i = 0; i < 10; i++) { fos.write("Hello".getBytes()); //换行在写入后加换行符号即可 fos.write("\r\n".getBytes()); } fos.close(); } }
8:字节流读数据的方法
public static void main(String[] args) throws IOException { //创建字节输入流的对象 FileInputStream inputStream = new FileInputStream("fos.txt"); //调用字节输入流读对象的数据方法 int read; //如果读到末尾则返回值为-1 while ((read=inputStream.read())!=-1){ System.out.println((char)read); } inputStream.close(); }
9:复制本文文件(案例)
public static void main(String[] args) throws IOException { //创建文件输入流对象 FileInputStream fileInputStream = new FileInputStream("D:\\MyFile\\测试.txt"); //创建文件输出流对象 FileOutputStream fileOutputStream = new FileOutputStream("fos.txt"); int b; while ((b=fileInputStream.read())!=-1){ fileOutputStream.write(b); } fileInputStream.close(); fileOutputStream.close(); }
10:复制图片(案例)
(1)创建文件输入流读取数据
(2)创建文件输出流写数据
(3)用字节数组的方式读入,然后并写入
(4)先关闭输出流,后关闭输入流(先开的后关)
public static void main(String[] args) throws IOException { //创建文件输入流 FileInputStream fileInputStream = new FileInputStream("D:\\MyFile\\1661408864088.jpg"); //创建文件输出流 FileOutputStream fileOutputStream = new FileOutputStream("1661408864088.jpg"); //一次读取一个字节数组 一次写入一个字节数组 byte[] bytes = new byte[1024]; int len; while ((len = fileInputStream.read(bytes, 0, bytes.length)) != -1) { //bytes:需要写出的数据,需要以byte数组的形式传输 off:数组中的下标,表示从数组中索引值off出开始写出数据。 len:写出多少个字节的数据。 fileOutputStream.write(bytes, 0, len); } fileOutputStream.close(); fileInputStream.close(); }
11:字节缓冲流的学习(可以极大提高读取的时间)
public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("bos.txt"); //创建字节缓冲输出流的对象 BufferedOutputStream bo = new BufferedOutputStream(fos); bo.write("hello\r\n".getBytes()); bo.write("world\r\n".getBytes()); bo.close(); fos.close(); //创建字节缓冲流输入流的对象 FileInputStream fis = new FileInputStream("bos.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(fis); //一次读取一个字节 int b; while ((b = bufferedInputStream.read()) != -1) { System.out.print(b); } byte[] bytes = new byte[1024]; //通过数组的形式读取 while ((b = bufferedInputStream.read(bytes)) != -1) { System.out.print(new String(bytes, 0, b)); } bufferedInputStream.close(); fis.close(); }
12:字符流读取数据(为何会出现字符1流)
(1)如果是CBK编码,占2个字节
(2)如果是UTF-8,占3个字节
(3)字符流=字节流+编码表,用字节流复制文本文件的时候,本地文件也存在中文,为何没有出现乱码呢?原因是底层操作会自动进行字节符拼接成中文,那么底层是如何识别中文呢?汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
13:编码和解码
public class EncodingAndDecoding { public static void main(String[] args) throws UnsupportedEncodingException { //编码 String str = "中国"; //通过系统默认的编码 byte[] bytes = str.getBytes(); System.out.println(Arrays.toString(bytes));//[-28, -72, -83, -27, -101, -67] //通过指定的格式编码 byte[] bytes1 = str.getBytes("UTF-8"); System.out.println(Arrays.toString(bytes1));//[-28, -72, -83, -27, -101, -67] byte[] gbks = str.getBytes("GBK"); System.out.println(Arrays.toString(gbks));//[-42, -48, -71, -6] //解码 //用系统默认的方式解码 String string = new String(bytes); System.out.println(string);//中国 //通过指定的方式解码 String s = new String(bytes, "UTF-8"); System.out.println(s);//中国 //如果通过不一样的编码格式解码会出现乱码的问题 String gbk = new String(bytes, "GBK"); System.out.println(gbk);//涓浗 } }
14:字符流
(1)字符流中的编码解码问题(通过指定的编码格式解码和编码)
public static void main(String[] args) throws IOException { //输入流 //1:创建字符输入流对象(默认的编码格式) OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("bos.txt")); outputStreamWriter.write("中国"); outputStreamWriter.close(); //2:指定字符集创建 OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("bos.txt"), "GBK"); outputStreamWriter.write("中国"); outputStreamWriter.close(); //输入流(通过GBK方式指定的读取数据) InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("bos.txt"),"GBK"); //一个字节的读取 int b; // while ((b = inputStreamReader.read())!=-1){ // System.out.print((char)b); // } //以一个数组的方式读取 char[] chars = new char[1024]; int len; while ((len = inputStreamReader.read(chars) )!= -1) { System.out.println(new String(chars,0,len)); } inputStreamReader.close(); }
15:字符流写数据的5种方式
public static void main(String[] args) throws IOException { //字符流写数据的五种方式 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("bos.txt")); //1:第一种写数据的方式(字符流写数据) osw.write(97); //字符流写数据需要刷新(字符流的写数据底层都是通过字节流进行写入的) osw.flush();//刷新流后可以继续写数据 osw.close();//在字符换种流中,关闭的时候会先刷新再关闭,当释放资源后,就不能再往里面写入数据了 //2:第二种方式(写一个字符数据的数据) char[] chars = {'a', 'b', 'c', 'd', 'e'}; osw.write(chars); osw.close(); //3:第三种方式(写入数组的一部分数据)(从数组下标1开始到3结束即:bcd) osw.write(chars, 1, 3); osw.close(); //4:写一个字符串数据 osw.write("aaaaaaaaaa"); osw.close(); //5:写字符串的一部分数据 String a = "1112222333"; osw.write(a, 1, 3); osw.close(); }
16:字符流读数据的2种方式
public static void main(String[] args) throws IOException { InputStreamReader streamReader = new InputStreamReader(new FileInputStream("bos.txt")); //1:一次读一个字符数据 int ch; while ((ch = streamReader.read()) != -1) { System.out.print((char)ch); } //2:一次读一个字符数据 char[] chars = new char[1024]; int ch; while ((ch = streamReader.read(chars)) != -1) { System.out.println(new String(chars,0,ch)); } streamReader.close(); }