首页 > 编程语言 >java io流

java io流

时间:2023-01-20 17:44:06浏览次数:42  
标签:字符 file java 字节 io new 序列化 String

起因:学习网编,发现里面的课程大量用到了io的知识,十分影响学习,所以转战io

何为“流”

流:数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

代码最后要关闭流,释放资源。关闭时写在条件if流!= null(说明流用过了)

创建文件

File file=new File(String pathname);//根据路径构建一个File对象 例子:“e:\\news1.txt”
File file=new File(File parent,String child);//根据父目录文件+子路径创建 例子:"e:\\","news2.txt"
File file=new File(String parent,String child)//根据父目录+子路径创建 例子:"e:\\","news3.txt"
//上面三种方法只是在内存中创建file对象,还没有输出到硬盘里面
file.creatNewFile();//真正创建对象

file对象信息

file.getName()//获得文件名
file.getAbsolutePath()//获得绝对路径
file.getParent()//获得父级目录
file.length()//获得文件大小(字节)
file.exists()//判断文件是否存在
file.isFile()//判断是不是一个文件
file.isDirectory//判断是不是一个目录
file.delete//删除文件,返回值是布尔值,成功为1

目录操作

mkdir创建一级目录,mkdirs创建多级目录,delete删除目录或文件。这三个方法都会返回一个布尔值

在java中目录也被当成文件,所以使用时file方法。比如一个目录既可以使用filePath也可以使用directoryPat

流的分类

  • 按操作数据单位不同分为:字节流(8bit)【操作二进制文件保证无损】,字符流(按字符)【文本文件效率更高】
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流/包装流
抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

上面的四个都是抽象类

FileInputStream

InputStream是字节输入流

InputStream抽象类是所有类字节输入流的超类

InputStream常用的子类

  1. FileInputStream文件输入流
  2. BufferedInputStream缓冲字节输入流
  3. ObjectInputStream对象字节输入流

read

  • read( )返回值如果为-1,表示读取完毕,所以一般仍在while的括号中。read返回值是int,在输出时需要强转为char才能输出字符

  • read(byte[ ] b)可以提高效率,不一个一个读取字节。

    • 如果返回-1,表示读取完毕
    • 如果读取正常,返回实际读取的字节数
    • 最多读b.length个字节

​ java中创建数组的方法

byte[] buf = new byte[8];

while((readLen = fileInputStream.read(buf))!=-1){
    sout(new String(buf,0,readLen));
}
//如果文件里内容是Hello,world(大于8个字节)
/*行为逻辑:先读取8个字节,readLen值为8,运用new String(buf,0,readLen)将buf数组中0到readLen(左闭右开)的元素转化为一个字符串
第二次,读取剩下三个,readLen为3,同上
第三次,无法读取,readLen为-1,循环结束

字节流无法读取汉字,因为一个汉字不止一个字节,会出现乱码,所以要用字符流

FileOutputStream

write与read用法类似

write(byte[ ] b)中需要用到一个string类型自带的方法 .getBytes 使字符串转换位一个字节数组

注意:如果使用new FileOutputStream(filepath)的方式,当写入内容时会覆盖原来的内容。使用new FileOutputStream(filepath,true)则写入的内容使从末尾追加的

一定要使用write(byte[ ] b, 0 ,readLen)第一个是byte数组,第二个是写出的起始位置,第三个readLen是自定义的,值为每次fileInputStream.read( byte[] b )的返回值。 防止最后一次数组没填充完,将不属于本次写入的数据也写出

文件字符流

FileReader和FileWriter是字符流,即按照字符来操作IO

FileReader相关用法

  1. new FileReader(File/String) 创建对象
  2. read方法:每次读取单个字符,返回该字符,如果到文件末尾返回-1
  3. read(char [ ] ):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
  • new String(char[ ])将char[ ]转换成String
  • new String(char[ ],off,len):将char[ ]的指定部分转换成String

FileWriter相关用法

  1. new FileWriter(File/String) 创建对象,覆盖模式,相当于流的指针在首端
  2. new FileWriter(File/String , true) 创建对象,覆盖模式,相当于流的指针在尾端
  3. write(int):写入单个字符
  4. write方法:每次写入单个字符,返回该字符,如果到文件末尾返回-1
  5. write(char [ ] ):批量写入多个字符到数组,返回写入到的字符数,如果到文件末尾返回-1。可以用(char[ ],off,len)指定部分
  6. write(string):写入整个字符串 可以用(string,off,len)指定部分
  • toCharArray将String转换成char[ ]

FileWriter使用后,必须要关闭close或者刷新flush,否则写入不到指定文件

节点流处理流

节点流:对特定的数据源读写数据,如FileReader,FileWrite

处理流(包装流)是连接在已存在的流(节点流或处理流),为程序提供更为强大的读写功能,如BufferedReader,BufferedWriter

BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的,只要是Reader的子类

writer同理

处理流设计模式

处理流(包装流)包装节点流,既可以消除不同节点流的实现差异(有些对文件操作,有些对管道操作,有些对数组操作),也可以提供更方便的方法来完成输入输出

关闭处理流时,会自动关闭他调用的节点流

Buffered使用方法

实例化Buffered,并且使用他的含参构造器,将需要使用的节点流输入进去。就可以通过对象buffered来实现某个节点流的方法

关闭时关闭buffered对象即可

对象处理流

对象流+处理流:OjectInputStream(完成反序列化) ObjectOutputStream(完成序列化)

需求

  1. 将int num=100这个int数据保存在文件中,保证这个100是int类型而不是double,string等。能够从文件中直接恢复int 100;
  2. 将Dog dog = new Dog("小黄",3 )这个dog对象保存到文件中,并且能够从文件中恢复

上面的要求,就是能够将基本数据类型或者对象进行序列化和反序列化操作

为了让某个类是可序列化的,该类必须实现如下两个接口之一

  • Serializable//这是一个标记接口 推荐选这个
  • Externalizable 该接口有方法需要实现,比较麻烦

序列化后,保存的文件格式不是存文本的,而是按照他的格式来保存的

数据和类型

把他们写到ObjectOutputStream的对象的write方法里

int会包装为Integer,他实现了Serializable

boolean会包装为Boolean,他实现了Serializable

char会包装为Charater,他实现了Serializable

double会包装为Double,他实现了Serializable

String本身就实现了Serializable

对象

如果要序列化某个类的对象,就让他implements Serializable

序列化细节

保存类型通过 .writexxx实现,比如保存Int类型就是 .writeInt( ),不写明类型的话就只是保存数据

特别的 String用的是 .writeUTF 对象用的是 .writeObject( )

反序列化细节

反序列化的顺序需要和保存数码(序列化)的顺序一样

反序列话对象要把ois(OjectInputStream对象名).readObject( )赋值给Object 对象名(比如dog)。然后通过 dog . getClass( )查看他的运行类型,dog查看他的属性信息

查看对象属性信息细节

正常会输出奇怪数字

需要在序列化时在Dog类中重写Serializable的toString方法,此时可以反序列化正常输出dog的属性

调用dog的方法:如果序列化的Dog类不在反序列化类所在的包中,或者是私有的不可调用,则需要把Dog定义(整个代码)拷贝到反序列化类所在的保重或者直接拷贝到反序列化类的下方(可以调用private ) (总之要拷贝到可以引用的地方)(引用的方法是import)

原因:Object dog = ois.readObject( ) 中dog的编译类型是Object,无法调用Dog类的方法

对象处理流的使用细节整理

  1. 读写顺序要一致
  2. 要求实现序列化或反序列化对象,需要实现Serializable
  3. 实例化的类中建议添加SerialVersionUID,为了提高版本的兼容性
private static final long serialVersionUID = 1L;
//新增属性时,系统不会认识是创建了一个新类,而是更新了版本
  1. 序列化对象时,默认将里面所有属性都进行实例化,但除了static或transient修饰的成员
  2. 序列化对象时,要求里面属性的类型也需要实现序列化接口
  3. 序列化具备可继承性,父类已经实现了序列化,他的所有子类就都实现了序列化

标准输入输出流

类型 默认设备
System.in 标准输入 InputStream 键盘
System.out 标准输出 PrintStream 显示器

System.in 编译类型是InputStream 运行类型是BufferedInputStream

System.iout 编译类型是PrintStream 运行类型也是PrintStream

转换流

InputStreamReader:Reader的子类,可以将InputStream(字节流)包装(转换)成Reader(字符流)

OutputStreamWriter:Writer的子类,可以将OutputStream(字节流)包装成Writer(字符流

默认情况下读取文件用的是utf-8编码,但是如果读的是其他编码就会出现乱码(因为没有指定读取文件的编码方式)

字节流可以指定读取的编码方式

转换流可以把字节流转换为字符流。所以先通过字节流指定编码方式读取,然后再转换为字符流

InputStreamReader

InputStreamReader(InputStream,Charset)
//先指定一个InputStream子类,然后再指定编码类型

解决乱码问题

InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath) , "gbk");
//先选用FileInputStream且采用gbk编码的字节流读取的方法,然后通过转换流包装为isr字符流
BufferedReader br = new BufferedReader(isr);
//将isr节点流转换为br处理流
String s = br.readLine( );

OutputStreamReader

与In相同,可以通过这种方法改变输出文件的编码方式

打印流

打印流只有输出流,没有输入流

PrintStream字节流

PrintWriter字符流

PrintStream

可以直接PrintStream out = System.out;创建一个out对象

在默认情况下,输出数据的位置是标准输出,即显示器

PrintStream编译类型的对象out有一个print方法,其底层是运用的write方法,所以也可以直接调用out的write方法

可以通过

System.setOut(new PrintStream("e:\\f1.txt"));

来修改打印流输出的位置/设备

Properties类

配置文件的格式

键=值

键=值

注意:键值对不需要有空格,值不需要用引号。默认为String类型

常用方法

load:加载配置文件的键值对到Properties对象

list:将数据显示到指定设备/流对象

getProperty(key):根据键获取值

setProperty(key,value):设置键值对到Properties对象,如果key存在就是修改,不存在就是新建

store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会储存为unicode值 store( )括号中第一个是输出流和新文件(修改文件)地址,第二个如果输入一个字符串就可以作为这个新文件的一个注释

标签:字符,file,java,字节,io,new,序列化,String
From: https://www.cnblogs.com/zaughtercode/p/17062941.html

相关文章

  • java 多态学习笔记
    因为在想去一个家乡的小国企,每个月五六千块钱或许也不错,所以懈怠了学习。但是论语中有说:取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣。如果我想着只是进一个小地......
  • JavaScript 中断forEach循环
    1、使用Array.prototype.some()方法代替some()方法会在找到第一个符合条件的元素时停止循环。例如:letarray=[1,2,3,4,5];array.some(function(element,inde......
  • 将IoTdb注册为Windows服务
    昨天写的文章《WindowsServer上部署IoTdb集群》,Windows下的IoTDB是控制台程序,打开窗口后,很容易被别人给关掉,因此考虑做成Windows服务,nssm正是解决该问题的利器。1.下载ns......
  • java HTML5
    HTML超文本标记语言W3C万维网联盟W3C标准包括:结构化标准语言(HTML,XML)表现标准语言(CSS)行为标准(DOM,ECMAScropt) 网页基本信息使用<!--注释内容-->进行注释......
  • java IO流
    起因:学习网编,发现里面的课程大量用到了io的知识,十分影响学习,所以转战io何为“流”流:数据在数据源(文件)和程序(内存)之间经历的路径输入流:数据从数据源(文件)到程序(内存)的路径......
  • java CSS3
    CSS层叠级联样式表快速入门CSS可以在html文件中写,写在<style>中,一般style写在head中(HTML,CSS没有分离)<style> h1(选择器){可以设置h1的属性(声明,分号结尾)......
  • javaWeb
    在java中,动态web资源开发的技术统称为JavaWeb一些默认tomcat:8080mysql:3306http:80https:443默认的主机名:loaclhost->127.0.0.1默认网站应用存放的位置:webapps......
  • javaScript
    JavaScript是一门流行脚本快速入门跟css一样,可以直接写在html中,放在script标签中alert可以弹出弹窗,内容用单引号引入的时候一定要成对出现,不能自闭和 基本语法入门......
  • java 继承 补充:子类能继承父类中的哪些内容?
    目录继承内存图构造方法的继承成员变量的继承成员方法的继承继承的特点成员变量的访问特点成员方法的访问特点方法的重写构造方法的访问特点继承内存图父类中有:成员变量......
  • vue.js客服系统实时聊天项目开发(八)使用axios post请求访客初始化接口
    访客的初始化,很多人可能会认为放到链接websocket的时候,通过ws去发送给服务端但是这样会有一定的问题,因为如果网络不稳定或者ws链接断了,会进行不停的重连,这样会造次多次请......