JavaIO流
什么是流
流(Stream)就是一系列的数据
1 //创建文件输入流 2 public static void main(String[] args) { 3 try { 4 File f = new File("d:/lol.txt"); 5 // 创建基于文件的输入流 6 FileInputStream fis = new FileInputStream(f); 7 // 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中 8 } catch (IOException e) { 9 // TODO Auto-generated catch block 10 e.printStackTrace(); 11 } 12 }
字节流
1 //字节输入流InputStream 2 try { 3 File file = new File("E:/OneDrive/Homework/CS/Java/program/test.txt"); 4 //创建字节输入流 5 FileInputStream fileInputStream = new FileInputStream(file); 6 byte[] bytes = new byte[(int) file.length()]; 7 fileInputStream.read(bytes); 8 for (byte b : bytes){ 9 System.out.println(b); 10 } 11 //使用完流需要关闭 12 fileInputStream.close(); 13 } catch (Exception e) { 14 e.printStackTrace(); 15 } 16 //字节输出流OutputStream:如果文件不不存在会自动创建,但如果目录不存在则会抛出异常 17 try { 18 File file = new File("E:/OneDrive/Homework/CS/Java/program/test1.txt"); 19 byte[] bytes = { 88 , 89 };//XY 20 //创建字节输出流 21 FileOutputStream fileOutputStream = new FileOutputStream(file); 22 fileOutputStream.write(bytes); 23 //使用完流需要关闭 24 fileOutputStream.close(); 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28 //JDK7开始,把流定义在try()里,try,catch或者finally结束的时候,会自动关闭 29 30 //对于定义在try外的流,以上关闭流的方法是不严谨的,因为如果文件不存在或读取异常,会导致关闭流代码不执行 31 //标准的关闭流的方法:在finally中关闭 32 } finally { 33 if (null != fileOutputStream) 34 try { 35 fileOutputStream.close(); 36 } catch (IOException e) { 37 // TODO Auto-generated catch block 38 e.printStackTrace(); 39 } 40 }
字符流
1 //FileReader对文件进行字符读取 2 public static void main(String[] args) { 3 File f = new File("E:/OneDrive/Homework/CS/Java/myfile.txt"); 4 try (FileReader fr = new FileReader(f)) { //创建基于文件的Reader 5 char[] all = new char[(int)f.length()]; //创建文件长度的字符数组 6 fr.read(all); //以字符流的形式读取文件的所有内容 7 for (char b:all){ 8 System.out.println(b); 9 } 10 } catch (IOException e) { //注意这里捕获的是IOException 11 e.printStackTrace(); 12 } 13 } 14 15 //FileWriter对文件进行字符写入 16 public static void main(String[] args) { 17 File f = new File("E:/OneDrive/Homework/CS/Java/myfile.txt"); 18 try(FileWriter fw = new FileWriter(f)) { //创建基于文件的Writer 19 String s = "456"; 20 char[] c = s.toCharArray(); //使用toCharArray将字符串转为字符数组 21 fw.write(c); //以字符流的形式写入文件 22 } catch (IOException e) { 23 e.printStackTrace(); 24 } 25 }
中文问题
常见编码:
-
ISO-8859-1 包含 ASCII
-
GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
-
UNICODE 包括了世界上几乎所有的文字
-
UTF-8 是UNICODE的精简版,对数字和字母使用1个字节,对汉字使用3个字节
-
Java采用UNICODE编码
1 //FileInputStream字节流读取中文:必须先了解文本的编码方式,以GBK为例 2 public static void main(String[] args) { 3 File f = new File("E:/OneDrive/Homework/CS/Java/myfile.txt"); 4 try (FileInputStream fis = new FileInputStream(f);) { 5 byte[] all = new byte[(int) f.length()]; 6 fis.read(all); 7 String str = new String(all,"GBK"); //创建字符串对象时需要说明“GBK” 8 System.out.println(str); 9 } catch (IOException e) { 10 e.printStackTrace(); 11 } 12 } 13 14 15 //FileReader字符流读取中文:读取时默认识别成字符 16 public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException { 17 File f = new File("E:/OneDrive/Homework/CS/Java/myfile.txt"); 18 System.out.println("默认编码方式:"+Charset.defaultCharset()); 19 //FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK 20 try (FileReader fr = new FileReader(f)) { 21 char[] cs = new char[(int) f.length()]; 22 fr.read(cs); 23 System.out.println(new String(cs));//使用默认编码方式 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } 27 28 //FileReader不能设置编码方式,使用其他编码方式只能使用InputStreamReader来代替 29 //new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")); 30 try (InputStreamReader isr = new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"))) { 31 char[] cs = new char[(int) f.length()]; 32 isr.read(cs); 33 System.out.printf("%n"); //输出指定编码方式识别的字符 34 System.out.println(new String(cs)); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 }
缓存流
缓存流解决IO频率较高时性能不佳的问题
数据先经过缓存区
1 //buffer 2 //BufferedReader可以一次读取一行数据 3 //PrintWriter可以一次写出一行数据 4 //flush可以立刻将数据写入硬盘,而不用等缓存满
数据流
通过数据流可以实现格式化顺序读写
1 //先创建字节流对象,再创建数据流对象 2 FileInputStream fis = new FileInputStream(f); 3 DataInputStream dis =new DataInputStream(fis); 4 //通过read+类型进行格式化读取 5 boolean b= dis.readBoolean(); 6 int i = dis.readInt(); 7 String str = dis.readUTF(); 8 9 //先创建字节流对象,再创建数据流对象 10 FileOutputStream fos = new FileOutputStream(f); 11 DataOutputStream dos =new DataOutputStream(fos); 12 //通过write+类型进行格式化读取 13 dos.writeBoolean(true); 14 dos.writeInt(300); 15 dos.writeUTF("123 this is gareen");
对象流
把一个对象以流的形式传输(又叫序列化)
对象序列化的前提:这个对象的类实现了Serializable接口
1 public class Hero implements Serializable { 2 //要把Hero对象直接保存在文件上,务必让Hero类实现Serializable接口 3 private static final long serialVersionUID = 1L;//版本号 4 public String name; 5 public float hp; 6 } 7 //========================================================== 8 public static void main(String[] args) { 9 Hero h = new Hero(); 10 h.name = "garen"; 11 h.hp = 616; 12 //准备一个文件用于保存该对象 13 File f =new File("d:/garen.lol"); 14 try( 15 //创建对象输出流 16 FileOutputStream fos = new FileOutputStream(f); 17 ObjectOutputStream oos =new ObjectOutputStream(fos); 18 //创建对象输入流 19 FileInputStream fis = new FileInputStream(f); 20 ObjectInputStream ois =new ObjectInputStream(fis); 21 ) { 22 oos.writeObject(h);//输出对象 23 Hero h2 = (Hero) ois.readObject();//读取对象 24 System.out.println(h2.name); 25 System.out.println(h2.hp); 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } catch (ClassNotFoundException e) { 29 e.printStackTrace(); 30 } 31 }
System.in/out
System.out:控制台输出
Scanner:常用,逐行读取
1 //Scanner更常用 2 Scanner s = new Scanner(System.in); 3 String line = s.nextLine(); 4 //int a = s.nextInt(); 5 System.out.println(line);
流关系图