7、I/O流
一、流的概念:流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。I/O就即用于处理设备之间的数据传输。
1、流的分类:
a)、按操作数据单位分类:字节流、字符流。
b)、按流向分类:输入流、输出流。
c)、按照功能分类:节点流、处理流。
字节流的抽象基类:InputStream、OutputStream
字符流的抽象基类:Reader、Writer
二、字符流:Reader、Writer
1、FileWriter:
1 public class IOTest { 2 3 /** 4 * 需求:往一个文本文件里写入一些字符、字符串 5 * 1、创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将被覆盖。 6 * 2、调用write方法,将字符串写入到流(内存)中 7 * 3、调用flush方法刷新缓冲中的数据,将数据刷到目的地中 8 * 4、close方法:关闭流资源,但是关闭之前会刷新一次内存中的缓冲数据,将数据刷新到目的地中 9 * 10 * 注意:close和flush的区别:flush刷新后流可以继续使用;close刷新后会关闭流 11 */ 12 public static void main(String[] args) { 13 Writer writer = null; 14 try{ 15 /* true:代表打开已存在的文件。如果指定的文件不存在,就会创建新的文件 16 * 如果指定的文件已存在,不会创建新的文件,会在原有数据的基础上追加新的数据*/ 17 writer = new FileWriter("E:\\qqq.txt", true); 18 writer.append('a'); //将指定字符添加到此 writer 19 writer.append("123qwerewqr");//将指定字符序列添加到此 writer。 20 writer.append("--abcdesafd", 0, 4);// 包含头,不包含尾 将指定字符序列的子序列添加到此 writer.Appendable 即将"--abcdesafd"的第0-3位上的字符添加到write上 21 char[] ch = new char[]{'A', 'Q', 'W', 'T'}; 22 writer.write(ch);//写入数组 23 writer.write(ch, 1, 2);//写入数组的一部分 24 writer.write("adsfkwe\r\n字符流写入示例");// 记事本里要换行使用\r\n 25 26 writer.flush();// 调用flush方法刷新缓冲中的数据,将数据刷到目的地中 27 28 }catch(Exception e){ 29 e.printStackTrace(); 30 }finally{ 31 try { 32 if(writer != null){ 33 writer.close();// 在关闭流资源之前,会先调用flush方法,然后再关闭 34 } 35 } catch (Exception e) { 36 e.printStackTrace(); 37 } 38 } 39 } 40 } 41 42 运行后可在相应的txt文件中看到下面的类容: 43 44 a123qwerewqr--abAQWTQWadsfkwe 45 字符流写入示例
2、FileRead:
a)、一个一个的读:
1 public class IOTest { 2 /** 3 * 1、创建一个fileReader对象,和指定的文件想关联,要保证文件已经存在,如果不存在会报FileNotFoundException错误 4 * 2、调用读取流的read方法,一次读一个字节,并且会自动往下读。 5 * 3、调用close方法关闭资源 6 */ 7 8 public static void main(String[] args) { 9 try { 10 FileReader fr = new FileReader("E://qqq.txt"); 11 System.out.println((char)fr.read()); //这个地方一定要加强转,否则显示的将是ASCLL码的值 12 //读取文件中所有的字符 13 while(fr.ready()){ //如果保证下一个 read() 不阻塞输入 14 System.out.print((char)fr.read()); 15 } 16 fr.close(); 17 } catch (Exception e) { 18 e.printStackTrace(); 19 } 20 } 21 }
b)、用数组来一次性提取文件中的类容:
public class IOTest { /** * 1、创建一个fileReader对象,和指定的文件想关联,要保证文件已经存在,如果不存在会报FileNotFoundException错误 * 2、调用读取流的read方法,一次读一个字节,并且会自动往下读。 * 3、调用close方法关闭资源 */ public static void main(String[] args) { try { FileReader fr = new FileReader("E://qqq.txt"); char[] buff = new char[4]; int num1 = fr.read(buff);// 将字符读入至buff数组里,返回的是读取的字符数 System.out.println(num1 + "\t" + String.valueOf(buff)); int num2 = fr.read(buff); System.out.println(num2 + "\t" + String.valueOf(buff)); fr.close(); } catch (Exception e) { e.printStackTrace(); } } } /* 显示结果为: 4 a123 4 qwer */
三、字符流的缓冲区:缓冲区提高了流的操作效率。但必须注意在创建缓冲区之前必须要先有流的对象。
1、BufferedWriter
1 public class IOTest { 2 public static void main(String[] args) { 3 FileWriter fw = null; 4 BufferedWriter bw = null; 5 try { 6 fw = new FileWriter("E:\\qqq.txt");// 创建一个字符流的输出对象 7 bw = new BufferedWriter(fw);// 创建一个缓冲区字符流,将字符流对象作为参数传递给构造方法 8 bw.write("asdflkj;l123123");// 通过 write方法将内容写入缓冲区里 9 bw.write("asdflkj;l123123"); 10 bw.newLine();//写入一个行分隔符。 11 bw.write("asflkj;l123123"); 12 bw.newLine(); 13 bw.write("asdflkj;l123123"); 14 bw.flush();// 通过flush方法将缓冲区里的内容写入至目标文件里 15 16 } catch (Exception e) { 17 e.printStackTrace(); 18 } finally{ 19 try{ 20 if(bw != null){ 21 bw.close();// 会关闭与之相关的字符流对象 22 } 23 }catch(Exception e){ 24 e.printStackTrace(); 25 } 26 } 27 } 28 /* 29 在qqq.txt文件中输出结果为: 30 asdflkj;l123123asdflkj;l123123 31 asflkj;l123123 32 asdflkj;l123123 33 * */ 34 }
2、BufferedReader
1 public class IOTest { 2 public static void main(String[] args) { 3 FileReader fr = null; 4 BufferedReader br = null; 5 try { 6 // 创建一个字符输入流对象 7 fr = new FileReader("E:\\qqq.txt"); 8 // 创建一个缓冲字符输入流,将字符输入流对象作为参数传递给构造方法 9 br = new BufferedReader(fr); 10 String str = ""; 11 while((str = br.readLine()) != null){ //readLine():读取一个文本行 12 System.out.println(str); 13 } 14 }catch (Exception e) { 15 e.printStackTrace(); 16 } finally{ 17 try{ 18 if(br != null){ 19 br.close();// 关闭与之相关的字符流 20 } 21 }catch(Exception e){ 22 e.printStackTrace(); 23 } 24 } 25 } 26 }
四、字节流:InputStream、OutputStream
1、FileInputStream
1 public class IOTest { 2 /** 3 * 读取a.jpg这幅图片中的数据在后台显示 4 */ 5 public static void main(String[] args) { 6 FileInputStream fis = null; 7 try{ 8 fis = new FileInputStream("E:\\a.jpg"); 9 byte[] buff = new byte[1024]; 10 int len = 0; 11 while((len = fis.read(buff)) != -1){ 12 for(int i = 0; i < len; i++){ 13 System.out.print(buff[i]); 14 } 15 System.out.println(); 16 } 17 18 }catch(Exception e){ 19 e.printStackTrace(); 20 }finally{ 21 try{ 22 if(fis != null){ 23 fis.close(); 24 } 25 }catch(Exception e){ 26 e.printStackTrace(); 27 } 28 } 29 } 30 }
2、FileOutputStream
1 public class IOTest { 2 /* 3 * 向qqq.txt文件中写入一个一组数据 4 */ 5 public static void main(String[] args) { 6 FileOutputStream fos = null; 7 try{ 8 fos = new FileOutputStream("E:\\qqq.txt"); 9 byte[] b1 = new byte[]{122, 97, 99, 65, 90}; 10 fos.write(b1);// 通过write方法写入一个字节数组 11 }catch(Exception e){ 12 e.printStackTrace(); 13 }finally{ 14 try{ 15 if(fos != null){ 16 fos.close(); 17 } 18 }catch(Exception e){ 19 e.printStackTrace(); 20 } 21 } 22 } 23 }
3、通过字节流及字节流缓冲区复制一个图片
1 public class IOTest { 2 /*将E盘中的a.jpg图片复制为b.jpg 3 * 4 */ 5 public static void main(String[] args) { 6 FileInputStream fis = null; 7 FileOutputStream fos = null; 8 try{ 9 fis = new FileInputStream("E:\\b.jpg"); 10 fos = new FileOutputStream("E:\\c.jpg"); 11 byte[] buff = new byte[1024]; 12 int len = 0; 13 while((len = fis.read(buff)) != -1){ 14 for(int i = 0; i < len; i++){ 15 fos.write(buff[i]); 16 } 17 } 18 }catch(Exception e){ 19 e.printStackTrace(); 20 }finally{ 21 try{ 22 if(fis != null)fis.close(); 23 }catch(Exception e){e.printStackTrace();} 24 try{ 25 if(fos != null)fos.close(); 26 }catch(Exception e){e.printStackTrace();} 27 } 28 } 29 }
五、读取键盘录入:
1 public class IOTest { 2 /* 3 * 读取键盘值 4 */ 5 public static void main(String[] args) throws IOException { 6 //获取到读取键盘录入的流对象。类型是InputStream 7 InputStream is = System.in; 8 while(true){ 9 int num1 = is.read();// 返回的是一个ASCLL码的值 10 System.out.println((char)num1); 11 } 12 13 } 14 }
六、File:将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。separator:与系统有关的默认名称分隔符。
1、对文件的一些常见操作的举例:
1 public class IOTest { 2 3 public static void main(String[] args) throws IOException { 4 /* 5 * 实验的空目录或者说是起始目录为E:\\99 6 */ 7 File file = new File("E:\\99\\a.txt"); 8 File file1 = new File("E:\\99\\aa"); 9 File file2 = new File("E:\\99\\bb\\cc"); 10 File file3 = new File("E:\\99\\qqq.txt"); 11 /* 12 * 创建文件或这是一个文件夹 13 */ 14 //创建一个"a.txt"文件,创建成功则返回true 15 System.out.println("createNewFile():" + file.createNewFile()); 16 //创建一个名字为"aa"的文件夹 17 System.out.println("createNewFile():" + file1.mkdir()); 18 // 创建多级目录即在E:\\99目录下先创建一个bb文件夹,再在bb文件夹下新建一个cc文件夹 19 System.out.println("mkdirs():" + file2.mkdirs()); 20 21 /* 22 * 删除一个文件或者删除一个文件夹 23 */ 24 System.out.println("delete():" + file.delete()); 25 System.out.println("delete():" + file1.delete()); 26 System.out.println("delete():" + file2.delete()); 27 /* 28 * 判断 29 */ 30 //测试此抽象路径名表示的文件或目录是否存在 31 System.out.println("exists():" + file.exists()); 32 //测试此抽象路径名表示的文件是否是一个目录。 33 System.out.println("isDirectory():" + file.isDirectory()); 34 //测试此抽象路径名表示的文件是否是一个标准文件。 35 System.out.println("isFile():" + file.isFile()); 36 // 测试此抽象路径名指定的文件是否是一个隐藏文件。 37 System.out.println("isHidden():" + file.isHidden()); 38 /* 39 * 获取信息 40 */ 41 //返回由此抽象路径名表示的文件或目录的名称。 42 System.out.println("getName():" + file3.getName()); 43 //返回此抽象路径名父目录的路径名字符串,如果此路径名没有指定父目录,则返回 null。 44 System.out.println("getParent():" + file3.getParent()); 45 //将此抽象路径名转换为一个路径名字符串。 46 System.out.println("getPath():" + file3.getPath()); 47 //返回此抽象路径名的绝对路径名字符串。 48 System.out.println("getAbsolutePath():" + file3.getAbsolutePath()); 49 } 50 }