秃头星人进化记(IO流学习总结)

Agnes ·
更新时间:2024-11-13
· 969 次阅读

IO流.学习笔记.总结开始基本概念File类(*****)*构造方法**常用方法*字节流(*****)字符流(*****)处理流(*****)关闭流(***)打印流(***)其他流(**)1:字节数组 节点流2:基本数据类型+String 保留数据+类型3:引用类型(对象)保留数据类型结束... 开始

(以下内容为听网课学习的总结见解,若有bug还请包涵指教,)
IO流说白了就是像在搬家,从老家(源头)搬到新家(目的地),当然你绝对不会把整栋房子地基平移过去,你会叫搬家公司或者自个把家具等重要的东西一点点运到新家,就相当于数据被当成无结构的字节或字符序列,以流的形式传递,进行输入输出…
注(*代表星级)

基本概念

流的意思:流动,从一端移动到另一端,源头与目的地
程序与文件|数组|网络连接|数据库,以程序为中心
流的方向:
输入流inputStream Reader
输出流outputSream writer
处理数据单元(节点流):
字节流:二进制,可以一切文件包括纯文本doc音频视频等
字符流:文本文件,只能处理纯文本
功能不同:
节点流:可以直接从数据源或目的地读写数据
处理流:不直接连接到数据源或目的地,是处理流的流,通过对其他的处理提高程序的性能 ,就相当于对节点流的修饰。

File类(*****) 构造方法

File(String pathname)这个pathname就是指路径 也是最常用的
例如:`File src = new File(“D:/1.txt”);
File (String parent,String child)这就相当于把上面那个肢解了
例如:

String parentPath="D:/"; String name="1.txt"; File src=new File(parentPath, name) ;

这里值得注意的是路径表示有三种:

//路径表示形式 String path1="‪D:\\1.txt"; String path2="‪D:"+File.separator+"1.txt";//中间这个separator是名称分隔符“/”;而pathSeparator则是路径分隔符“;” String path3="‪D:/1.txt";

注意:路径名称不能直接复制电脑上的,D:\1.txt 这样会报错1
报错1

常用方法

getName() 返回文件或目录的名称
getPath() 返回路径名字字符串
isFile() 判断是否是一个文件
isDirectory()判断是否是一个目录

import java.io.File; import java.io.IOException; public class Demo03 { public static void main(String[] args) throws IOException { File src = new File("D:/1.txt"); System.out.println(src.getName());//返回名称 System.out.println(src.getPath());//如果是绝对路径的话返回完整路径,否则相对路径 System.out.println(src.getAbsolutePath());//返回绝对路径 System.out.println(src.getParent());//返回上一级目录 //System.out.println(src.get); System.out.println("文件是否存在"+src.exists()); System.out.println("是否可读可写"+src.canWrite()+src.canRead()); System.out.println(""); if(src.isFile()) { System.out.println("文件");//存在 }else { System.out.println("文件夹");//不存在 } //创建新的文件 ,要是已经有了就不新建了 返回失败 File src2=new File("D:/1.txt"); if(!src2.exists()) { boolean flog=src2.createNewFile(); System.out.println(flog?"成功":"失败"); } //删除文件 boolean flog=src2.delete(); System.out.println(flog?"成功":"失败"); }

运行结果:
在这里插入图片描述

字节流(*****)

一:读取文件
1:建立联系 File对象 源头(老家)
2:选择流 文件输入流 inputstream Fileinputstream
3:操作: byte[] x=new byte[10] + read()+读取大小
输出
4:释放资源:关闭 .close()

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; //读取文件 public class inputstream { public static void main(String[] args) { //1:建立联系 File对象 File src=new File("D:/1.txt"); //2:选择流 InputStream is=null; try { is=new FileInputStream(src); //3:操作不断读取,缓冲数组 byte[] x=new byte[1024]; int cr=0;//接收实际读取大小 try { //循环读取 while(-1!=(cr=is.read(x))) { String y=new String(x, 0, cr); System.out.println(y); } } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("文件不存在"); } } catch (IOException e) { e.printStackTrace(); System.out.println("读取文件失败"); }finally { if(is!=null) { try { is.close(); } catch (IOException e) { System.out.println("无法关闭"); e.printStackTrace(); } } } } }

二:写出文件
1:建立联系 File对象 目的地(新家)
2:选择流 文件输出流 outputstream Fileoutputstream
3:操作: write()+flush
输出
4:释放资源:关闭 .close()

//写入数据 public class outputstream { public static void main(String[] args) { //1:建立连接 file 目的地 File src= new File("D:/1.txt"); //2:选择流 OutputStream os=null; //以追加形式写出文件 try { os=new FileOutputStream(src,true);//注意了 这里的true是说 你第一次写入数据后 如果再执行若你不写true或者写flase就会覆盖上一次的结果,但是若是true则会追加,在后面继续添加 //3:操作 String x="1234567你好呀"; //字符串转字节数组 byte[] data=x.getBytes(); try { os.write(data, 0, data.length); os.flush();//强制刷新出去 } catch (IOException e) { System.out.println("文件写出失败"); e.printStackTrace(); } } catch (FileNotFoundException e) { System.out.println("文件不存在"); e.printStackTrace(); }finally { if(os!=null) { try { os.close(); } catch (IOException e) { System.out.println("关闭失败"); e.printStackTrace(); } } } } }

三:文件|文件夹的拷贝 程序为桥梁,就是把读取的内容拷贝到写出的目的地里面,两个不同的路径,也就是把前两个结合起来了
1:建立联系 File对象 源头和目的地
2:选择流 文件输入流 inputstream Fileinputstream 文件输出流 outputstream Fileoutputstream
3:操作: byte[] x=new byte[10] + read()+读取大小
write()+flush

4:释放资源:关闭 .close()
文件的拷贝

//复制文件 就是将前两个合并 先读取后合并 public class copy { public static void main(String[] args) throws IOException { String srcpath="D:/1.JPG"; String destpath="D:/4.JPG"; try { copyfile(srcpath, destpath); } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("404NotFound"); }catch (IOException e) { e.printStackTrace(); System.out.println("复制失败,关闭流失败"); } } public static void copyfile(String srcpath,String destpath) throws IOException{ File src=new File(srcpath); File dest= new File(destpath); if(!src.isFile()) { System.out.println("只能拷贝文件"); } InputStream is=null; is=new FileInputStream(src); OutputStream os=null; os=new FileOutputStream(dest,true); //读取1.txt(必须存在且为文件) byte[] x=new byte[1024]; int cr=0; while(-1!=(cr=is.read(x))) { os.write(x,0,cr); } //2:copy 将上面读取的写入到3.txt(可以不存在) os.flush();//强制刷新出去 os.close(); is.close(); } }

文件夹的拷贝(如果将父目录复制到子目录会报错):

//复制文件夹 public class copydir { public static void main(String[] args) throws IOException { String srcpath="G:/1"; String destpath="F:/1"; File src=new File(srcpath); File dest=new File(destpath); if(src.isDirectory()) { dest=new File(destpath,src.getName()); } copyDirDetail(src, dest); } public static void copyDirDetail(File src,File dest) throws IOException { if(src.isFile()) {//如果是文件 则直接读取复制 FileUtil.copyfile(src, dest); }else if(src.isDirectory()) {//如果是文件夹 //确保目标文件夹存在 dest.mkdirs(); //这里有一个bug解决 if(dest.getAbsolutePath().contains(src.getAbsolutePath())) { System.out.println("父目录不能拷贝到子目录中"); return; } //获取下一级目录文件 for(File sub:src.listFiles( )) { copyDirDetail(sub, new File(dest,sub.getName())); } } } } 字符流(*****) 字符流(只能处理纯文本,全部为可见字符 .txt .html)

一:纯文本读取
1:建立联系
2:选择流 Reader FlieReader
3: 执行操作
4:关闭流

//字符流读取 public class reader { public static void main(String[] args) { //建立连接 String path="D:/1.txt"; File src=new File(path); //选择流 Reader r=null; try { r=new FileReader(src); char[] cr=new char[1024];//这里不是byte 是char int len=0; try { while(-1!=(len=r.read(cr))) { String s=new String(cr, 0, len); System.out.println(s); } } catch (IOException e) { System.out.println("文件读取失败"); e.printStackTrace(); } } catch (FileNotFoundException e) { System.out.println("文件找不到404"); e.printStackTrace(); }finally { if(r!=null) { try { r.close(); } catch (IOException e) { System.out.println("关闭流失败"); e.printStackTrace(); } } } } }

二:纯文本写出
1:建立联系
2:选择流
3:读取write(字符数组,0,长度)+flush
write(字符串)
write(字符|字符串)
4:关闭流

import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; //纯文本写出 public class writer { public static void main(String[] args) { String path="D:/1.txt"; File dest =new File(path); Writer wt=null; try { wt=new FileWriter(dest,true); String s="java"; wt.write(s); wt.append("123"); wt.flush(); } catch (IOException e) { System.out.println("404"); e.printStackTrace(); } } }

三:纯文本拷贝:

import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; //只能拷贝纯文本 public class copytxt { public static void main(String[] args) { String srcpath="D:/1.txt"; String destpath="D:/4.txt"; try { copy(srcpath,destpath); } catch (IOException e) { System.out.println("拷贝失败"); e.printStackTrace(); } } public static void copy(String srcpath,String destpath) throws IOException { File src=new File(srcpath); File dest=new File(destpath); Reader r=null; r=new FileReader(src); Writer w=null; w=new FileWriter(dest,true); char[] c=new char[1024]; int len=0; while(-1!=(len=r.read(c))) { w.write(c, 0, len); w.flush(); } r.close(); w.close(); } } 处理流(*****) 处理流:增强性能、提供性能,节点流之上

一:缓冲流
1:字节缓冲流
BufferedinputStream
BufferedoutputStream
没有新增的方法

// InputStream is=null; // is=new FileInputStream(src); // OutputStream os=null; // os=new FileOutputStream(dest,true); InputStream is=null; is=new BufferedInputStream(new FileInputStream(src)); OutputStream os=null; os=new BufferedOutputStream(new FileOutputStream(src)); /* * 注意这里加了缓冲流 */

2:字符缓冲流
Bufferedreader
Bufferedwriter
有新增的方法

//注意这里加了缓冲流,新增了两个方法 r=new BufferedReader(new FileReader(src)); BufferedWriter w=null; w=new BufferedWriter(new FileWriter(dest,true)); // char[] c=new char[1024]; // int len=0; // while(-1!=(len=r.read(c))) { // // w.write(c, 0, len); // w.flush(); // // } String line=null; while(null!=(line=r.readLine())) { w.write(line); w.newLine(); w.flush(); }

二:转换流
字节流(byte)转为字符流(char) 处理乱码(编码集,解码集)
1:编码与解码的概念
编码 字符 —>编码字符集—>二进制
解码 二进制 —>解码字符集—> 字符
2:乱码问题:
编码和解码的字符集不统一;字节缺少,长度丢失
例如:

import java.io.UnsupportedEncodingException; public class conver { public static void main(String[] args) throws UnsupportedEncodingException { //解码 String str="你好呀";//gbk字符集 //编码 char---byte byte[] data=str.getBytes(); //默认情况下编码与解码字符集相同 System.out.println(new String(data)); //不相同的情况 try { byte[] data2 =str.getBytes("utf-8"); System.out.println(data2); } catch (UnsupportedEncodingException e) { System.out.println("字符集不相同"); e.printStackTrace(); } //修改方法 //编码 byte[] data3 = str.getBytes("utf-8"); //解码 System.out.println( new String(data3,"utf-8")); //就是这俩地都得设置成一样的 //还有一种错误乱码的情况就是字节丢失缺少 String str2="你好呀"; byte[] data4=str2.getBytes(); System.out.println(new String(data4,0,3)); } }

3:转换流:字节转为字符
输出流OutputStreamWriter 编码
输入流InputStreamReader 解码

BufferedReader r=null; r=new BufferedReader(new InputStreamReader( new FileInputStream(src),"utf-8")); BufferedWriter w=null; w=new BufferedWriter(new OutputStreamWriter( new FileOutputStream(dest),"utf-8")); 关闭流(***)

由于每次都要.close(),太麻烦了
因此编写工具类,实现关闭功能

public class FileUtil { /*一: * 工具类关闭流 * 可变参数:... 只能放在形参的最后一个位置,处理方式与数组一致 */ public static void close( Closeable ... io) { for(Closeable temp:io) { if(null!=temp) { try { temp.close(); } catch (IOException e) { e.printStackTrace(); } } } }//所以在is.close(); os.close(); 这样的关闭方法中 可以用FileUtil.close(is,os); /*二: * 使用泛型方法 */ public static void closseall(T ... io) { for(Closeable temp:io) { if(null!=temp) { try { temp.close(); } catch (IOException e) { e.printStackTrace(); } } } }//所以在is.close(); os.close(); 这样的关闭方法中 可以用FileUtil.closseall(is,os); } /*三: * try {声明}{操作}这是Jdk1.7以后新出的 */ 打印流(***) PrintStream

一:先了解一下这三个常量

1:system.in 输入流 默认键盘输入 2: system.out 输出流 默认控制台输出 ,一般用于测试或者写日志 , 在system 源码中可以看到 控制台的地址是 FileDescriptor.in/on/err 3: system.err 错误输出流 会和out是不一样的颜色 运行一下就看出来了 如果想要打印输出外面的文件就涉及到 -->重定向 就是说用上面的控制文件 而不是输出输入在控制台 因此就可用到setErr() setIn() setOut()
看下面演示代码 public class Systemio { public static void main(String[] args) throws FileNotFoundException { System.out.println("out"); System.err.println("err"); //键盘输入 //Scanner sc=new Scanner(System.in);也就是下面这个 // InputStream is=System.in; // Scanner sc=new Scanner(is); // System.out.println(sc.nextLine()); //text2(); //控制台--->文件 System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("D:/5.txt",true)),true));//第一个true早就知道了是每次输入都不覆盖的意思(每次输入追加);所以这里的第二个true 就是让他自动刷新,要不然没内容 System.out.println("aaaaaaaa");//此时运行你会发现5.txt里面木有东西 是因为没有刷新 .flush() //回到控制台 System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true)); System.out.println("back......."); } public static void text2() throws FileNotFoundException { //也可以从文件输出输入 InputStream is2=System.in; is2=new BufferedInputStream(new FileInputStream("D:/5.txt")); Scanner sc2=new Scanner(is2); System.out.println("请输入:"); System.out.println(sc2.nextLine()); } }

二:PrintStream打印输出流练习:

public class PrintStreamio { public static void main(String[] args) throws FileNotFoundException { System.out.println("text"); PrintStream ps=System.out; ps.println("sjw");//这就是把上面的分解了 //输出到文件 File src=new File("D:/5.txt"); ps=new PrintStream(new BufferedOutputStream(new FileOutputStream(src))); ps.println("123456"); FileUtil.closseall(ps);//看这个就调用了咱们的工具类 关闭流方法 } } 其他流(**)

一:节点流

1:字节数组 节点流 输入流:ByteArrayInputStream read(byte[]b,int off,int len)+close() 输出流:ByteArrayInputStream write(byte[]b,int off,int len)+toByteArray() 不要使用多态 文件---程序---字节数组 文件输入流 字节数组输出流 字节数组---程序---文件 字节数组输入流 文件输出流 public class byteArrayfile { public static void main(String[] args) throws IOException { byte[] data=getBytesFromFile("D:/1.jpg"); toFileFromByteArray(data, "D:/7.jpg"); } /* * 文件---程序---字节数组 文件输入流 字节数组输出流 */ public static byte[] getBytesFromFile(String path) throws IOException { File src=new File(path); byte[] dest=null; InputStream is=new BufferedInputStream(new FileInputStream(src)); //字节数组输出流不能使用多态 ByteArrayOutputStream bos= new ByteArrayOutputStream() ; byte[] flush=new byte[1024]; int len=0; while(-1!=(len=is.read(flush))){ dest=bos.toByteArray();//转为字节数组 } return dest; } /* * 字节数组---程序---文件 字节数组输入流 文件输出流 */ public static void toFileFromByteArray(byte[] src,String destPath) throws IOException { //创建源 //目的地 File dest =new File(destPath); //选择流 //字节数组输入流 InputStream is=new BufferedInputStream(new ByteArrayInputStream(src)); //文件输出流 OutputStream os=new BufferedOutputStream(new FileOutputStream(dest)); //操作不断读取数组 byte[] by=new byte[1024]; int len=0; while(-1!=(len=is.read(by))) { os.write(by,0,len); } os.flush(); os.close(); } }

二:处理流

2:基本数据类型+String 保留数据+类型 输出流:DataInputStream readxxx 输入流:DataOutputStream writexxx 一般可以结合节点数组使用 注意:所读取的数据类型和顺序必须与目标相同 若不同会报错*EOFException* 意思是说已经读取到末尾 没读取到你指定类型的数据 public class Data { public static void main(String[] args) throws IOException { datain("D:/7.txt"); //dataout("D:/7.txt"); } //读取 public static void datain(String srcpath) throws IOException { //创建源 File src=new File(srcpath); //选择流 DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream(src))); //操作读取的顺序与写出一致,必须存在才能读取 dis.readDouble(); dis.readInt(); dis.readUTF(); System.out.println(dis.readUTF()); dis.close(); } public static void dataout(String destpath) throws IOException { Double y=1.2; int z=100; String x="你好"; File dest=new File(destpath); DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest))); dos.writeDouble(y); dos.writeInt(z); dos.writeUTF(x); dos.flush(); dos.close(); } } 3:引用类型(对象)保留数据类型

反序列化:输入流 ObjectInputStream readObject
序列化: 输出流:ObjectOutputStream writeObject
先序列化后反序列化 反序列化必须与序列化顺序一致
java.io.NotSerializableException报错 解决方法implements java.io.Serializable
不是所有的属性都需要序列化 若加了transient 此属性就不会被序列化
注意 数组也可以序列化 跟对象一样

```java public class Objectio { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { //seri("D:/4.txt"); datain("D:/4.txt"); } //反序列化 public static void datain(String srcpath) throws IOException, ClassNotFoundException { //创建源 File src=new File(srcpath); //选择流 ObjectInputStream dis=new ObjectInputStream(new BufferedInputStream(new FileInputStream(src))); Object obj=dis.readObject(); if(obj instanceof Demo4 ) { Demo4 de=(Demo4 )obj; System.out.println(de.getName());//他输出来不会是你好,会是null, 因为他加了transient没有序列化 System.out.println(de.getx()); } obj=dis.readObject(); int[] arr=(int[])obj; System.out.println(Arrays.toString(arr)); dis.close(); } //序列化 public static void seri(String destPath) throws FileNotFoundException, IOException { Demo4 de=new Demo4 ("你好",100000.2); int[] arr= {1,2,3}; File dest=new File(destPath); ObjectOutputStream dos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dest))); dos.writeObject(de); dos.writeObject(arr); dos.flush(); dos.close(); } }

附:

public class Demo4 implements java.io.Serializable{ //不需要序列化就加transient private transient String name; private double x; public Demo4() { } public Demo4(String name,double x) { super(); this.name=name; this.x=x; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getx() { return x; } public void setx(double x) { this.x = x; } } 结束…

此次学习是对IO流的初步理解,具体的深水区会慢慢探索,若文章笔记内容有错,还请提出指教。。。


作者:fluoxetine~



io流 进化 学习 io

需要 登录 后方可回复, 如果你还没有账号请 注册新账号