流的基本概念
1、IO流,什么是IO?
I:Input
O:Output
通过IO可以完成硬盘文件的读和写。2、IO的分类?
有多种分类方式:
一种方式是按照流的方向进分类:
(1)以内存作为参照物,
往内存中存,叫做输入。或者叫做读。
从内存中取,叫做输出。或者叫做写。另一种方式是按照读取数据方式不同进行分类:
(2)按照读取数据的方式
【1】有的流是按照字节的方式读取数据,一次读取一个byte,等同于一次读取8个二进制位,
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,声音文件。视频文件等等。
a中国bc张三fe
第一次读:一个字节,正好读到'a'(char在java中占用两个字节)
第二次读:一个字节,正好读到'中'字符的一半
第三次读:一个字节,正好读到'中'字符的另一半【2】有的流是按照字符的方式读取的,一次读取一个字符,这种流是为了方便读取普通文本文件
而存在的,种种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文档都
无法读取。
假设文件file.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读取:'a'字符('a'字符在windows系统中占用一个字节。)
第二次读:'中'字符('中'字符在windows系统中占用两个字节。)
3、java中所有的流都是在java.io.*;下。
java中主要还是研究:
怎么new流对象。
调用流对象的那个方法是读,那个方法是写。4、java IO流有四大家族。
四大家族的首领:
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流java.io.Reader 字符输入流
java.io.Writer 字符输出流四大家族的首领都是抽象的。(abstract class)
所有流都实现了:
java.io.Closeable接口,都是可关闭的,都有close()方法。
流毕竟是一个管道,这是实现内存和硬盘之间的通道,用完之后一定要关闭,
不然会耗费(占用)很多资源。养成好习惯:用完流一定要关闭。所有的---输出流---都实现了:
java.io.Flushable接口,都是可刷新的,都有flush()方法
养成一个好习惯,输出流在最终输出之后,一定要记得flush()
刷新一下,这个刷新表示将通道/管道当中剩余未输出的数据
强行输出完(清空管道!)刷新的作用就是清空管道。
注意:如果没有flush()方法,可能会导致丢失数据。注意:
在java中只要“类名”以Stream结尾的都是字节流。
以“Reader/Writer”结尾的都是字符流。4、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.DateOutputStream
标准输出流:
java.io.PrintWriter
java.io.PrintStream
对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream
*/
文件专属流
文件专属:
java.io.FileInputStream(掌握)
java.io.FileOutputStream(掌握)
java.io.FileReader
java.io.FileWriter
1、java.io.FileInputStream
package com.tjdz.javaSE.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
java.io.FileInputStream:
1、文件字节输入流,万能的,任何的类型文件都可以采用这个流来读。
2、字节的方式,完成输入的操作,完成读的操作(硬盘--->内存)
*/
public class FileInputStreamTest01 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
// 创建文件字节输入流对象
// 文件路径:E:\Text document\file\temp.txt(IDEA工具会自动把\变成\\,因为java中\表示转义)
//FileInputStream fis = new FileInputStream("E:\\Text document\\file\\temp.txt");
//写成/也是可以的
fis = new FileInputStream("E:/Text document/file/temp.txt");
//开始读
int realData = fis.read(); // 这个方法的返回值读取到的“字节”本身
System.out.println(realData); //97
realData = fis.read();
System.out.println(realData); //98
realData = fis.read();
System.out.println(realData); //99
realData = fis.read();
System.out.println(realData); //100
realData = fis.read();
System.out.println(realData); //101
realData = fis.read();
System.out.println(realData); //102
//已经读到文件的末尾了,在读的时候读取不到任何数据,返回-1
realData = fis.read();
System.out.println(realData); //-1
realData = fis.read();
System.out.println(realData); //-1
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
//在finally语句块当中确保流一定要关闭
if(fis != null){ // 避免空指针异常
//关闭流的前提是:流不是null,流是null的时候没必要关闭
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.tjdz.javaSE.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
对第一个程序进行该进。循环方式。
分析这个程序的缺点:
一次读取一个byte,这样内存和硬盘之间交互太频繁,基本上大部分时间/资源
都耗费在交互上面了。能不能一次读取多个字节呢。
*/
public class FileInputStreamTest02 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("E:/Text document/file/temp.txt");
/*
while(true){
int readDate = fis.read();
if(readDate == -1){
break;
}
System.out.println(readDate);
}
*/
//改造while循环
int readDate = 0;
while((readDate = fis.read()) != -1){
System.out.println(readDate);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.tjdz.javaSE.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
int read(byte[] b)
一次最多读取 b.length 个字节
减少硬盘和内存交互,提高程序执行效率
往byte[]数组当中读。
*/
public class FileInputStreamTest03 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
// IDEA默认的当前路径在哪?(工程Protect的根就是IDEA的默认当前路径。)
fis = new FileInputStream("temp.txt");
//开始读,采用byte数组,一次读取多个字节。最多读取“数组.length”个字节
byte [] bytes = new byte[4]; //准备一个4个长度的byte数组,一次性读取4个字节
// 这个方法的返回值是:读取到的字节数量(不是字节本身)
int readCount = fis.read(bytes);
System.out.println(readCount); //第一次读到了四个字节
//将字节数组全部转换成字符串
//System.out.println(new String(bytes)); //abcd
//不应该全部转换,应该读取多少个转多少个
//System.out.println(new String(bytes,0,readCount));
readCount = fis.read(bytes); //第二次只能读取到两个字节
System.out.println(readCount); //2
//System.out.println(new String(bytes,0,readCount));
readCount = fis.read(bytes); //1个字节都没读取到返回-1
System.out.println(readCount); // -1
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.tjdz.javaSE.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
最终版
*/
public class FileInputStreamTest04 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("temp.txt");
byte[] bytes = new byte[4];
/*
while(true){
int readCount = fis.read(bytes);
if(readCount == -1){
break;
}
System.out.print(new String(bytes,0,readCount));
}
*/
//改造while循坏
int readCount = 0;
while((readCount = fis.read(bytes)) != -1){
System.out.print(new String(bytes,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.tjdz.javaSE.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
FileInputStream类的其他方法;
int available() :返回流当中剩余的没有读到的字节数量
long skip(long n) :跳过集合字节字节不读
*/
public class FileInputStreamTest05 {
public static void main(String[] args) {
FileInputStream fis =null;
try {
fis = new FileInputStream("temp.txt");
System.out.println("总字节数:"+fis.available());
//读1个字节
int readByte = fis.read(); //转换为对应额ASCII码值
System.out.println(readByte); // 这里对应输出的是ASCII码值
// 还剩下可以读的字节数量:5
System.out.println("还剩下可以读的字节数量:"+fis.available());
//byte [] bytes = new byte[fis.available()];//不适合大文件,因为byte数组不是太大
//不需要循环
// 只需要读一次就行
//int readCount = fis.read(bytes);
//System.out.println(new String(bytes));
//skip跳过几个字节不读取
fis.skip(3);
System.out.println("跳过后流的数量:"+fis.available());
byte[] bytes = new byte[fis.available()];
int readCount = fis.read(bytes);
System.out.println(readCount);
System.out.println(new String(bytes));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2、java.io.FileOutputStream
package com.tjdz.javaSE.IO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
文件字节输出流
从内存到硬盘。
void write(byte[] b)
写 b.length字节从指定的字节数组的输出流。
*/
public class FileOutStreamTest01 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//myfile文件不存在时,会自动新建
//这种方式谨慎使用,这种方式先回将源文件清空,然后再重新写入。
//fos = new FileOutputStream("myfilm");
//若想追加
//以追加的方式在文件末尾写入,不会清空源文件内容。
fos = new FileOutputStream("myfilm",true);
//开始写
byte[] bytes = {97,98,99,100};
//将byte数组全部写出
fos.write(bytes); //abcd
//将bytes的一部分写入
fos.write(bytes,0,2); //ab
//字符串
String s = "我是一个中国人";
//将字符串转换成bytes数组。
byte[] bytes1 = s.getBytes();
//写
fos.write(bytes1);
//写完之后,最终一定要刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3、java.io.FileReader
package com.tjdz.javaSE.IO;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
FileReader:
文件字符输入流,只能读取普通文本
读取文本内容时,比较方便,快捷。
*/
public class FileReaderTest {
public static void main(String[] args) {
FileReader reader = null;
try {
//创建文件字符流输入流
reader = new FileReader("temp.txt");
//准备一个char数组
char[] chars = new char[10];
reader.read(chars);
for(char c : chars){
System.out.print(c);
}
/*//开始读
char [] chars = new char[4]; // 一次读取4个字符
int readCount =0;
while((readCount = reader.read(chars)) != -1){
System.out.print(new String(chars,0,readCount));
}*/
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4、java.io.FileWriter
package com.tjdz.javaSE.IO;
import java.io.FileWriter;
import java.io.IOException;
/*
FileWriter:
文件字符输出流。写。
只能输出普通文本。
*/
public class FileWriterTest {
public static void main(String[] args) {
FileWriter out = null;
try {
//创建字符输出流对象
//out = new FileWriter("file");
//如果想在后面一直不删除原来的情况下追加
out = new FileWriter("file",true);
//开始写
char [] chars = {'我','是','中','国','人'};
out.write(chars);
out.write(chars,2,3);
out.write("\n");
out.write("我是一名java软件工程师!");
//刷新
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}