16IO流

I/O流

理解流
ATM机器,数据保存在内存中,一旦系统运行完毕,或者中途中断退出,当前操作的数据将全部消失,下次在进行访问数据已经丢失。

如果要将数据保存起来,要用流的操作,文件的操作

流的概念:java程序中当需要读取数据的时候,就会开启一个通向数据源的设备流,这个文件可以是文件、内存、网络资源。
获取数据:
程序====>硬盘文件
程序====>内存获取
程序====>网络资源

当我们程序要写入数据的时候,开启一个通往目的地的设备流。这个时候我们就可以将数据理解为“流”在管道中进行传输和流动

流的两个特征:
1.含有流质
2.具有方向
这两个特征正好符合计算机系统中数据传输的特征
流来抽象数据传递

方向:硬盘文件到程序(输入流) 程序到硬盘文件(输出流)

在程序中流的分类

java.io包提供了我们操作数据的各种流。流的分类(流质、方向)

  1. 按方向来分:
    1.输入流:从数据源读取到内存。inputStream、Reader对象代表输入流
    2.输出流:从内存将数据写入到数据源,outputStream、Writer

  2. 按照类型来分:
    1.字节流:传输的时候以byte为最小单位进行传递
    2.字符流:传输的时候以char为最小单位来进行传递

  3. 按照功能来分:
    1.节点流:节点流表示从一个特定的数据源读取数据、节点流一般直接操作文件、或者网络等提供的流。他们直接从文件读取数据、将数据直接写入到文件中,也称为低级流
    2.处理流:处理流不是直接连接在设备之上,而是建立在其他流之上,通过对数据的处理提供更强大的功能。处理流也称为高级流。
    高级流的好处:
    在低级流的基础之上,继续扩展和优化了功能。
    程序中操作的都是高级流。

    学习类:InputStream、OutputStream Reader、Writer都是抽象类。使用的是抽象类的子类。

file文件类的操作

java.io包提供的一个类,主要用于管理磁盘里的所有文件或者文件的目录,比如我们可以操作文件的大小、文件的名字、文件的类型,但唯一不能操作的是文件的内容

file类描述的是一个文件或者是文件夹。
该类出现的目的:封装file对象,提供各种文件操作方法,供我们开发过程中直接调用接口可以完成某些特定的功能(创建文件、删除文件、查看文件是否存在)
file.separator //分隔符
创建新的文件夹

File file = new File(路径\文件名)  //表示当前文件目录
	file.exists()  返回一个boolear值,判断文件是否存在
	File file = new File("C:\\software\\fileTest\\day17.txt");
	//判断文件是否存在。不存在创建一个
	if(!file.exists()){
		try {
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

file.getAbsolutePath() 返回文件路径
file.getParent() 得到父类路径
file.getName() 返回文件名字
创建一个文件
File file2 = new File(路径\文件名)
file2.mkdir()
file2.isDirectory() //判断当前路径是否是一个文件夹
file2.isFile() //判断是否是文件
file2.delete() //删除空文件夹或文件并返回一个布尔值,判断是否删除成功
file2.list(); // 列出当前文件下所有文件

String[] strs = file2.list();
for (String string : strs) {
	System.out.println(string);
}

File[] files = file2.listFiles();
for (File file : files) {
	System.out.println(file.getName()+"  "+file.length());
}
file2.renameTo()  //移动文件
File file2 = new File("C:\\software\\fileTest\\work\\out.txt");
File file3 = new File("C:\\software\\fileTest\\work\\new\\out.txt");
	
file2.renameTo(file3);

具体流的操作

操作流的步骤:
1.建立流,根据不同类型的数据选择不同的流的操作。
2.操作流,将数据读取到内存,或者将内存数据写入到数据源
3.关闭流,操作结束后,记得将流关闭,释放所有资源。
字节流
字节流以byte作为最小单位,字节流经常用于操作二进制的文件、图片、音频、视频。

  1. InputStream:
    FileInputStream:对二进制文件进行操作,数据源一般为磁盘,字节流
    PipedInputStream:主要针对线程管道
    FilterOutputStream:过度流,提供的子类非常重要,缓冲流,数据流
    BufferedInputStream:缓冲流
    DateInputStream:数据操作流
    LineNumberInputStream:表示程序读取哪一行,计数器
    ByteArrayOutPutStream:对内存缓冲区的数据进行读写操作,数据源是内存的字节数组
    SequenceInputStream:实现两个文件的合并
    StringBufferInputStream:用于操作字符串的流
    ObjectInputStream:用于操作内存中的对象

  2. BufferedInputStream:
    缓冲流:缓冲流一个高级流。套在响应节点流基础之上,对读写数据提供缓冲的功能,提高了读写效率,同时还增加了一些额外方法。
    缓冲区:
    byte[] by = new byte[1024];缓冲区,在内存空间开辟一个缓冲区域,读写现将数据放入缓冲区,减少磁盘的读写
    使用缓冲流:
    1.减少对磁盘的io操作
    2.提高数据读写效率

  3. DatetInputStream:
    数据流:提供一系列功能,读取的数据转化为一个byte Boolean long float
    InputStream in = new FileInputStream(“C:\software\fileTest\b.txt”);
    DataInputStream datain = new DataInputStream(in);

    byte s1 = datain.readByte();
    System.out.println(s1);
    boolean boo = datain.readBoolean();
    System.out.println(boo);
    char s3 = datain.readChar();
    System.out.println(s3);

    OutputStream out = new FileOutputStream(“C:\Users\Administrator\Desktop\My_java\day17.txt”);
    DataOutputStream dataout = new DataOutputStream(out);
    dataout.writeByte(12);
    dataout.writeInt(205);

  4. printWrite:打印流,在system系统输出就已经使用了

    OutputStream o = new FileOutputStream(“C:\software\fileTest\k.txt”);
    PrintStream out = new PrintStream(o);

    out.print(true);
    out.print(‘a’);
    out.print(“xiaowang”);

    o.close();
    out.close();

字符流
字符流是以字符为单位来进行传输的, char java 采用16位Unicode编码表示字符和字符串。字符流分为两种:
字符输入流:Reader
字符输出流:Writer
都是抽象类

字符集:就是规定了某个文字对应的二进制存放方式(编码)和某个二进制值代表了哪个文字(解码)的转换关系

字符编码:
计算机只能存放二进制的数据,我们要让他表示多种多样的数据,我们要对各种字符指定一个数字编码,这种编码就是编码集。
只有编码和解码的方式一致,才能正常显示

计算机中常用的编码:GBK、GB2312、utf-8、unicode编码,前三个支持中文
计算机中只保存字符对应的编码,计算机只需维持字符集清单,当读到这种编码的时候,就与清单中的字符匹配,显示出当前字符。
乱码的原因:编码和解码的编码集不一样。

  • Reader
    -InputerStreamReader:转换流,可以将字节流转换为字符流
    -FileReader
    -BufferReader:缓冲区流

  • Writer

    • OutputStreamWriter:字符输出流
    • BufferedWriter
      如何选择字符流和字节流:
      针对文件传输,一般选择字节流,比如:图片、音频、视频
      针对文本传输,一般选择字符流

    用字符流操作文本内容没问题,整体传输可以传递,用字符来操作文件可能字节丢失,文件打不开

对象的操作

-对象的序列化:将所有的object对象转化为byte为单位的内容传输到目的地(磁盘、网络空间)
-反序列化:将磁盘中的数据以byte为单位读取,转化为object对象放入内存。
创建对象:new 克隆 反序列化

序列化规范:
1.你要序列化的对象必须要实现Serializable接口,如果对象没有实现接口,序列化的时候抛出没有实现接口的异常。
2.静态变量和成员方法不可序列化
3.一个类要被序列化,该类可应用的对象也应该是可被序列化的,否则整个序列化的过程将失败
4.声明transient关键字可以控制当前属性不被序列化

-ObjectInputStream
(1)创建一个文件对象
File file = new File("C:\\software\\fileTest\\object.txt");

(2)创建流

ObjectInputStream objin = new ObjectInputStream(new FileInputStream(file));

(3)操作对象:反序列化

try {
	Object obj = objin.readObject();
	StudentBean stu = (StudentBean) obj;
	System.out.println(stu);
	System.out.println(stu.age);
} catch (ClassNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

(4)关闭

objin.close();

-ObjectOutputStream
(1)创建一个文件对象

File file = new File("C:\\software\\fileTest\\object.txt");

(2)创建一个流

OutputStream o = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(o);

(3)操作对象,写入到文件

ClassBean cb = new ClassBean(1,"wn46");
StudentBean stu = new StudentBean(1, "xiaowang",cb);
out.writeObject(stu);

(4)关闭流

out.close();

重复传输默认将以前数据覆盖,导致以前数据丢失
多对象操作

  1. 序列化

     (1)创建一个文件对象
         File file = new File("C:\\software\\fileTest\\object1.txt");
     (2)创建一个流   调用构造的时候,传递了一个boolean值 true表示:追加信息到文本, false覆盖
    
     FileOutputStream o = null;
     ObjectOutputStream out =null;
         if(file.exists()){
         	long index = 0;
         	o = new FileOutputStream(file,true);
         	out = new ObjectOutputStream(o);
         	//每次写对象到文件的时候,都会默认创建一个头信息,StreamHeader有4个字节所以减去
         	index = o.getChannel().position()-4;
         	o.getChannel().truncate(index);
         	
    out.writeObject(stu);
     }else{
     	o = new FileOutputStream(file);
     	out = new ObjectOutputStream(o);
     	out.writeObject(stu);
     }
    

    //(3)操作对象,写入到文件

    //(4)关闭流
    out.close();

  2. 反序列化

     //(1)创建一个文件对象
    
     File file = new File("C:\\software\\fileTest\\object1.txt");
     FileInputStream filein = new FileInputStream(file);
     //(2)创建流
     ObjectInputStream objin = new ObjectInputStream(filein);
     
     
     (3)操作对象:反序列化
     try {
     	while(filein.available()>0){
     		Object obj = objin.readObject();
     		StudentBean stu = (StudentBean) obj;
     		System.out.println(stu);
     	}
     } catch (ClassNotFoundException e) {
     	// TODO Auto-generated catch block
     	e.printStackTrace();
     }
     
     //(4)关闭
     objin.close();
    

猜你喜欢

转载自blog.csdn.net/Yang_Jin_/article/details/88962776