IO流知识点汇总

来源:互联网 发布:java path设置方法技巧 编辑:程序博客网 时间:2024/06/06 03:30
IO(Input Output)流
IO流用来处理设备之间的数据传输
流按操作数据分为俩种:字节流和字符流
字节流:任何类型的数据都是二进制的
字符流:文本数据比较常见,为了方便处理,分离出字符流
将abcd等24个字母按照ASCII表编码和“1,0”序列对应
将汉字按照GBK表(GB2312表)和“1,0”序列对应
将地球上各个国家的文字进行编排,形成Unicode码表,优化后成为utf-8
unicode表无论什么字符,都是俩个字节表示,16个2进制位(有空间浪费)

utf-8,优化了存储,最多使用三个字节表示

单字节时,首位为0;

双字节时,首位110,第二位10;

三字节时,首位1110,第二位10,第三位10;


字符流基于字节流,字节流是通用的


字节流的抽象基类:InputStream,OutputStream




字符流的抽象基类:Reader,Writer




IO流是用来操作数据的,那么数据的最常见体现形式是:文件
    Writer:
专门用来操作文件的Writer子类对象。FileWriter   后缀名是父类名,前缀名是该流对象的功能
write() 将指定内容写入到流中
flush() 将数据刷新到目的地
close() 关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据

Java本身是不能往系统中写入数据,其实是调用了系统中的内容来完成写动作,这些动作全在使用系统的资源,使用完后一定要释放出来


IO异常的处理方式:
由于资源创建、写入流、以及资源关闭,三个语句都会抛出异常,所有基于多种考虑,将对象的创建放在try、catch块外部,将关闭资源语句放在finally代码块中,并且用try、catch包围,同时在该代码块中要对流资源是否创建给予判断
文件的续写:
FileWriter的构造函数,FileWriter("String str",true)//创建一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写
注:在记事本中换行要使用“\r\n”

     Reader:
close() 关闭该流并释放与之关联的所有资源,不刷新
read() 读取方法,一次读一个字符,而且会自动往下读,对于读取的内容,会返回一个整数,如果以到达流的末尾,则返回-1;
read(char[] cbuf) 返回值是读取的字符数
FileReader,用于读取字符文件的便捷类
FileReader(String fileName)


流程:
硬盘上的文件(abcde)
|
FileReader(.txt)写入流中
|
fr.read(char[] buf)fr为FileReader的对象,调用流的read方法,将流读入到字符数组中
|
fw.write(char[])fw为FileWriter的对象,调用流的write方法,将字符数组中的内容读到流中
|
new FileWriter(.txt);(.txt为目的地)
|
fw.flush()或者fw.close();

读写完毕,在finally中关闭俩个流资源


字符流的缓冲区
缓冲区的出现是为了提高对数据及流的读写效率,所以在创建缓冲区之前,必须要先有流对象
只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可,使用缓冲区,记得刷新
关闭缓冲区,就是关闭缓冲区中的流对象



对应类

|--BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供了单个字符、数组和字符串的高校写入

BufferedWriter bufw=new BufferedWriter(new FileWriter("buf.txt"));

BufferedWriter bufw=new BufferedWriter(new FileWriter("buf.txt"),int sz);

newLine();跨平台的换行符

|--BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取

BufferedReader bufr=new BufferedReader(new FileReader("buf.txt"));

BufferedReader bufr=new BufferedReader(new FileReader("buf.txt"),int sz);

readLine();一个读一行的方法,方便对文本数据的读取,当返回null是,表示读到文件末尾,该方法返回的时候只返回回车符之前的数据内容,并不返回回车符

缓冲区要结合流才可以使用
在流的基础上对流的功能进行了增强


装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类成为装饰类
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能


装饰和继承:
MyReaderclass MyBufferReader{
|--MyTextReaderMyBufferReader(MyTextReader text){}
|--MyBufferTextReaderMyBufferRaader(MyMediaReader media){}
|--MyMediaReader}
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader

MyReaderclass MyBufferReader extends MyReader{
|--MyTextReaderprivate MyReader r;
|--MyMediaReaderMyBufferReader(MyReader r){}
|--MyDataReader}
|--MyBufferReader
装饰设计模式比继承要灵活,避免了继承体系臃肿。而且降低了类与类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中


//练习:模拟一个带行号的缓冲区对象




字节流:
当操作数据不再是文本类型数据,这时就要用到字节流
由于字节流为最小单位,在传递时可以直接写不需要刷新,但是字符流不同,由于字符流底层调用的还是字节流,但一个字符可能是二个字节,所以在读取一个完整字节后,要去查表,所以必须要做刷新动作。字节流虽然没有了刷新,但是关闭资源的动作还是要执行的。


OutputStream、InputStream、BufferedInputStream、BufferedOutputStream

available()
字节流在读取时,用InputStream方法,调用方法fis.available()可以返回该文件的大小,可以根据此方法,定义一个刚刚好的缓冲区大小,不用再使用while循环
该方法在使用时,一定要注意,如果文件特别大,new一个非常大的数组会发生内存溢出。
所以new byte[1024],还是比较常见的

在字节流中read()方法读取的是字节,8个二进制位,而返回值为int类型,在这里涉及到数据类型向上提升,有Byte变为了int,由于读取数据为-1时,将结束读取,故演示-1
byte:-1  --> int:-1;
1111-1111 -->提升了一个int类型,还是-1。原因是提升时前面的位全部补得是1所导致的,如果要在前面补0的话,就既可以保留原字节数据不变,又可以避免-1的出现。
方法:&1111-1111--->&255;
由于read()方法,增加的数据的字节位,为使得文件大小不变,write()方法中带有类型强转动作,只取有效位获得原数据(最低8位)


读取键盘录入:
System.out:对应的是标准输出设备,控制台。
System.in :对应的标准输入设备:键盘。
转换流
|----InputStreamReader是字节流通向字符流的桥梁,它使用知道那个的charset读取字节并将其解码为字符。
|----OutputStreamWriter是字符流通向字节流的桥梁,
键盘录入最常见写法:
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
键盘录入时,一定要标识结束符,不然会造成程序无法结束。
注:转换流的出现,实现了字节字符的转换,同时可以自己选择字符集


流操作的基本规律:

最痛苦的就是流对象有很多,不知道该用哪一个
1.明确源和目的
源:输入流-------InputStream  Reader
目的:输出流-----OutputStream  Writer
2.明确操作的数据是否是纯文本
是:字符流
不是:字节流
3.当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:

源设备:

内存:  ByteArrayInputStream

硬盘 FileReader

键盘 System.in(该方法为字节录入,可以使用转换流转为字符流使用)

目的设备:

内存:  ByteArrayOutputStream

硬盘:  FileWriter

控制台:  System.out (该方法为字节录入,可以使用转换流转为字符流使用)

以上内容均可加入缓冲技术,


   1.将一个文本文件中数据存储到另一个文件中。复制文件。

源:读取流:InputStreamReader
文本:Reader
对象:
设备:硬盘上的一个文件

Reader体系中可以操作文件的对象时FileReader

FileReader fr=new FileReader("a.txt");

     

是否需要提高效率:加入Reader体系中的缓冲区 BufferedReader

BufferedReader bufr=new BufferedReader(fr);

目的:OutputStream Writer

文本:Writer
对象:

  

设备:硬盘上的一个文件

Writer体系中可以操作文件的对象FileWriter
FileWriter fw=new FileWriter("b.txt");
     是否需要提高效率:加入Writer体系中的缓冲区 BufferedWriter
BufferedReader bufr=new BufferedReader(fr);

   

2.将一个图片文件中数据存储到另一个文件中。复制文件。

源:读取流:InputStream Reader

文本:非纯文本

增强:BufferedInputStream

目的:OutputStream Writer

文本:非文本

增强:BufferedOutputStream

  



--------------------------------------------------------------


   1.需求:将键盘录入的数据保存到一个文件中
源:InputStream Reader
键盘录入:纯文本
设备:键盘对应的对象时System.in
而System.in是字节流,明确要使用Reader,那么就将System.in转换成Reader,用了Reader体系中的转换流,InputStreamReader

InputStreamReader isr=new InputStreamReader(System.in);
需要提高效率:
BufferedReader bufr=new BufferedReader(isr);


目的:OutputStream Writer
纯文本
设备:硬盘使用FileWriter
FileWriter fw=new FileWriter("a.txt");
需要提高效率:
BufferedWriter bufw=new BufferedWriter(fw);

扩展:想要把录入的数据按照指定的编码表,将数据存到文件中。

目的:OutputStream Writer
纯文本
设备:硬盘使用FileWriter

但是存储时,需要加入指定编码表utf-8,而指定的编码表只有转换流可以指定
所以要使用的对象时OutputStreamWriter。
而该转换刘对象要接收一个字节输出流,而且还可以操作的文件的字节输出流。FileOutputStream

OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

需要提高效率:

BufferedWriter bufw=new BufferedWriter(osw);
   转换流的使用:
字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。
注:默认字符集为GBK,如果使用了转换流,用utf-8保存的文件,读取时就必须使用转换流才能读取。
   system.setIn    system.setOut   改变输入输出设备
使用地点:生成日志文件,当然网路上有现成工具类log4j


**流只能用来操作数据,File对象用来操作数据封装成的对象**


File类
1.用来将文件或者文件夹封装成对象
2.方便对文件与文件夹的属性信息进行操作
字段摘要
static String separator---->与系统有关的默认名称分隔符
构造方法
1.File(String pathname)
2.File(String parent,String child)
3.File(File parent,String child)
常见方法
1.创建
boolean creatNewFile()在指定位置创建文件,如果该文件已经创建,则不创建,返回false。和输出流不一样,输出流对象一建立就会创建文件。而且文件已经存在的话,就会覆盖。
boolean mkdir()创建文件夹
boolean mkdirs()创建多级文件夹
2.删除
boolean delete();删除目录下的文件,删除失败返回false。
void deleteOnExit();使用在前面,当程序退出时,删除指定文件
3.判断
boolean canExecute()文件是否能被执行
boolean exists()文件是否存在

   注:

1.记住在判断文件对象是否是文件或者目录时,必须要先判断该文件封装的内容是否存在

2.“file.txt",这样的不一定就是文件,如果

File f=new File("file.txt");

f.creatNewFile();创建文件

f.mkdir();  创建目录

boolean isFile()是否是文件
booleanisDirectory()是否是目录
boolean isHidden()是否是隐藏//隐藏文件无法访问
boolean isAbsolute()是否为绝对路径


boolean renameTo(File dest)重新命名抽象路径名表示的文件,可实现文件重命名以及移动
4.获取信息
getName();
getPath();
getParent();该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null
如果相对路径中有上一层目录,那么该目录就是返回结果。
getAbsolutePath();
getAbsoluteFile();将绝对路径封装为File对象
long lastModified();
long length();


static File[] listRoots 列出可用的文件系统根
String[] list();列出指定目录下的所有文件或者文件夹的名称(包含隐藏文件)
调用list方法的file对象必须是封装了一个目录。该目录还必须存在
String[] list(FilenameFilter filter)
File[] listFiles()
File[] listFiles(FileFilter filter)

File[] listFiles(FilenameFilter filter)


列出指定目录下文件或者文件夹,抱哈子目录中的内容
也就是列出指定目录下所有内容
 
因为目录中海油目录,只要使用同一个列出目录功能的函数完成即可
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身
这种表现形式,或者编程手法,称为递归

递归要注意:
1、限定条件
2、要注意递归的次数,尽量避免内存溢出


删除一个带内容的目录
原理:在window中,删除目录是从里面往外删除的




打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印
PrintStream 字节打印流
构造函数可以接收的参数类型:
1.file对象 File 2.字符串路径 String3.字节输出流 OutputStream
PrintWriter 字符打印流
构造函数可以接收的参数类型:
1.file对象 File 2.字符串路径 String3.字节输出流 OutputStream
4.字符输出流 Writer
序列流:
可以将多个流对象拼成一个流对象即,多源变成单个源头
SequenceInputStream

还可以实现切割


操作对象:
ObjectInputStream与ObjectInputStream直接操作对象的流
protected ObjectOutputStream(OutputStream out)
可以将对象持久化到硬盘等介质中,根据类编译时的UID判断是否为该类对象,UID可以手动设置,被transient修饰的字段不会被序列化、
类想要被序列化,必须实现Serializable接口,注意持久化对象时,static修饰的字段在方法区,而对象存储在堆区,所以静态修饰的字段不会被序列化


管道流:

PipedInputStream和PipedOutputStream

输入输出可以直接进行连接,通过结合线程使用


RandomAccessFile:(可以实现数据的分段读写,实例:多线程下载)
该类不算是IO体系中的子类,而是直接继承自Object,但它是IO包中的成员,因为它具备读和写功能
内部封装了一个数组,而且通过指针对数组的元素进行操作。内部通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流
通过构造函数可以看出,该类只能操作文件
而且操作文件还有模式:只读 r,读写 rw
如果模式为只读 r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常
如果模式为读写 rw,操作的文件不存在,会自动创建,如果存在则不会覆盖。

所有在读取的时候,可以通过对数组内部指针的操作,读到数值。(一般建议存储数据时,一组数据的长度固定,这样方便读取)
ex:raf.seek(8*1);//如果一组数据长度为8个字节,那么可以通过8*x读取到第x+1组数据
ex:rafskipBytes(8);//该功能可以直接跳过指定长度的字节数,但是不能回头,只能一直往下走

注:write和writeInt的区别


DataInputStream和DataOutputStrea:(操作基本数据类型)
可以用于操作基本数据类型的数据的流对象


ByteArrayInputStream和ByteArrayOutputStream(操作字节数组)

用于操作字节数组的流对象


ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组
ByteArrayOutputStream:在巩固早的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地
因为这俩个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭


流操作规律:
源设备
|--1.键盘 System.in
|--2.硬盘 FileStream
|--3.内存 ArrayStream
目的设备
|--1.控制台 System.out
|--2.硬盘 FileStream
|--3.内存 ArrayStream
用流的读写思想来操作数据


CharArrayReader和CharArrayWrite:
操作字符数组

StringReader和StringWriter
操作字符串


字符编码:字符流的出现时为了方便操作字符,原理是加入了编码转换
1.通过子类转换流来完成
|--InputStreamReader|--OutputStreamWriter
2.编码表
ASCII:美国标准信息交换码
用一个字节的7位表示
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示
GB2312:中国的中文编码表
用二个字节
GBK:中国的中文编码表升级,融合了更多的中文文字符号
Unicode:国际标准码,融合了多种文字。
所有文字都用俩个字节来表示,Java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符。


编码:
字符串变成字节数组
解码:
字节数组变成字符串

String-->byte[];
str.getBytes();
str.getBytes(charsetName);
byte[]-->String;
new String(byte[],);
new String(byte[],charsetName);IO(Input Output)流
IO流用来处理设备之间的数据传输
流按操作数据分为俩种:字节流和字符流
字节流:任何类型的数据都是二进制的
字符流:文本数据比较常见,为了方便处理,分离出字符流
将abcd等24个字母按照ASCII表编码和“1,0”序列对应
将汉字按照GBK表(GB2312表)和“1,0”序列对应
将地球上各个国家的文字进行编排,形成Unicode码表,优化后成为utf-8
unicode表无论什么字符,都是俩个字节表示,16个2进制位(有空间浪费)

utf-8,优化了存储,最多使用三个字节表示

单字节时,首位为0;

双字节时,首位110,第二位10;

三字节时,首位1110,第二位10,第三位10;


字符流基于字节流,字节流是通用的


字节流的抽象基类:InputStream,OutputStream




字符流的抽象基类:Reader,Writer




IO流是用来操作数据的,那么数据的最常见体现形式是:文件
    Writer:
专门用来操作文件的Writer子类对象。FileWriter   后缀名是父类名,前缀名是该流对象的功能
write() 将指定内容写入到流中
flush() 将数据刷新到目的地
close() 关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据

Java本身是不能往系统中写入数据,其实是调用了系统中的内容来完成写动作,这些动作全在使用系统的资源,使用完后一定要释放出来


IO异常的处理方式:
由于资源创建、写入流、以及资源关闭,三个语句都会抛出异常,所有基于多种考虑,将对象的创建放在try、catch块外部,将关闭资源语句放在finally代码块中,并且用try、catch包围,同时在该代码块中要对流资源是否创建给予判断
文件的续写:
FileWriter的构造函数,FileWriter("String str",true)//创建一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写
注:在记事本中换行要使用“\r\n”

     Reader:
close() 关闭该流并释放与之关联的所有资源,不刷新
read() 读取方法,一次读一个字符,而且会自动往下读,对于读取的内容,会返回一个整数,如果以到达流的末尾,则返回-1;
read(char[] cbuf) 返回值是读取的字符数
FileReader,用于读取字符文件的便捷类
FileReader(String fileName)


流程:
硬盘上的文件(abcde)
|
FileReader(.txt)写入流中
|
fr.read(char[] buf)fr为FileReader的对象,调用流的read方法,将流读入到字符数组中
|
fw.write(char[])fw为FileWriter的对象,调用流的write方法,将字符数组中的内容读到流中
|
new FileWriter(.txt);(.txt为目的地)
|
fw.flush()或者fw.close();

读写完毕,在finally中关闭俩个流资源


字符流的缓冲区
缓冲区的出现是为了提高对数据及流的读写效率,所以在创建缓冲区之前,必须要先有流对象
只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可,使用缓冲区,记得刷新
关闭缓冲区,就是关闭缓冲区中的流对象



对应类

|--BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供了单个字符、数组和字符串的高校写入

BufferedWriter bufw=new BufferedWriter(new FileWriter("buf.txt"));

BufferedWriter bufw=new BufferedWriter(new FileWriter("buf.txt"),int sz);

newLine();跨平台的换行符

|--BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取

BufferedReader bufr=new BufferedReader(new FileReader("buf.txt"));

BufferedReader bufr=new BufferedReader(new FileReader("buf.txt"),int sz);

readLine();一个读一行的方法,方便对文本数据的读取,当返回null是,表示读到文件末尾,该方法返回的时候只返回回车符之前的数据内容,并不返回回车符

缓冲区要结合流才可以使用
在流的基础上对流的功能进行了增强


装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类成为装饰类
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能


装饰和继承:
MyReaderclass MyBufferReader{
|--MyTextReaderMyBufferReader(MyTextReader text){}
|--MyBufferTextReaderMyBufferRaader(MyMediaReader media){}
|--MyMediaReader}
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader

MyReaderclass MyBufferReader extends MyReader{
|--MyTextReaderprivate MyReader r;
|--MyMediaReaderMyBufferReader(MyReader r){}
|--MyDataReader}
|--MyBufferReader
装饰设计模式比继承要灵活,避免了继承体系臃肿。而且降低了类与类之间的关系。装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中


//练习:模拟一个带行号的缓冲区对象




字节流:
当操作数据不再是文本类型数据,这时就要用到字节流
由于字节流为最小单位,在传递时可以直接写不需要刷新,但是字符流不同,由于字符流底层调用的还是字节流,但一个字符可能是二个字节,所以在读取一个完整字节后,要去查表,所以必须要做刷新动作。字节流虽然没有了刷新,但是关闭资源的动作还是要执行的。


OutputStream、InputStream、BufferedInputStream、BufferedOutputStream

available()
字节流在读取时,用InputStream方法,调用方法fis.available()可以返回该文件的大小,可以根据此方法,定义一个刚刚好的缓冲区大小,不用再使用while循环
该方法在使用时,一定要注意,如果文件特别大,new一个非常大的数组会发生内存溢出。
所以new byte[1024],还是比较常见的

在字节流中read()方法读取的是字节,8个二进制位,而返回值为int类型,在这里涉及到数据类型向上提升,有Byte变为了int,由于读取数据为-1时,将结束读取,故演示-1
byte:-1  --> int:-1;
1111-1111 -->提升了一个int类型,还是-1。原因是提升时前面的位全部补得是1所导致的,如果要在前面补0的话,就既可以保留原字节数据不变,又可以避免-1的出现。
方法:&1111-1111--->&255;
由于read()方法,增加的数据的字节位,为使得文件大小不变,write()方法中带有类型强转动作,只取有效位获得原数据(最低8位)


读取键盘录入:
System.out:对应的是标准输出设备,控制台。
System.in :对应的标准输入设备:键盘。
转换流
|----InputStreamReader是字节流通向字符流的桥梁,它使用知道那个的charset读取字节并将其解码为字符。
|----OutputStreamWriter是字符流通向字节流的桥梁,
键盘录入最常见写法:
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
键盘录入时,一定要标识结束符,不然会造成程序无法结束。
注:转换流的出现,实现了字节字符的转换,同时可以自己选择字符集


流操作的基本规律:

最痛苦的就是流对象有很多,不知道该用哪一个
1.明确源和目的
源:输入流-------InputStream  Reader
目的:输出流-----OutputStream  Writer
2.明确操作的数据是否是纯文本
是:字符流
不是:字节流
3.当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:

源设备:

内存:  ByteArrayInputStream

硬盘 FileReader

键盘 System.in(该方法为字节录入,可以使用转换流转为字符流使用)

目的设备:

内存:  ByteArrayOutputStream

硬盘:  FileWriter

控制台:  System.out (该方法为字节录入,可以使用转换流转为字符流使用)

以上内容均可加入缓冲技术,


   1.将一个文本文件中数据存储到另一个文件中。复制文件。

源:读取流:InputStreamReader
文本:Reader
对象:
设备:硬盘上的一个文件

Reader体系中可以操作文件的对象时FileReader

FileReader fr=new FileReader("a.txt");

     

是否需要提高效率:加入Reader体系中的缓冲区 BufferedReader

BufferedReader bufr=new BufferedReader(fr);

目的:OutputStream Writer

文本:Writer
对象:

  

设备:硬盘上的一个文件

Writer体系中可以操作文件的对象FileWriter
FileWriter fw=new FileWriter("b.txt");
     是否需要提高效率:加入Writer体系中的缓冲区 BufferedWriter
BufferedReader bufr=new BufferedReader(fr);

   

2.将一个图片文件中数据存储到另一个文件中。复制文件。

源:读取流:InputStream Reader

文本:非纯文本

增强:BufferedInputStream

目的:OutputStream Writer

文本:非文本

增强:BufferedOutputStream

  



--------------------------------------------------------------


   1.需求:将键盘录入的数据保存到一个文件中
源:InputStream Reader
键盘录入:纯文本
设备:键盘对应的对象时System.in
而System.in是字节流,明确要使用Reader,那么就将System.in转换成Reader,用了Reader体系中的转换流,InputStreamReader

InputStreamReader isr=new InputStreamReader(System.in);
需要提高效率:
BufferedReader bufr=new BufferedReader(isr);


目的:OutputStream Writer
纯文本
设备:硬盘使用FileWriter
FileWriter fw=new FileWriter("a.txt");
需要提高效率:
BufferedWriter bufw=new BufferedWriter(fw);

扩展:想要把录入的数据按照指定的编码表,将数据存到文件中。

目的:OutputStream Writer
纯文本
设备:硬盘使用FileWriter

但是存储时,需要加入指定编码表utf-8,而指定的编码表只有转换流可以指定
所以要使用的对象时OutputStreamWriter。
而该转换刘对象要接收一个字节输出流,而且还可以操作的文件的字节输出流。FileOutputStream

OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

需要提高效率:

BufferedWriter bufw=new BufferedWriter(osw);
   转换流的使用:
字符和字节之间的桥梁,通常,涉及到字符编码转换时,需要用到转换流。
注:默认字符集为GBK,如果使用了转换流,用utf-8保存的文件,读取时就必须使用转换流才能读取。
   system.setIn    system.setOut   改变输入输出设备
使用地点:生成日志文件,当然网路上有现成工具类log4j


**流只能用来操作数据,File对象用来操作数据封装成的对象**


File类
1.用来将文件或者文件夹封装成对象
2.方便对文件与文件夹的属性信息进行操作
字段摘要
static String separator---->与系统有关的默认名称分隔符
构造方法
1.File(String pathname)
2.File(String parent,String child)
3.File(File parent,String child)
常见方法
1.创建
boolean creatNewFile()在指定位置创建文件,如果该文件已经创建,则不创建,返回false。和输出流不一样,输出流对象一建立就会创建文件。而且文件已经存在的话,就会覆盖。
boolean mkdir()创建文件夹
boolean mkdirs()创建多级文件夹
2.删除
boolean delete();删除目录下的文件,删除失败返回false。
void deleteOnExit();使用在前面,当程序退出时,删除指定文件
3.判断
boolean canExecute()文件是否能被执行
boolean exists()文件是否存在

   注:

1.记住在判断文件对象是否是文件或者目录时,必须要先判断该文件封装的内容是否存在

2.“file.txt",这样的不一定就是文件,如果

File f=new File("file.txt");

f.creatNewFile();创建文件

f.mkdir();  创建目录

boolean isFile()是否是文件
booleanisDirectory()是否是目录
boolean isHidden()是否是隐藏//隐藏文件无法访问
boolean isAbsolute()是否为绝对路径


boolean renameTo(File dest)重新命名抽象路径名表示的文件,可实现文件重命名以及移动
4.获取信息
getName();
getPath();
getParent();该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null
如果相对路径中有上一层目录,那么该目录就是返回结果。
getAbsolutePath();
getAbsoluteFile();将绝对路径封装为File对象
long lastModified();
long length();


static File[] listRoots 列出可用的文件系统根
String[] list();列出指定目录下的所有文件或者文件夹的名称(包含隐藏文件)
调用list方法的file对象必须是封装了一个目录。该目录还必须存在
String[] list(FilenameFilter filter)
File[] listFiles()
File[] listFiles(FileFilter filter)

File[] listFiles(FilenameFilter filter)


列出指定目录下文件或者文件夹,抱哈子目录中的内容
也就是列出指定目录下所有内容
 
因为目录中海油目录,只要使用同一个列出目录功能的函数完成即可
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身
这种表现形式,或者编程手法,称为递归

递归要注意:
1、限定条件
2、要注意递归的次数,尽量避免内存溢出


删除一个带内容的目录
原理:在window中,删除目录是从里面往外删除的




打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印
PrintStream 字节打印流
构造函数可以接收的参数类型:
1.file对象 File 2.字符串路径 String3.字节输出流 OutputStream
PrintWriter 字符打印流
构造函数可以接收的参数类型:
1.file对象 File 2.字符串路径 String3.字节输出流 OutputStream
4.字符输出流 Writer
序列流:
可以将多个流对象拼成一个流对象即,多源变成单个源头
SequenceInputStream

还可以实现切割


操作对象:
ObjectInputStream与ObjectInputStream直接操作对象的流
protected ObjectOutputStream(OutputStream out)
可以将对象持久化到硬盘等介质中,根据类编译时的UID判断是否为该类对象,UID可以手动设置,被transient修饰的字段不会被序列化、
类想要被序列化,必须实现Serializable接口,注意持久化对象时,static修饰的字段在方法区,而对象存储在堆区,所以静态修饰的字段不会被序列化


管道流:

PipedInputStream和PipedOutputStream

输入输出可以直接进行连接,通过结合线程使用


RandomAccessFile:(可以实现数据的分段读写,实例:多线程下载)
该类不算是IO体系中的子类,而是直接继承自Object,但它是IO包中的成员,因为它具备读和写功能
内部封装了一个数组,而且通过指针对数组的元素进行操作。内部通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流
通过构造函数可以看出,该类只能操作文件
而且操作文件还有模式:只读 r,读写 rw
如果模式为只读 r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会出现异常
如果模式为读写 rw,操作的文件不存在,会自动创建,如果存在则不会覆盖。

所有在读取的时候,可以通过对数组内部指针的操作,读到数值。(一般建议存储数据时,一组数据的长度固定,这样方便读取)
ex:raf.seek(8*1);//如果一组数据长度为8个字节,那么可以通过8*x读取到第x+1组数据
ex:rafskipBytes(8);//该功能可以直接跳过指定长度的字节数,但是不能回头,只能一直往下走

注:write和writeInt的区别


DataInputStream和DataOutputStrea:(操作基本数据类型)
可以用于操作基本数据类型的数据的流对象


ByteArrayInputStream和ByteArrayOutputStream(操作字节数组)

用于操作字节数组的流对象


ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组
ByteArrayOutputStream:在巩固早的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地
因为这俩个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭


流操作规律:
源设备
|--1.键盘 System.in
|--2.硬盘 FileStream
|--3.内存 ArrayStream
目的设备
|--1.控制台 System.out
|--2.硬盘 FileStream
|--3.内存 ArrayStream
用流的读写思想来操作数据


CharArrayReader和CharArrayWrite:
操作字符数组

StringReader和StringWriter
操作字符串


字符编码:字符流的出现时为了方便操作字符,原理是加入了编码转换
1.通过子类转换流来完成
|--InputStreamReader|--OutputStreamWriter
2.编码表
ASCII:美国标准信息交换码
用一个字节的7位表示
ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示
GB2312:中国的中文编码表
用二个字节
GBK:中国的中文编码表升级,融合了更多的中文文字符号
Unicode:国际标准码,融合了多种文字。
所有文字都用俩个字节来表示,Java语言使用的就是unicode
UTF-8:最多用三个字节来表示一个字符。


编码:
字符串变成字节数组
解码:
字节数组变成字符串

String-->byte[];
str.getBytes();
str.getBytes(charsetName);
byte[]-->String;
new String(byte[],);
new String(byte[],charsetName);
0 0
原创粉丝点击