Idea默认的当前路径在:工程project的根 //当前路径 fis = new FileInputStream("D:\\ideaworkspace\\example\\src\\com\\basics\\extest"); IO(Input Output): Input(输入流):往内存中去叫做输入(Input)也叫读(read) Input(输出流):从内存中出来叫做输出(Output)也叫写(write) 按照读取方式不同分为: 字节流:一次读一个字节(8个二进制位),可以读任何文件(a占一个字节(windows,java占两个),中占两个字节) a中: 第一次读'a',第二次:中的一半,第三次:'a中' 字符流:一次读一个字符,只能读txt的普通文本 分为四类:(以Stream结尾的为字节流,以reader/writer结尾时字符流)(都是抽象类) InputStream: 字节输入流 OutPutStream: 字节输出流 Reader: 字符输入流 Writer: 字符输出流 所有的输出流都实现了Flushable接口,都有flush()方法(最终输出之后使用flush()刷新(清空管道)) 需要掌握: 文件专属:(byte数组) ** -FileInputStream ** -FileOutPutStream (char数组) -FileReader -FileWriter 转换流:(字节流转字符流) InputStreamReader OutputStreamWriter 缓冲流专属: BufferedReader BufferedWrite BufferInputStream BufferOutputStream 数据流专属: DataInputStream DataOutputStream 标准输出流: PrintWriter ** PrintStream 对象专属流: ** ObjectInputStream ** ObjectOutputStream FileInputStream-------------------------------------------------- FileInputStream fis = null; try { //fis = new FileInputStream("D:\\2021年\\新建文本文档.txt"); //当前路径 fis = new FileInputStream("D:\\ideaworkspace\\example\\src\\com\\basics\\extest"); //采用byte数组,一次读"数组.length"个字节 //int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 byte[] bytes = new byte[4]; //--------------------------------------- //此时readcount中有四个字节abcd int readcount = fis.read(bytes); System.out.println(readcount); //调用String的构造方法把数组转成字符串,但是应该读几个转换几个 //System.out.println(new String(bytes)); //调用另个一构造方法 System.out.println(new String(bytes,0,readcount)); //在继续调用读字节只能读到两个字节ef,会把ab覆盖 readcount = fis.read(bytes); System.out.println(readcount); System.out.println(new String(bytes,0,readcount)); //------------------------------------------------- //上述代码改造为 while (true){ int readcount = fis.read(bytes); if (readcount == -1) { break; } System.out.print(new String(bytes,0,readcount)); } FileInputStream最后为*** FileInputStream fis = null; try { //fis = new FileInputStream("D:\\2021年\\新建文本文档.txt"); //当前路径 fis = new FileInputStream("D:\\ideaworkspace\\example\\src\\com\\basics\\extest"); //采用byte数组,一次读"数组.length"个字节 //int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 byte[] bytes = new byte[4]; int readcount = 0; while ((readcount = fis.read(bytes))!= -1){ System.out.print(new String(bytes,0,readcount)); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis == null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } --------------------------------------------------------------- fis = new FileInputStream("D:\\ideaworkspace\\example\\src\\com\\basics\\extest");//abcdef System.out.println("还有"+ fis.available()+"个字节没有读");//6 //使用available方法可以一次读完,不需要循环 byte[] bytes = new byte[fis.available()]; int readcount = fis.read(bytes); System.out.println(new String(bytes)); -------------------------------------------------------------- 其他常用方法 1. int available() 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 fis = new FileInputStream("D:\\ideaworkspace\\example\\src\\com\\basics\\extest"); System.out.println("还有"+ fis.available()+"个字节没有读");//6 //使用available方法可以一次读完,不需要循环 byte[] bytes = new byte[fis.available()]; int readcount = fis.read(bytes); System.out.println(new String(bytes)); 但是不适合大文件,因为byte[]不能太大 2.long skip(long n) 从输入流中跳过并丢弃 n 个字节的数据。 fis.skip(2); System.out.println("还有"+ fis.available()+"个字节没有读"); FileOutputStream---------------------------------------------------- try { // fos =new FileOutputStream(("D:\\2021年\\新建文本文档.txt"));//文件不存在会自动新建 // //谨慎使用,会把原文件清空再重新写入 // fos =new FileOutputStream(("Myfile"));//文件不存在会自动新建//位置在工程文件的根目录 //提供了一个构造方法,以追加的方法写入,不会清空源文件 fos = new FileOutputStream("Myfile",true); byte[] bytes = {97,98,99,100}; fos.write(bytes);//abcd String s = "双剑华斩"; byte[] bytes1 = s.getBytes(); fos.write(bytes1); //写后刷新 fos.flush();; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } FileReader---------------------------- 输出普通文本只能 //创建字符输入流 FileReader reader = null; try { reader = new FileReader("Myfile"); //使用char数组一次读取4个字符 char[] chars = new char[4]; int readCount = 0; while((readCount = reader.read(chars)) != -1){ System.out.print(new String(chars,0,readCount)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } FileWriter(与FileOutputStream同理)-------------------------------- BufferedReader--------------------------------------------------- 使用这个流不需要自定义char,byte数组,自带缓冲 /这里没有使用try{}catch语句,实际情况应该使用 FileReader fr = new FileReader("Myfile"); //需要传一个流//被传进去的叫做节点流//接收的流叫做包装流/处理流 //并且这个构造方法只能传字符流 BufferedReader br = new BufferedReader(fr); //这个方法一次可以读一行(不带换行符),如果读到最后没有元素则返回null String s= br.readLine(); System.out.println(s); //使用循环读文件 String read = null; while((read = br.readLine())!=null){ System.out.println(read); } //读完关闭最外层的流即可 br.close(); BufferedWriter------------------------- //带有缓冲区的字符输出流通过转换流把字节输出流变成字符输入流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Myfile"))); bw.write("hello"); bw.write("\n"); bw.write("world"); bw.write("\n"); bw.write("!!"); bw.flush(); bw.close(); BufferedInputStream(与BufferedReader同理)----------------------- BufferedOutputStream(与BufferedWriter同理)---------------------- InputStreamReader--------------------- //字节流可以通过转换流变成字符流 //在此程序种InputStreamReader也是节点流,BufferedReader是包装流 //字节输入流 FileInputStream fis = new FileInputStream("Myfile"); //转换流 InputStreamReader isr = new InputStreamReader(fis); //缓冲流 BufferedReader br = new BufferedReader(isr); String read = null; while((read = br.readLine())!=null){ System.out.println(read); } //读完关闭最外层的流即可 br.close(); --------- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("Myfile"))); String read = null; while((read = br.readLine())!=null){ System.out.println(read); } br.close(); OutputStreamWriter------------------------------ //带有缓冲区的字符输出流通过转换流把字节输出流变成字符输入流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Myfile"))); bw.write("hello"); bw.write("\n"); bw.write("world"); bw.write("\n"); bw.write("!!"); bw.flush(); bw.close(); ---------------以上为前10个---------------------- DataOutPutStream-DataInputStream------------------------- //创建数据专属输出流,创建出来的文件不能用记事本打开,且会将数据的数据类型一并写入 DataOutputStream dis = new DataOutputStream(new FileOutputStream("datafile")); int i = 1; byte b = 100; short s = 200; long l = 300; double d = 3.14; float f = 3.0F; boolean o = true; char c = 'a'; //写 dis.writeInt(i); dis.writeByte(b); dis.writeShort(s); dis.writeLong(l); dis.writeDouble(d); dis.writeFloat(f); dis.writeBoolean(o); dis.writeChar(c); //只能使用DataInputStream来读且需要知道顺序 DataInputStream dos = new DataInputStream(new FileInputStream("datafile")); System.out.println(dos.readInt()); System.out.println(dos.readByte()); System.out.println(dos.readShort()); System.out.println(dos.readLong()); System.out.println(dos.readDouble()); System.out.println(dos.readFloat()); System.out.println(dos.readBoolean()); System.out.println(dos.readChar()); PrintWriter------------------------------------------ PrintStream------------------------------------------ //PrintStream,可以把sout分开写,且标准输出流不需要手动关闭 PrintStream ps = System.out; ps.println(13); ps.println("zhangsan"); //可以利用PrintStream改变输出方向 //创建标准输出流,参数是传一个输出流,默认路径在Project工程下 PrintStream printStream = new PrintStream(new FileOutputStream("PrintStreamTest")); //使用SetOut()方法,将默认输出方向改为PrintStreamTest System.setOut(printStream); System.out.println("zhagnsan"); System.out.println("lisi"); System.out.println("wanger"); System.out.println("mazi"); //可以利用此方法写成日志工具 File---------------------------------------------- //创建File对象 File f = new File("D:\\z"); //如果上述文件不存在就以文件的形式创建出来 if (!f.exists()){ f.createNewFile(); } //如果上述文件不存在就以目录的方式创建出来,可以创建多重目录 if (!f.exists()){ f.mkdir();//单独一个文件 f.mkdirs();//多重目录 } //获取文件的父路径(两种) String s = f.getParent(); File f1 = f.getParentFile(); //获取绝对路径 f.getAbsolutePath(); //获取文件名 f.getName(); //判断是否是目录 f.isDirectory(); //判断是否是文件 f.isFile(); //获取文件以后一次修改时间 long haomiao = f.lastModified(); //转换成日期 Date time = new Date(haomiao); SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String s1 = sd.format(time); System.out.println(s1); //获取文件大小 f.length(); //获取当前目录下的所有子文件 File file = new File("D:\\游戏"); File[] files = file.listFiles(); for (File file1 : files) { System.out.println(file.getAbsolutePath()); //获取名字 System.out.println(file1.getName()); } ObjectOutputStream(序列化)--------------------------------- //参与序列化与反序列化的类需要实现Serializable接口,接口无代码,只是一个标志性接口 //java虚拟机看到类实现这个接口之后会自动生成一个序列化版本号 //如果不想让某个属性序列化使用transient(游离的,不参与序列化)关键字修饰 transient int age; class Student implements Serializable{} ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Myfile")); Student s = new Student(); oos.writeObject(s); -------------- //可以利用集合序列化多个对象(集合实现了Serializable接口) List<Student> list = new ArrayList<>(); list.add(new Student(21)); list.add(new Student(25)); list.add(new Student(23)); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Myflie")); //序列化集合 oos.writeObject(list); oos.flush(); //反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Mylife")); //Object o = ois.readObject(); //因为返回的是list集合,直接强转成list List<Student>list1 = (List<Student>)ois.readObject(); for (Student student:list1) { System.out.println(student); } oos.close(); ObjectInputStream(反序列化)-------------------------------- //参与序列化与反序列化的类需要实现Serializable接口,接口无代码,只是一个标志性接口 //java虚拟机看到类实现这个接口之后会自动生成一个序列化版本号 java种先用类名区分类,如果类名不一样,就不是一个类,如果类名一样再按照序列化版本号区分 但是后续不能修改代码,所以不建议自动生成序列化版本号(手动写出来后续可以改代码) 建议将序列化版本号手动写出来(String等从出生到如今使用的都是同一个序列化版本号) private static final long serialVersionUID = 534534534L;//版本号应该写成全球唯一的 //创建反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Myfile")); //读文件,就调用Object的toString方法,因此需要重写toString方法 Object o = ois.readObject(); System.out.println(o); ois.close(); IO+Properties(配置文件)---------------------------------------------- //Io+Properties的联合使用 //Properties是Map集合,key和value都是String //如何将Usertest文件加载到properties对象中 //可以利用这个动态获取文件(称为属性配置文件,规范是以properties结尾) //配置文件中#是注释,key相同,value会覆盖,最号不要使用空格 //新建输入流 FileReader fis = new FileReader("Usertest"); Properties ps = new Properties(); //调用Properties的load()方法加载到Map中 ps.load(fis);//字符字节流都支持,其中等号左边是key,右边是value,不需要手动截取 //调用方法得到value String username = ps.getProperty("username"); System.out.println(username); String password = ps.getProperty("password"); System.out.println(password);
IO流,IO与Properties的联合使用
于 2022-02-09 11:17:16 首次发布