Java基础-IO流
目录
- 1.IO流概述
- 2.IO流概述
- 3.流的四大家族
- 4.FileInputStream
- 4.1.初步
- 4.2.循环读:
- 4.3.往byte数组中读
- 4.4.最终版
- 4.5.available();
- 5.FileOutputStream
- 6.文件的复制
- 7.FileReader和FileWriter
- 7.1.FileReader
- 7.2.FileWriter
- 8.带有缓冲区的字符流
- 9.标准输出流
1.IO流概述
输入输出都是参照内存的,从内存里面出来,叫做输出,进入内存,叫输入。
I : Input
O : Output
通过IO可以完成硬盘文件的读和写。
2.IO流概述
有多种分类方式:
一种方式是按照流的方向进行分类:
- 以内存作为参照物,
往内存中去,叫做输入(Input)。或者叫做读(Read)。
从内存中出来,叫做输出(Output)。或者叫做写(Write)。
另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件等…
假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)
综上所述:流的分类
- 输入流、输出流
- 字节流、字符流
Java中的IO流都已经写好了,我们程序员不需要关心,我们最主要还是掌握,在java中已经提供了哪些流,每个流的特点是什么,每个流对象上的常用方法有哪些????
java中所有的流都是在:java.io.*;下。
java中主要还是研究:
怎么new流对象。
调用流对象的哪个方法是读,哪个方法是写。
3.流的四大家族
四大家族的首领:
- java.io.InputStream 字节输入流
- java.io.OutputStream 字节输出流
- java.io.Reader 字符输入流
- java.io.Writer 字符输出流
四大家族的首领都是抽象类。(abstract class)
注意:在Java中只要“类名”以Stream结尾的都是字节流,以Reader/Writer结尾的都是字符流。
所有的流都实现了:
- java.io.Closeable接口,都是可关闭的,都有close()方法。
流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
所有的输出流都实现了:
- java.io.Flushable接口,都是可刷新的,都有flush()方法。
养成一个好习惯,输出流在最终输出之后,一定要记得flush()
刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据
强行输出完(清空管道!)刷新的作用就是清空管道。
注意:如果没有flush()可能会导致丢失数据。
java.io包下需要掌握的流有16个:
文件专属:
- java.io.FileInputStream(掌握)
- java.io.FileOutputStream(掌握)
- java.io.FileReader
- java.io.FileWriter
转换流:(将字节流转换成字符流)
- java.io.InputStreamReader
- java.io.OutputStreamWriter
缓冲流专属:
- java.io.BufferedReader
- java.io.BufferedWriter
- java.io.BufferedInputStream
- java.io.BufferedOutputStream
数据流专属:
- java.io.DataInputStream
- java.io.DataOutputStream
标准输出流:
- java.io.PrintWriter
- java.io.PrintStream(掌握)
对象专属流:
- java.io.ObjectInputStream(掌握)
- java.io.ObjectOutputStream(掌握)
4.FileInputStream
4.1.初步
java.io.FileInputStream
1.文件字节输入流:万能的,任何类型的文件都可以采用这个流来读
2.字节的方式:完成输入的操作,完成读的操作(硬盘—>内存)
public class FileInputStreamTest01 {public static void main(String[] args) {// TODO Auto-generated method stubFileInputStream fis = null;try {//创建文件字节输入流对象//文件路径D:\\学习\\Eclipse工程\\file\\temp,Java中\表示转义//写成这个也是可以的///以下都是采用绝对路径的方式fis=new FileInputStream("D:\\学习\\Eclipse工程\\file\\temp");//开始读//调用read,指针后移1个字节。开始是处在-1的位置上int readData=fis.read();System.out.println(readData);readData=fis.read();System.out.println(readData);readData=fis.read();System.out.println(readData);readData=fis.read();System.out.println(readData);readData=fis.read();System.out.println(readData);readData=fis.read();System.out.println(readData);//读到文件的末尾了,再读的时候,读不到任何数据就返回-1readData=fis.read();System.out.println(readData);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//在finally语句块中确保流一定关闭if(fis!=null){ //避免空指针异常//关闭流的前提是:流不为空。流式null的时候没必要关闭try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}
4.2.循环读:
fis=new FileInputStream("D:\\学习\\Eclipse工程\\file\\temp");while(true){int readData=fis.read();if(readData==-1){break;}System.out.println(readData);}//改造while循环int readData=0;while((readData=fis.read())!=-1){System.out.println(readData);}
分析这个程序的特点:
一次读取一个字节byte,这样内存和硬盘交互太频繁,基本上时间/资源都耗费在交互上面了。
能不能一次读取多个字节呢?可以。
4.3.往byte数组中读
int read(byte [] b);
一次最多读取b.length个字节
减少硬盘和内存的交流,提高程序的执行效率
往byte[]数组当中读
public class FileInputStreamTest03 {public static void main(String[] args) {FileInputStream fis=null;try {//相对路径一定是从当前所在的位置寻找//eclipse和idea默认路径在哪//eclipse在工程目录下即可,idea在与工程文件夹是平级的,即默认当前路径是project的根fis=new FileInputStream("tempfile");//开始读,采用byte数组,一次读取多个字节,最多读取数组.length个字节byte[] bytes=new byte[4]; //准备一个4个长度的byte数组,一次最多读取4个字节//这个方法返回值是:读到的字节数量(不是字节本身)//原文件中内容为abcdefgint readCount=fis.read(bytes);System.out.println(readCount); //第一次读到了4个字节//不应该全部都转换,应该是读取了多少个字节,转换了多少个,所以后面是readCountSystem.out.println(new String(bytes,0,readCount));readCount=fis.read(bytes);System.out.println(readCount); //第二次只能读取3个字节System.out.println(new String(bytes,0,readCount));readCount=fis.read(bytes);System.out.println(readCount); //再次读只能返回-1} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(fis!=null){try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
}
4.4.最终版
public class FileInputStreamTest04 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("tempfile");//准备一个byte数组byte[] bytes=new byte[4];while(true){int readCount=fis.read(bytes);if(readCount==-1){break;}//把byte数组转换成字符串,读到多少个就转换多少个System.out.println(new String(bytes,0,readCount));}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(fis!=null){try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
4.5.available();
FileInputStream类的其他常用方法
int available(); //返回流当中剩余的没有读到的字节数量
long skip(); //跳过几个字节不读
fis=new FileInputStream("tempfile");System.out.println("总字节数量"+fis.available());//读1个字节int readByte=fis.read();//还剩下可以读的字节数量System.out.println("剩下多少个字节没有读"+fis.available());//这个方法有什么用byte[] bytes=new byte[fis.available()]; //这种方式不太适合太大的文件,因为byte数组不能太大//不需要循环了,直接读一次就行了int readCount=fis.read(bytes);System.out.println(new String(bytes));
skip
//跳过3个字节不读
fis.skip(3);
System.out.println(fis.read());
5.FileOutputStream
文件字节输出流:
从内存到硬盘
public static void main(String[] args) {// TODO Auto-generated method stubFileOutputStream fos=null;try {//myfile文件不存在的时候会自动新建。//这种方式谨慎使用,这种方式会先将源文件清空,然后重新写入。
// fos=new FileOutputStream("myfile");//以追加的方式在文件末尾写入,不会清空源文件内容fos=new FileOutputStream("myfile",true);//开始写byte[] bytes={97,98,99,100};//将byte数组全部写出fos.write(bytes);//将byte数组的一部分写出fos.write(bytes,0,2);//字符串String s="我是一个中国人,我骄傲";byte[] bs=s.getBytes();fos.write(bs);//写完之后,一定要刷新fos.flush();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(fos!=null){try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
6.文件的复制
使用FileInputStream和FileOutputStream完成文件的拷贝
拷贝的过程应该是一边读,一边写
使用以上的字节流拷贝文件的时候,文件类型随便,万能的。什么样的文件都能拷贝。
public static void main(String[] args) {FileInputStream fis=null;FileOutputStream fos=null;try {//创建一个输入流对象fis=new FileInputStream("D:\\aaa.txt");//创建一个输出流独享fos=new FileOutputStream("E:\\aaa.txt");//最核心的,一边读一边写byte[] bytes=new byte[1024*1024]; //一次最多拷贝1MBint readCount=0;while((readCount=fis.read(bytes))!=-1){fos.write(bytes,0,readCount);}//刷新fos.flush();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//分开try,不要一起try//一起try的时候,其中一个出现异常,可能会影响到另一个流的关闭if(fos!=null){try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(fis!=null){try {fis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
7.FileReader和FileWriter
7.1.FileReader
**文件字符输入流,只能读取普通文件。**
**读取文本内容时,比较方便,快捷。**
按照字符的方式读取,第一次e,第二次f,第三次
public static void main(String[] args) {FileReader reader=null;try {//创建文件字符输入流reader=new FileReader("myfile");//开始读char[] chars=new char[4]; //一次读取4个字符int readCount=0;while((readCount=reader.read(chars))!=-1){System.out.println(new String(chars,0,readCount));}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(reader!=null){try {reader.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
7.2.FileWriter
**文件字符输出流,写**
**只能输出普通文本**
public static void main(String[] args) {FileWriter out=null;try {//创建文件字符输出流对象out=new FileWriter("file",true);//开始写char[] chars={'我','是','黄','梅','人'};out.write(chars);out.write(chars,2,3);out.write("我是一名java软件工程师");//写出一个换行符out.write("\n");out.write("hello,world");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {if(out!=null){try {out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
8.带有缓冲区的字符流
BufferedReader:
带缓冲区的字符输入流
使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组,自带缓冲。
public static void main(String[] args) {try {FileReader reader=new FileReader("myfile");//当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流//外部负责包装的流,叫做包装流,还有一个名字叫做:处理流//像当前这个程序来说,FileReader叫做节点流,BufferedReader叫做处理流BufferedReader br=new BufferedReader(reader);//读一行
// String firstLine=br.readLine();
// System.out.println(firstLine);
// String secondLine=br.readLine();
// System.out.println(secondLine);
// String thirdLine=br.readLine();
// System.out.println(thirdLine);String s=null;while((s=br.readLine())!=null){System.out.println(s);}//关闭流//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭。br.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
如果是字节流
public static void main(String[] args) {try {//字节流FileInputStream in=new FileInputStream("myfile");//通过转换流转换 InputStreamReader将字节流转换为字符流//in是节点流,reader是包装流InputStreamReader reader=new InputStreamReader(in);//这个构造方法只能传一个字符流,不能传字节流//reader是节点流,br是包装流BufferedReader br=new BufferedReader(reader);String line=null;while((line=br.readLine())!=null){System.out.println(line);}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
BufferedWriter:带有缓冲的字符输出流
outputStreamWriter:转换流
public static void main(String[] args) {try {//带有缓冲区的字符输出流BufferedWriter out=new BufferedWriter(new FileWriter("copy"));out.write("hello,world");out.write("\n");out.write("hello,kitty!");out.flush();out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
9.标准输出流
PrintStream
标准的字节输出流:默认输出到控制台。
//联合起来写System.out.println("hello,world");//分开写java.io.PrintStream ps=System.out;ps.println("hello zhangsan");ps.println("hello,lisi");//标准输出流不需要关闭//可以改变标准输出流的输出方向吗?可以//标准输出流不再指向控制台,指向log文件PrintStream printStream=new PrintStream(new FileOutputStream("log"));System.setOut(printStream);//修改输出方向,将输出方向修改到log文件System.out.println("hello,world");System.out.println("hello,world");System.out.println("hello,world");
记录的日志类
public class Logger {/*记录日志的方法* */public static void log(String msg) {try {//指向一个日志文件PrintStream out=new PrintStream(new FileOutputStream("log.txt",true));//改变输出方向System.setOut(out);//日期当前时间Date nowTime=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");String strTime=sdf.format(nowTime);System.out.println(strTime+":"+msg);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
public class LogTest {public static void main(String[] args) {//测试工具类是否好用Logger.log("调用了System类的gc()方法,建议启动垃圾回收机制");Logger.log("调用了UserService的doSome()方法");Logger.log("用户尝试进行登录,验证失败");}
}
Java基础-IO流相关推荐
- Java基础-IO流对象之数据流(DataOutputStream与DataInputStream)
Java基础-IO流对象之数据流(DataOutputStream与DataInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据流特点 操作基本数据类型 ...
- Java基础IO流(二)字节流小案例
JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...
- # Java基础——IO流
Java基础--IO流 File类的使用(熟悉构造器和方法的使用) File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹) File类的声明在java.io包下 文件和文件目录路径的抽象表示 ...
- Java基础IO流之字符流的使用
☆引言☆ 大家好,我是痛而不言笑而不语的浅伤.IO流分为字节流和字符流,而上一篇文章我们学习了字节流(Java基础IO流之字符流的使用),这篇文章带大家一起来学习字符流吧.对文章中描述错误的希望大家积 ...
- 黑马程序员-JAVA基础-IO流之字符流和字符流缓冲区
------- android培训.java培训.期待与您交流!------- Java 的IO 流 是实现输入和输出的基础,Java 中把不同的输入.输出源抽象表述为"流" (S ...
- Java基础—IO流
第一讲 IO概述 1. 流的概念 IO流即InputOutput的缩写,在Java中IO流用来处理设备之间的数据传输,Java对数据的操作是通过IO流的方式, 我们可以把IO流抽象的当作一根管道, ...
- java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类
目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...
- JAVA基础 IO流技术学习笔记
目录 一.IO 流技术介绍 1.1 什么是IO? 1.2 流的概念 1.3 数据源 1.3.1 什么是数据源? 1.3.2数据源的分类 二.第一个简单的IO流程序 三.IO流经典写法(适用于任何 ...
- java基础--IO流之File类
一.File类概述 用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作,File对象可以作为参数传递给流的构造函数 二.File类常见方法: 1,创建 boolean createN ...
- Java基础——IO流
IO流基础知识内容: 1.java.io包下 File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源. File file1 = new File("d:\\ ...
最新文章
- 登录之图形跟短信验证码
- 【html+css练习】小白使用html+css模拟音乐播放器构造了网页音乐播放器--1
- Spring Boot 最核心的 3 个注解详解
- 4690s i5_秒杀i7?小恶魔i5-4690K对决i7-4770K
- 十、华为鸿蒙HarmonyOS应用开发之Java UI框架、常用TabList组件使用
- 如何禁止使用bottomsheetdialogfragment拖动?
- python特效电子相册_用Python和Conky做个电子相册,美化你的Linux桌面
- 邻居子系统:地址解析协议
- @primary注解_springboot整合redis分别实现手动缓存和注解缓存
- 一文看尽Facebook 3D视觉技术研究进展
- linux找不到mysql服务_linux mysql 找不到 mysql/mysql.h
- Lost Cows POJ 2182 思维+巧法
- qqxml图片代码_QQxml卡片代码合集超大图、清明上河图、官方认证推荐等
- 笔记本摄像头计算机,笔记本摄像头怎么开
- 康考迪亚大学应用计算机科学,2020年康考迪亚大学IT专业会学什么内容
- 如何安装最新igraph 现在已经无坑了
- 我们来用Unity做一个局域网游戏(下)
- 卫星轨道和两行数据TLE
- Win2003下安装MSN
- github优秀项目源码汇总---Android