JAVASE之IO流 Myth丶恋晨 2022-07-16 11:21 157阅读 0赞 我觉得java的io流就是管道和水 ## java的IO流 ## 输入,输出流 输入流用于 从外界获取数据 操作是读取 输出流用于 向外界发送数据 操作时写 ![这里写图片描述][20161017092042335] 处理流称为高级流 节点流称为低级流 **节点流 的地点很明确** **高级流通常都是处理另一个流,独立存在没有意义,为了简化读写操作** 一般都是操作高级流 高级流的参数是传入另一个流 **还分为字节流和字符流** InputStream和OutputSream是抽象类。是所有字节流字符流的父类 InputStream中定义了 int rean()一个字节 和 read(byte\[\] d) OutputStream类型 ## 低级流 ## 文件流 FileIntputStream 和 FileOutputStream 先Out 传入与Fiel对象或者路径 输出流只能做写操作 ## FileInputStream ## /** * FileInputStream * 节点流 * 用于从文件中读取字节的流 * @author Administrator * */ public class FileIntputStreamDemo2 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("c:/asdasd.txt"); int i = fis.read(); System.out.println(i); byte[] buf = new byte[9]; int len = fis.read(buf); String str = new String(buf); System.out.println(str); } } ## FileOutputStream ## /** * FileOutputStream * 节点流 * 用于向文件中写字节的流 * @author Administrator * */ public class FileOutputStreamDemo1 { public static void main(String[] args) throws InterruptedException, IOException { FileOutputStream fos = new FileOutputStream("c:/asdasd.txt"); fos.write(97); String str ="asdasd666"; byte[] buf = str.getBytes(); fos.write(buf); fos.close(); } } ## 查看RandomAccessFile的指针位置 ## /** * 查看RandomAccessFile的指针位置 * RAF总是格机当前指针所指向的位置进行读或者写操作的 * 并且每次读写后,指针自动向后移动 * @author Administrator * */ public class RandomAccessFileDemo { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("c:/qweqwe.txt","rw"); //获取当前指着的位置 long p =raf.getFilePointer(); System.out.println(p);//0 raf.write(97); System.out.println(raf.getFilePointer());//1 raf.writeInt(1);//连续写4个字节 System.out.println(raf.getFilePointer()); //读 //RandomAccessFile总是在指针当前位置读写 //所有现在指针的位置是在文件末尾。把指针移回来 /* * 若想从文件的某个地方读取字节 * 需要先将指针移动到这个位置 */ raf.seek(0); int n = raf.read(); System.out.println(n); System.out.println(raf.getFilePointer());//1 raf.close(); } } ## int skipBytes(int n) ## /** * int skipBytes(int n) * 该方法会尝试跳过n个字节,返回值为实际跳过的字节数 * @author Administrator * */ public class RandomAccessFileDemo2 { public static void main(String[] args) throws IOException { RandomAccessFile raf = new RandomAccessFile("c:/qweqwe.txt","r"); //跳过第一个字节 long p =raf.skipBytes(1); int i = raf.readInt(); System.out.println(i); } } ## 注意追加写操作 ## /** * 使用文件字节输出流对已有文件进行写操作的注意事项 * 追加写操作 * @author Administrator */ public class FosDemo2 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("c:/asdasd.txt",true); //会清除之前的!!! fos.write(99); //追加的话就在参数中加个true,不追加就不写或者false fos.close(); } } ## 使用文件的字节输入输出流实现文件的复制 ## /** * 使用文件的字节输入输出流实现文件的复制 * @author Administrator * */ public class IOCopyDemo { public static void main(String[] args) throws InterruptedException, IOException { FileInputStream fis = new FileInputStream("c:/asdasd.txt"); FileOutputStream fos = new FileOutputStream("c:/asdasdcopy.txt"); //使用缓冲区 int len=-1; //定义个byte[] 缓冲区,然后循环读直到文件结束就是读出来-1 byte[] buf = new byte[10240]; while((len=fis.read(buf))!=-1){ //从缓冲区写,从0开始,长度为实际长度len fos.write(buf,0,len); } System.out.println("复制完毕!"); } } ## 删除文件或目录 ## /** * 删除文件或目录 *在方法中所有情况都考虑到 *总有到头的时候,这个就是目录下没有目录和文件了。 * @author Administrator * */ public class shanchudemo { public static void main(String[] args) { /* * 主要是删除目录,要删除目录就要删除子目录和文件 * 用递归 */ File file = new File("c:/a"); deleteFile(file); System.out.println("删除完成!"); } //传入File对象,然后将其删除 public static void deleteFile(File file){ //看看是否是目录,不是目录就进不去if,就最后直接删除 if(file.isDirectory()){ //如果是目录就要看是否还有子项 File[] subs = file.listFiles(); //先删除所有子项 for(File sub:subs){ //这个方法就是删除文件或者目录,就是一直去找,是文件的就删除,不是就找。 deleteFile(sub); } } file.delete(); } } ## 缓冲流 ## 这一对缓冲流是高级流 组合不同高级流 ## 缓冲输出流写出数据的注意事项 ## /** * 缓冲输出流写出数据的注意事项 * @author Administrator * */ public class BosDemo1 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("c:/zxczxc.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); String str = "6666的"; byte[] buf = str.getBytes(); bos.write(buf); //flush()强制将当前缓冲区流中的缓冲区中的数据全部写出,无论是否装满 bos.flush(); //close中会把缓冲区中数据全部写出后再关闭 //只要关闭最外层就会自动把里面的关了就是用的flush bos.close(); } } ## 使用缓冲流加快读写效率 ## /** * 使用缓冲流加快读写效率 * 相当于外面套个壳,只对外面操作就可以了。 * @author Administrator *一次性尽可能多的读取,然后取出来。一次给完,再去取一次。 *出去的话就是一次性的装,然后满了去输出。空了再回来。 */ public class CopyDemo2 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("c:/1.gz"); //使用缓冲流加快,就是把基本的节点流外面套个高级缓冲流 BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("c:/1copy.gz"); BufferedOutputStream bos = new BufferedOutputStream(fos); //于是下面的 int d=-1; while((d=bis.read())!=-1){ bos.write(d); } //只关最外层的就行了。就不用关4个 bis.close(); bos.close(); System.out.println("复制完成!"); } } ## 字符输入流 ## /** * InputStreamReader * 字符输入流 * 用于读取字符数据的流 * @author Administrator * */ public class ISRDemo1 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("c:/qaz.txt"); InputStreamReader isr = new InputStreamReader(fis); int d=-1; while((d=isr.read())!=-1){ char c = (char)d; System.out.println(c); } } } ## 字符输出流 ## /** * OutputStreamWriter * 字符输出流,以字符为单位写出数据 * 字符流只用于读写字符数据 * @author Administrator * */ public class OSWDemo1 { public static void main(String[] args) throws IOException { /* * 想文件写出文本数据(写字符串) * 1、向文件中写数据(FileOutputStream) * 2、写的是文本数据() * OutputStreamWriter的特点是可以将给定的字符串按照特定的字符集转换为直接后写出 * */ FileOutputStream fos = new FileOutputStream("c:/qaz.txt"); //高级字符流,操作,直接就可以写! OutputStreamWriter osw = new OutputStreamWriter(fos); osw.write("6的一批"); osw.close(); } } ## 使用字符流复制文本文件 ## /** * 使用字符流复制文本文件 * 只能复制文本文件 * @author Administrator * */ public class CopyDemo3 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("c:/student2"); FileOutputStream fos = new FileOutputStream("c:/studen2.txt"); InputStreamReader isr = new InputStreamReader(fis); OutputStreamWriter osw = new OutputStreamWriter(fos); int d=-1; while((d=isr.read())!=-1){ osw.write(d); } System.out.println("复制完成!"); isr.close(); osw.close(); } } ## 缓冲字符输入流 ## 要求传入字符流。 首先用 FileInputStream 来打开文件,但是是低级流,要将其转换为字符流才能给BufferedReader操作,那么就用InputStreamReader来转换为字符流 **需要注意的是它的 readLine()读取文件没有数据返回null** /** * BufferedReader * 缓冲字符输入流 * 可以以行为单位读取字符串 * @author Administrator */ public class BufferReaderDemo { public static void main(String[] args) throws IOException { //这个是字符流 FileInputStream fis = new FileInputStream("c:/pw.txt"); //用InputStreamReader转换为字符流 InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); BufferedReader br = new BufferedReader(isr); /*String readLine() * 若返回的字符串是null就是文件末尾了 * 读取到换行符为止,将之前的一行字符串返回 * 若该方法返回的字符串为null,说明没有数据可读了 */ String str = null; while( (str = br.readLine())!=null){ System.out.println(str); } } } ## 缓冲字符输出流,带有自动行刷新 ## /** * PrintWriter * 缓冲字符输出流,带有自动行刷新 * 可以以行为单位写出字符串 * @author Administrator * */ public class PrintWriteDemo1 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("c:/pw.txt"); OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8"); PrintWriter pw = new PrintWriter(osw,true); pw.println("我爱你啊"); pw.println("我不爱你啊"); pw.close(); } } 很快,但是这么的不能改变字符集 若要修改字符集的话: FileOutputStream fos = new FileOutputStream("c:/pw.txt"); **InputStreamReader还有个重要的功能就是可以设置字符集!!!** ## 序列化 ## 写对象啊~ 把对象变成字节,写入硬盘。 写字符串到硬盘中,要经历两件事: 1、将字符串转换成一组字节 2、将一组字节写入硬盘做长久保存 将一个特定的数据结构转换为一组字节的过程,称之为序列化 将数据写入硬盘做长久保存的过程称之为持久化 序列化与反序列一般用于: 1、传输 2、保存 先实例化一个对象 然后用FileOutputStream fos 操作 文件路径 加上 高级流 ObjectOutputStream oos = new …(fos) //可以将给定的对象转换为一组字节后写出 oos.writeObject(实例化的那个对象); ![这里写图片描述][20161017094253937] 前提是这个对象是可以被序列化的 让他可以拆 就在那个类实现个接口 implements Serializble\{ 不需要重写任何方法。。 \} 读取序列化的对象 是ObjectInputStream 将一组字节转换为对应的对象 用于对象的反序列化 先用 FileInputStream fos操作文件 然后传给反序列化流 ObjectInputStream ois ois.readObject(); 将他强制转换为对应的对象类型 定义属性的时候 加上这个就不会被序列化了。 ## transient ## 有可能在序列化后,把原来类的属性进行了更改,删除或者增加了。那么在反序列化就会出现问题。 在类中属性加个 1L serialVersionUID =1L; 然后删除个属性,在反序列化不会出现问题,因为version版本都是1L就不会报错 类修改后,版本号不变,就尽量会兼容,版本后改变就会报错 ## 小结: ## 也就是说 所有的InputStream和OutputStream的就是字节流。 所有的Reader和Writer的就是字符流 然后不同的子类名称加在他们的前面就是不同的功能延伸。 [20161017092042335]: /images/20220716/7ce2435bf89846f6b6b335e63c6ad15e.png [20161017094253937]: /images/20220716/bb543a30e85e4af4af9034a3331e6bcc.png
还没有评论,来说两句吧...