Java笔记(六)
IO流:
字符流和字节流:
字符流两个基类: InputStream OutputStream
字节流两个基类: Reader Writer
FileWriter:
1 import java.io.FileWriter; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args) throws IOException { 6 //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件 7 //而且该文件被创建到指定目录下,如果该目录下已有同名文件,将被覆盖 8 //该步就是在明确数据要存放的目的地 9 FileWriter fw = new FileWriter("F:\\demo.txt"); 10 11 //调用write方法,将字符串写入到流中 12 fw.write("abcde"); 13 14 //刷新流对象中的缓冲区数据 15 //将数据刷到目的地中 16 fw.flush(); 17 18 //关闭流资源,但是关闭之前会刷新一次内部的缓冲区数据 19 //将数据刷到目的地中 20 //和flush区别:flush刷新后,流可以继续使用;close刷新后,会将流关闭 21 fw.close(); 22 } 23 }
IO异常处理方式:
1 import java.io.FileWriter; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args) { 6 FileWriter fw = null; 7 try{ 8 fw = new FileWriter("F:\\demo.txt"); 9 fw.write("abcdefg"); 10 }catch(IOException e){ 11 System.out.println(e.toString()); 12 }finally{ 13 if(fw != null){ 14 try{ 15 fw.close(); 16 }catch(IOException e){ 17 System.out.println(e.toString()); 18 } 19 } 20 } 21 } 22 }
文件的续写:
1 import java.io.FileWriter; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args) throws IOException { 6 //传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写 7 FileWriter fw = new FileWriter("F:\\demo.txt", true); 8 fw.write("haha"); 9 fw.close(); 10 } 11 }
文件的读取方式(一):
1 import java.io.FileReader; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args) throws IOException { 6 //创建一个文件读取流对象,和指定名称的文件相关联 7 //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException 8 FileReader fr = new FileReader("F:\\demo.txt"); 9 10 //调用读取流对象的read方法 11 //read():一次读一个字符,而且会自动往下读 12 int ch = 0; 13 while((ch = fr.read()) != -1){ 14 System.out.print((char)ch); 15 } 16 } 17 }
文件的读取方式(二):
1 import java.io.FileReader; 2 import java.io.IOException; 3 4 public class Demo{ 5 public static void main(String[] args) throws IOException { 6 FileReader fr = new FileReader("F:\\demo.txt"); 7 8 //定义一个字符数组,用于存储读到的字符 9 //该read(char[])返回的是读到字符的个数 10 char[] buf = new char[1024]; 11 int num = 0; 12 while((num = fr.read(buf)) != -1){ 13 System.out.println(new String(buf, 0, num)); 14 } 15 fr.close(); 16 } 17 }
复制文件:
1 import java.io.FileReader; 2 import java.io.FileWriter; 3 import java.io.IOException; 4 5 public class Demo{ 6 public static void main(String[] args){ 7 copy(); 8 } 9 public static void copy(){ 10 FileReader fr = null; 11 FileWriter fw = null; 12 try{ 13 fr = new FileReader("F:\\demo.txt"); 14 fw = new FileWriter("F:\\demo_copy.txt"); 15 char[] buf = new char[1024]; 16 int len = 0; 17 while((len = fr.read(buf)) != -1){ 18 fw.write(buf, 0, len); 19 } 20 }catch(IOException e){ 21 throw new RuntimeException("读写失败"); 22 }finally{ 23 if(fr != null){ 24 try{ 25 fr.close(); 26 }catch(IOException e){ 27 System.out.println(e.toString()); 28 } 29 } 30 if(fw != null){ 31 try{ 32 fw.close(); 33 }catch(IOException e){ 34 System.out.println(e.toString()); 35 } 36 } 37 } 38 } 39 }
BufferedWriter:
缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区前,必须要先有流对象。
1 import java.io.BufferedWriter; 2 import java.io.FileWriter; 3 import java.io.IOException; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException { 7 //创建一个字符写入流对象 8 FileWriter fw = new FileWriter("F:\\demo.txt"); 9 10 //为了提高字符写入流效率,加入缓冲技术 11 //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可 12 BufferedWriter bufw = new BufferedWriter(fw); 13 for(int i = 0; i < 5; i++){ 14 bufw.write("abcd" + i); 15 bufw.newLine(); //等同于bufw.write("\r\n");且跨平台 16 bufw.flush(); 17 } 18 19 //关闭缓冲区,就是在关闭缓冲区中的流对象 20 bufw.close(); 21 } 22 }
BufferedReader:
该缓冲区提供了一个一次读一行的方法readLine,方便用于对文本数据的获取。当返回null时,表示读到文件的末尾。
1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException { 7 //创建一个读取流对象和文件相关联 8 FileReader fr = new FileReader("F:\\demo.txt"); 9 10 //为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数 11 BufferedReader bufr = new BufferedReader(fr); 12 13 String line = null; 14 while((line = bufr.readLine()) != null){ 15 System.out.println(line); 16 } 17 bufr.close(); 18 } 19 }
通过缓冲区复制一个文件:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileReader; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 7 public class Demo{ 8 public static void main(String[] args) { 9 BufferedReader bufr = null; 10 BufferedWriter bufw = null; 11 try{ 12 bufr = new BufferedReader(new FileReader("F:\\demo.txt")); 13 bufw = new BufferedWriter(new FileWriter("F:\\demo_copy.txt")); 14 String line = null; 15 while((line = bufr.readLine()) != null){ 16 bufw.write(line); 17 bufw.newLine(); 18 bufw.flush(); 19 } 20 }catch(IOException e){ 21 throw new RuntimeException("读写失败"); 22 }finally{ 23 if(bufr != null){ 24 try{ 25 bufr.close(); 26 }catch(IOException e){ 27 throw new RuntimeException("读取关闭失败"); 28 } 29 } 30 if(bufw != null){ 31 try{ 32 bufw.close(); 33 }catch(IOException e){ 34 throw new RuntimeException("写入关闭失败"); 35 } 36 } 37 } 38 } 39 }
模拟BufferedReader:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileReader; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 7 class MyBufferedReader{ 8 private FileReader f; 9 MyBufferedReader(FileReader f){ 10 this.f = f; 11 } 12 public String myReadLine() throws IOException{ 13 StringBuilder sb = new StringBuilder(); 14 int ch = 0; 15 while((ch = f.read()) != -1){ 16 if(ch == '\r') 17 continue; 18 else if(ch == '\n') 19 return sb.toString(); 20 else 21 sb.append((char)ch); 22 } 23 if(sb.length() != 0){ 24 return sb.toString(); 25 } 26 return null; 27 } 28 public void myClose() throws IOException{ 29 f.close(); 30 } 31 } 32 33 public class Demo{ 34 public static void main(String[] args) throws IOException { 35 MyBufferedReader mybuf = new MyBufferedReader(new FileReader("F:\\demo.txt")); 36 String line = null; 37 while((line = mybuf.myReadLine()) != null){ 38 System.out.println(line); 39 } 40 mybuf.myClose(); 41 } 42 }
LineNumberReader:
1 import java.io.FileReader; 2 import java.io.IOException; 3 import java.io.LineNumberReader; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException { 7 FileReader fr = new FileReader("F:\\demo.txt"); 8 LineNumberReader num = new LineNumberReader(fr); 9 num.setLineNumber(100); 10 String line = null; 11 while((line = num.readLine()) != null){ 12 System.out.println(num.getLineNumber() + ": " + line); 13 } 14 num.close(); 15 } 16 }
输出结果:
101: abcd0 102: abcd1 103: abcd2 104: abcd3 105: abcd4
模拟LineNumberReader:
1 import java.io.FileReader; 2 import java.io.IOException; 3 import java.io.Reader; 4 5 class MyBufferedReader{ 6 private FileReader f; 7 MyBufferedReader(FileReader f){ 8 this.f = f; 9 } 10 public String myReadLine() throws IOException{ 11 StringBuilder sb = new StringBuilder(); 12 int ch = 0; 13 while((ch = f.read()) != -1){ 14 if(ch == '\r') 15 continue; 16 else if(ch == '\n') 17 return sb.toString(); 18 else 19 sb.append((char)ch); 20 } 21 if(sb.length() != 0){ 22 return sb.toString(); 23 } 24 return null; 25 } 26 public void myClose() throws IOException{ 27 f.close(); 28 } 29 } 30 31 class MyLineNumberReader extends MyBufferedReader{ 32 private int lineNum; 33 MyLineNumberReader(FileReader r) { 34 super(r); 35 } 36 public String myReadLine() throws IOException{ 37 lineNum++; 38 return super.myReadLine(); 39 } 40 public void setLineNumber(int lineNum){ 41 this.lineNum = lineNum; 42 } 43 public int getLineNumber(){ 44 return lineNum; 45 } 46 } 47 48 public class Demo{ 49 public static void main(String[] args) throws IOException { 50 MyLineNumberReader myline = new MyLineNumberReader(new FileReader("F:\\demo.txt")); 51 String line = null; 52 myline.setLineNumber(100); 53 while((line = myline.myReadLine()) != null){ 54 System.out.println(myline.getLineNumber() + ": " + line); 55 } 56 myline.myClose(); 57 } 58 }
字节流读写操作:
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 public class Demo{ 7 public static void main(String[] args) throws IOException{ 8 readFile_03(); 9 } 10 public static void writeFile() throws IOException{ 11 FileOutputStream f = new FileOutputStream("F:\\demo.txt"); 12 f.write("ztq".getBytes()); 13 //不需要刷新 14 f.close(); 15 } 16 public static void readFile_01() throws IOException{ 17 FileInputStream f = new FileInputStream("F:\\demo.txt"); 18 int ch = 0; 19 while((ch = f.read()) != -1){ 20 System.out.print((char)ch); 21 } 22 f.close(); 23 } 24 public static void readFile_02() throws IOException{ 25 FileInputStream f = new FileInputStream("F:\\demo.txt"); 26 byte[] buf = new byte[1024]; 27 int len = 0; 28 while((len = f.read(buf)) != -1){ 29 System.out.println(new String(buf, 0, len)); 30 } 31 f.close(); 32 } 33 //字节流特有的读文件方法 34 public static void readFile_03() throws IOException{ 35 FileInputStream f = new FileInputStream("F:\\demo.txt"); 36 37 //定义一个大小刚好的数组,不用循环 38 byte[] buf = new byte[f.available()]; 39 f.read(buf); 40 System.out.println(new String(buf)); 41 } 42 }
复制一个图片:
1 import java.io.FileInputStream; 2 import java.io.FileOutputStream; 3 import java.io.IOException; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException{ 7 FileInputStream fis = null; 8 FileOutputStream fos = null; 9 try{ 10 fis = new FileInputStream("F:\\pic.jpg"); 11 fos = new FileOutputStream("F:\\pic_copy.jpg"); 12 byte[] buf = new byte[1024]; 13 int len = 0; 14 while((len = fis.read(buf)) != -1){ 15 fos.write(buf, 0, len); 16 } 17 }catch(IOException e){ 18 throw new RuntimeException("复制文件失败"); 19 }finally{ 20 if(fis != null){ 21 try{ 22 fis.close(); 23 }catch(IOException e){ 24 throw new RuntimeException("读取流关闭失败"); 25 } 26 } 27 if(fos != null){ 28 try{ 29 fos.close(); 30 }catch(IOException e){ 31 throw new RuntimeException("写入流关闭失败"); 32 } 33 } 34 } 35 } 36 }
字节流的缓冲区:
1 import java.io.BufferedInputStream; 2 import java.io.BufferedOutputStream; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 public class Demo{ 8 public static void main(String[] args) throws IOException{ 9 BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("F:\\pic.jpg")); 10 BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("F:\\pic_copy.jpg")); 11 int ch = 0; 12 while((ch = bufis.read()) != -1){ 13 bufos.write(ch); 14 } 15 bufis.close(); 16 bufos.close(); 17 } 18 }
模拟字节流的缓冲区:
注:11111111提升到int型还是-1,因为在8个1的前面补的全是1。要是在前面补0,既可以保留原字节数据不变,又可以避免-1的出现。
11111111 11111111 11111111 11111111 &
00000000 00000000 00000000 11111111
1 import java.io.BufferedOutputStream; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 class MyBufferedInputStream{ 8 private InputStream in; 9 private int count = 0, pos = 0; 10 private byte[] buf = new byte[1024]; 11 MyBufferedInputStream(InputStream in){ 12 this.in = in; 13 } 14 public int myRead() throws IOException{ 15 if(count == 0){ 16 count = in.read(buf); 17 if(count < 0) return -1; 18 pos = 0; 19 byte b = buf[pos]; 20 count--; 21 pos++; 22 return b & 0xff; 23 } 24 else if(count > 0){ 25 byte b = buf[pos]; 26 count--; 27 pos++; 28 return b & 0xff; 29 } 30 return -1; 31 } 32 public void myClose() throws IOException{ 33 in.close(); 34 } 35 } 36 37 public class Demo{ 38 public static void main(String[] args) throws IOException{ 39 MyBufferedInputStream mybfis = new MyBufferedInputStream(new FileInputStream("F:\\pic.jpg")); 40 BufferedOutputStream bfos = new BufferedOutputStream(new FileOutputStream("F:\\pic_copy.jpg")); 41 int ch = 0; 42 while((ch = mybfis.myRead()) != -1){ 43 bfos.write(ch); 44 } 45 mybfis.myClose(); 46 bfos.close(); 47 } 48 }
读取键盘录入:
通过键盘录入数据,当录入一行数据后,就将该行数据进行打印。如果录入的数据是over,那么停止录入。
1 import java.io.IOException; 2 import java.io.InputStream; 3 4 public class Demo{ 5 public static void main(String[] args) throws IOException{ 6 InputStream in = System.in; 7 StringBuilder sb = new StringBuilder(); 8 while(true){ 9 int ch = in.read(); 10 if(ch == '\r') 11 continue; 12 else if(ch == '\n'){ 13 String s = sb.toString(); 14 if("over".equals(s)) 15 break; 16 System.out.println(s); 17 sb.delete(0, sb.length()); 18 } 19 else{ 20 sb.append((char)ch); 21 } 22 } 23 } 24 }
读取转换流:
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 6 public class Demo{ 7 public static void main(String[] args) throws IOException{ 8 //获取键盘录入对象 9 InputStream in = System.in; 10 11 //将字节流对象转成字符流对象,使用转换流。InputStreamReader 12 InputStreamReader isr = new InputStreamReader(in); 13 14 //为了提高效率,将字符串进行缓冲区技术高效操作。BufferedReader 15 BufferedReader bufr = new BufferedReader(isr); 16 17 String line = null; 18 while((line = bufr.readLine()) != null){ 19 if("over".equals(line)) break; 20 System.out.println(line.toUpperCase()); 21 } 22 bufr.close(); 23 } 24 }
写入转换流:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.IOException; 4 import java.io.InputStreamReader; 5 import java.io.OutputStreamWriter; 6 7 public class Demo{ 8 public static void main(String[] args) throws IOException{ 9 //键盘录入常见写法 10 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); 11 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); 12 13 String line = null; 14 while((line = bufr.readLine()) != null){ 15 if("over".equals(line)) break; 16 bufw.write(line.toUpperCase()); 17 bufw.newLine(); 18 bufw.flush(); 19 } 20 bufr.close(); 21 bufw.close(); 22 } 23 }
流操作的基本规律:
1.(1)明确源和目的
源:输入流。InputStream Reader
目的:输出流。 OutputStream Writer
(2)操作的数据是否是纯文本
是:字符流。
否:字节流。
(3)当体系明确后,再明确要是用哪个具体的对象。通过设备来进行区分。
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
通常涉及到字符编码转换时,需要用到转换流。
异常的日志信息:
1 import java.io.IOException; 2 import java.io.PrintStream; 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 public class Demo{ 7 public static void main(String[] args){ 8 try{ 9 int[] arr = new int[2]; 10 System.out.println(arr[3]); 11 }catch(Exception e){ 12 try{ 13 Date d = new Date(); 14 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 15 String s = sdf.format(d); 16 PrintStream ps = new PrintStream("F:\\exception.log"); 17 ps.println(s); 18 System.setOut(ps); 19 }catch(IOException ex){ 20 throw new RuntimeException("日志文件创建失败"); 21 } 22 e.printStackTrace(System.out); 23 } 24 } 25 }
将系统信息存储到文件中:
1 import java.io.IOException; 2 import java.io.PrintStream; 3 import java.util.Properties; 4 5 public class Demo{ 6 public static void main(String[] args) throws IOException{ 7 Properties pro = System.getProperties(); 8 pro.list(new PrintStream("F:\\properties.txt")); 9 } 10 }