Input:时数据从 硬盘 进入 内存 的过程 ,称之为“读”
Output:是数据从 内存 到 硬盘 的过程,称之为“写”
以 内存 为参照物,内存在读写
内存:内存条
IO流:不管字节流还是字符流,输入和输出全都是字节的格式,只是字符流多了一个可以直接字符串输入的。
在遍历的时候:
为什么
int len;
while((len = s.read())!= -1){sout((char)len)}
而不是
while(s.read() != -1){sout((char)s.read())}?
因为,在条件中s.read()执行了一次,读了一个字节,然后在循环内s.read()又执行了一次,一个循环执行两次read方法,肯定出错,所以必须要用变量来接,然后用变量输出
为什么在很多char数组或byte数组的动态数组的创建都是用长度为1024
并不是越大越好,一个长度为10,你用100000去装合适吗?
按流向分:
IO:输入流、输出流
按数据类型分:(一般来说,我们说的分类是以数据类型分)
IO:
字节流:可操作所有类型文件(音频、视频等)
字符流:只能操作纯文本文件(java、text等)
IO流的技术选型:以text方式打开,能看得懂内容得是字符流,看不懂的是字节流
IO流也称字节流
字节输出流:
从内存到硬盘
构造方法:
FileOutputStream(File f) | 将File文件的路径写出到硬盘 |
FileOutputStream(String s) | 将路径写出到硬盘 |
FileOutputStream f = new FileOutputStream("D:\\a.text")
f.write("97");
f.close();
1.若文件不存在,则自动创建
2.若存在会把文件删除,并重新创建自己的内容
3.写数据write(),在传一个整数时,实际写到文件中的,是这个整数在码表中对应的字符
4.告诉操作系统可以释放这个资源,否则会一直运行,无法增删改等操作(会提示文件占用中)
file和fileOutputStream是什么关系?
file是用来创建文件或文件夹的,FileOutputStream是用来写内容的
字节流写数据的3种方式:
void write(int b) | 一次写一个字节数据 |
void write(byte[ ] b) | 一次写一个字节数组数据 |
void write(byte[ ] , int off , int len) | 一次写一个字节数组的部分数据 off:从第几个索引开始 len:拷贝几个 |
换行:
win:\r\n
linux:\n
mac:\r
write("\r\n".getBytes() ),注意:write里只能写int或字节数组,需要查看String里有无转换方法
如何追加(保留原来的内容,不清空,从后面开始添加)
在构造方法的参数后面还有一个参数开关
FileOutputStream(File f,boolean append) | append(续写开关):默认为false,当打开时,即true,则在文件后面续写 |
异常标准处理方式:try...catch...finally{};finally里面的内容一定会被执行
public static void main(String[] args) throws IOException { FileOutputStream f = null; try { sout(2/0) f = new FileOutputStream("Mo2\\src\\package4\\b.text",true); byte[] a = {48,49,50}; f.write(a); //f.close();----如果在这里释放资源,若前面出异常,则一直释放不了 } catch (IOException e) { e.printStackTrace(); } finally { if (f!=null) {----如果f都还没被赋值,被传过来了,会报错 try { f.close(); } catch (IOException e) { e.printStackTrace(); } } } }
字节输入流:(注意:没有续写开关)
从硬盘到内存
FileInpurStream f = new FileInputStream("D:\\a.text");如果文件不存在,则报错
int r = f.read();
注意!!!read方法:一次读取一个字节,例:text中的97,只能读到9,然后打印出来是57
也就是字符在码表中对应的数字
如果想看字符,必须强转成char
sout((char)r);
f.close();
循环一般只有在读取中使用,写入用不到
切记,字节流,在write写入时或read读取时,都是以字节的格式写入,以字节的格式读取出来
即:你write(97),text显示a,read()之后出来的时97
但不能write(a)直接写a或其他字符串,
若text中是手动写的97,则读取时,read方法一次只能读一个字节,只能读到数字9,要转回字节码9对应的ascall码表为57
Ascall码表是基础(0-255),gbk是中文(255以外),unicode是全球码表
连续读取多个字节
读取多个字节实例:(拷贝音乐文件到另外一个目的地)
如果是拷贝目的地是项目下即相对路径,则可以右键文件,旋转show in explore,可以打开文件位置
在删除文件时,会弹出提示框,最好全选会自动检测,提示代码中哪里用到这个文件,当确认无误之后可以点击左下角的Do Refactor
但 一个字节一个字节拷贝速度实在太慢
提高拷贝速度方法:
public int read(byte[ ] b ) | 从输入流中读取最多b.length个字节数据 注意: 返回的是读入(内存)缓冲区的总字节数,也就是实际的读取字节个数 |
理解:
read()方法:是一个字节一个字节读
read(集合)方法:是将字节装进数组里然后读取
1KB=1024byte(字节)=1024*8bit(比特)
1024KB等于1MB。
动态数组长度更大不是更多吗?有什么影响
字节缓冲流:
构造方法:
BufferedOutputStream(OutputStream o) | 创建字节缓冲输出流对象 |
BufferedInputStream(InputStream i) | 创建字节缓冲输入流对象 |
两个构造方法的底层都会自动创建一个8192的数组
参数的OutputStream就是FileOutputStream
为什么字节缓存流的构造方法的参数要字节流,而不是文件或路径呢?
缓冲流仅仅是提供缓冲区(其实缓冲区就是数组),不能直接操作数据,真正读写的还是字节流
在关闭流时,只需要关闭缓冲流即可,他会把字节流一起关了