IO流
1 Java IO流
- I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
- Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行
I(Input): 输入流指的是将数据以字符或字节形式从外部媒介比如文件、数据库等读取到内存中。
通过Java程序读取硬盘上的某个文件内容就需要使用输入流。
O(Output):输出流指的是将内存中的数据写入外部媒介。
通过Java程序将内容写入到硬盘上的某个文件就需要使用输出流。
流(Stream)源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的 通信 ,或 读写 外围设备、外部文件等。
2 字节流
字节流和字符流:
字节流包含:InputStream和OutputStream
字符流包含:Reader和Writer
字节流的概念:字节流是由字节组成的,字节流是最基本的,所有的InputStream和OutputStream的子类都是字节流,主要用在处理二进制数据,它是按字节来处理的。
字符流的概念: 字符流是由字符组成的,Java里字符由两个字节组成,所有的Reader和Writer的子类都是字符流,主要用在处理文本内容或特定字符。
字节流和字符流的区别:
1、 读写的时候一个是按字节读写,一个是按字符。
2、需要对内容按行处理,一般会选择字符流。
3、只是读写文件,和文件内容无关的(下载、复制等),一般选择字节流
2.1 字节流 FileInputStream
FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
常用方法:
方法名: | 解释 |
---|---|
read() | 从此输入流中读取下一个数据字节。 |
close() | 关闭此输入流并释放与此流关联的所有系统资源。 |
案例
FileInputStream fi = new FileInputStream( "D:\\Lenovo\\info.txt" );
int i = fi.read();
int allRead = 0;
while (i != -1)// 判断文件读完的条件
{
System.out.print((char) i); // 注意:这里简单地把读到的字节转为字符输出,不适用于所有情况。
allRead++;
i = fi.read();
}
2.2 字节流FileOutputStream
常用方法:
方法名: | 解释 |
---|---|
close() | 关闭此输出流并释放与此流有关的所有系统资源。 |
flush() | 刷新此输出流,并强制将所有已缓冲的输出字节写入该流中。 |
write(byte[] b) | 将 b.length 个字节写入此输出流。 |
案例
使用FileOutputStream将“lenovo”写入到D:/Lenovo/info.txt文件中
byte[] data = "lenovo".getBytes();
FileOutputStream fo = new FileOutputStream("D:\\Lenovo\\info.txt");
fo.write(data);
fo.close();
综合案例:
1 使用FileInputStream/FileOutputStream进行读写文件。
使用字节流的方式D:/Lenovo/info.txt文件复制一份。
FileInputStream fis = new FileInputStream("D:\\Lenovo\\info.txt");
FileOutputStream fos = new FileOutputStream("D:\\Lenovo\\info1.txt");
int read = fis.read();
while (read != -1) {
fos.write(read);
read = fis.read();
}
// fos.flush();
fos.close();
2 将D盘中的Lenovo文件夹,复制到C盘
File dirs = new File("D:\\Lenovo"); // 要复制的目标文件夹
if (dirs.exists() && dirs.isDirectory()) { // 判断是否存在和是否是文件夹
File newDirs = new File(“C:\\Lenovo”); // 判断C盘有没有Lenovo文件夹
if (!newDirs.exists()) {
newDirs.mkdir(); // 如果没有先创建一个,文件夹是不可以复制的,需要创建出来
}
File[] files = dirs.listFiles(); // 取出要复制的文件夹中的子项
for (int i = 0; i < files.length; i++) { // 逐一将文件写入到C盘Lenovo文件夹中
FileInputStream fis = new FileInputStream(files[i].getAbsolutePath());
FileOutputStream fos = new FileOutputStream("C:\\Lenovo\\"+ files[i].getName());
int read = fis.read();
while (read != -1) {
fos.write(read);
read = fis.read();
}
fos.flush();
fos.close();
}
}
3 字符流
Java中的字符流是用于处理字符数据的输入输出流。字符流和字节流的区别在于字符流是按照字符进行读写,可以直接处理Unicode字符。
3.1 Reader子类:
1、BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
2、FileReader 从InputStreamReader类继承而来,该类按字符读取流中数据。
BufferedReader和FileReader的常用方法
BufferReader:
方法名: | 解释 |
---|---|
readLine() | 读取一个文本行。 |
close() | 关闭该流并释放与之关联的所有资源。 |
FileReader:
方法名: | 解释 |
---|---|
read() | 读取单个字符。 |
close() | 关闭该流并释放与之关联的所有资源。 |
案例1
使用BufferedReader和FileReader将D:/Lenovo/info.txt文件内容输出到控制台上
BufferedReader br = null;
// 构造BufferedReader对象
br = new BufferedReader(new
FileReader("D:\\Lenovo\\info.txt"));
String line = null;
while ((line = br.readLine()) != null) {
// 将文本打印到控制台
System.out.println(line);
}
案例2 读取一个文件中的数据
public class ReadTxt {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("D://lenovo/c.txt");
// 读取 字符流
BufferedReader br = new BufferedReader(fr);
// 使用循环读取数据
String str = null;
while ( (str = br.readLine()) != null ){
System.out.println(str);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2 Writer子类:
1.BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
2.FileWriter 从OutputStreamWriter类继承而来,该类按字符向流中写入数据。
BufferWriter常用api
方法 | 解释 |
---|---|
write(String s, int off, int len) | 写入字符串的某一部分。 |
close() | 关闭此流,但要先刷新它。 |
FileWriter常用api
方法 | 解释 |
---|---|
write(String str, int off, int len) | 写入一部分字符串。 |
close() | 关闭此流,但要先刷新它。 |
案例1:
public class WriteTest {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter("D://lenovo/hello.txt",true);//true:向后追加数据
BufferedWriter bw = new BufferedWriter(fw);
bw.write("hello lenovo !@!!!\n");//把数据写入到缓冲区 \n:转义字符,表示换行符
bw.write("hello world\t~~~~~!!!!!!!!!!");// \t tab
bw.newLine();//换行
bw.write("jinanInfo");
bw.flush();//强制输出缓冲区的数据
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
案例2
使用BufferedWriter和FileWriter将“lenovo"写入到D:/Lenovo/info.txt文件中。
BufferedWriter bufferedWriter = null;
bufferedWriter = new BufferedWriter(new FileWriter("D:\\Lenovo\\info.txt"));
bufferedWriter.write("Lenovo");
bufferedWriter.newLine();
bufferedWriter.write("!");
bufferedWriter.flush(); // flush非常重要
bufferedWriter.close(); // 文件流用完之后必须及时通过close方法关闭,否则会一直处于打开状态,直至程序停止,增加系统负担
案例3
使用字符流的方式将D:/Lenovo/info.txt文件复制一份
BufferedReader bre = null;
BufferedWriter bw = null;// 定义一个流
String file = "D:\\Lenovo\\info.txt";
bre = new BufferedReader(new FileReader(file));// 此时获取到的bre就是整个文件的缓存流
bw = new BufferedWriter(new FileWriter(new File("D:\\Lenovo\\info1.txt”);// 确认流的输出文件和编码格式,此过程创建了“test.txt”实例
String str = "";
while ((str = bre.readLine()) != null) // 判断最后一行不存在,为空结束循环
{
bw.write(str);// 将要写入文件的内容,写入到新文件
bw.newLine();
}
bw.close();// 关闭流
bre.close();// 关闭流
案例4
将D盘中的Lenovo文件夹,复制到C盘
for (int i = 0; i < files.length; i++) { // 逐一将文件写入到C盘Lenovo文件夹中
bre = new BufferedReader(new FileReader(files[i].getAbsolutePath()));// 此时获取到的bre就是整个文件的缓存流
bw = new BufferedWriter(new FileWriter(new File("C:\\Lenovo\\" + files[i].getName())));// 确认流的输出文件和编码格式,此过程创建了“test.txt”实例
String str = "";
while ((str = bre.readLine()) != null)
// 判断最后一行不存在,为空结束循环{
bw.write(str);// 将要写入文件的内容,写入到新文件
bw.newLine();
}
bw.close();// 关闭流
bre.close();// 关闭流
案例5
将字符串“Hello Lenovo”追加到D:/Lenovo/info.txt文件内容的尾部
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
FileWriter writer = new FileWriter("D:\\Lenovo\\info.txt", true);
writer.write("Lenovo");
writer.close(); // 文件流用完之后必须及时通过close方法关闭,否则会一直处于打开状态,直至程序停止,增加系统负担。