IO流的分类
按流向分:分为输入流和输出流
按类型分:分为字节流和字符流
字节流
FileOutputStream字节输出流
两种构造方法:
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream fos= new FileOutputStream(new File(“hello.txt”));
如果没有此文件,字节输出流会自动创建这个文件
FileOutputStream fos2 = new FileOutputStream(“a.txt”);
fos2.write(98);可以写入int类型
fos2.write(‘a’);字符型
fos2.write(“c”.getBytes());字符串应该转换为字符型
流用完之后一定要释放资源 .close()
换行符\r\t
三种write方法:
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分
GBK编码:一个汉字占两个字节
UTF-8:一个汉字占三个字节
FileInputStream字节输入流
文件输入流在读取文件时,文件不存在就会报错
FileNotFoundException系统找不到指定的文件
一次读取一个字节 int read(byte [] b)
没有读取到字节就会返回-1
一次读取一个字节数组
byte[] bytes = new byte[1024] ;//字节缓冲区
int len = 0 ; // 作用: 记录读取到的有效的字节个数
for(byte b:bytes){
System.out.print(new String(b);
}
字节流的异常捕获
import java.io.FileOutputStream;
import java.io.IOException;
public class Mytest {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out =null;
try {
in = new FileInputStream("c.txt");
out = new FileOutputStream("ee.txt");
int len=0;
byte[] bytes = new byte[1024];
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(out!=null){
out.close();
}
if (in!=null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
高效的字节流
BufferedOutputStream 高效字节输出流
BufferedInputStream 高效的字节输入流
这两个流基于字节输出流的顶层父类OutputStream以及字节输入流的顶层父类InputStream,数据底层引入了缓冲区的思想,所以就算用这两个流,一个一个读写文件也要比FileInputStream和FileOutputStream快
构造方法:
例如:BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(“test.txt”));
需要接收一个FileOutputStream 的对象
字符流
字符流=字节流+编码表
因为字节流操作中文不是特别方便,所以Java提供了字符流
Java中默认使用GBK编码
转换流,字符输出流OutputStreamWriter
构造方法:
OutputStreamWriter(OutputStreamWriter out)
根据默认编码(GBK)把字节流的数据转换为字符流
OutputStreamWriter(OutputStreamWriter out ,Strng charseName)
根据指定的编码把字节流转换为字符流
字节流的五种写入方式
public void write(int c) 写一个字符
public void write(char[] cbuf) 写一个字符数组
public void write(char[] cbuf,int off,int len) 写一个字符数组的 一部分
public void write(String str) 写一个字符串
public void write(String str,int off,int len) 写一个字符串的一部分
其中off是开始角标,len是个数
注意事项:
字符流中写入后需要flash()刷新流,或close()刷新并关闭
\r\n换行符
getEncoding获取编码方式
输出流所关联的文件如果不存在会自动创建
输入流所关联的文件如果不存在就会报错
转换流,字符输入流InputStreamReader
构造方法:
InputStreamReader(InputStream is)
用默认的编码(GBK)读取数据
InputStreamReader(InputStream is,String charsetName)
用指定的编码读取数据
字符流的两种读取方法
public int read() 一次读取一个字符
public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
一次读取一个数组时需要一个缓冲区char[] chs = new char[1024]
用字符流复制文件
package Demo98;
import java.io.*;
public class MyTest2 {
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("a.txt"));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("cba.txt"));
char[] chars = new char[1024 * 8];
int len=0;
while((len=in.read(chars))!=-1){
out.write(chars,0,len);
out.flush();
}
out.close();
in.close();
}
}
字符流便捷类FileWriter和FileReader
转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类FileWriter和FileReader
这两个类不能指定编码方式,所以使用默认编码,具有追加功能
高效的字符流
BufferedReader(Reader in)高效字符输入流
readline()一次读一行,读不到返回null
BufferedWriter(Writer out)高效字符输出流
newline()高效字符流独有的具有平台兼容性的换行符
用高效的字符流一次读取一个字符复制文件
package Demo99;
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("eeee.txt"));
int line=0;
while((line=br.read())!=-1){
bw.write(line);
}
br.close();
bw.close();
}
}
用高效的字符流一次读取一个字符数组复制文件
package Demo99;
import java.io.*;
public class MyTest2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("aabb.txt"));
char[] chars = new char[1024 * 8];
int line=0;
while((line=br.read(chars))!=-1){
bw.write(chars,0,line);
bw.flush();
}
bw.close();
br.close();
}
}
用高效的字符流一次读取一行复制文件
package Demo99;
import java.io.*;
public class MyTest3 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("zzz.txt"));
String line=null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
经典案例
把两首歌合唱一首歌
package Demo102;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class MyTest {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("f:\\薛之谦.mp3");
FileInputStream in2 = new FileInputStream("f:\\陈钰琪.mp3");
FileOutputStream out = new FileOutputStream("e:\\专辑大合唱.mp3");
ArrayList<FileInputStream> list = new ArrayList<>();
list.add(in);
list.add(in2);
byte[] bytes = new byte[1024 * 8];
int len=0;
for (FileInputStream inputStream : list) {
while ((len=inputStream.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
inputStream.close();
}
out.close();
}
}
我有一个文本文件,每一行是一个学生的名字,请写一个程序,每次允许随机获取一个学生名称
package Demo7;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class MyTest {
public static void main(String[] args) throws IOException {
// 需求:我有一个文本文件,每一行是一个学生的名字,请写一个程序,每次允许随机获取一个学生名称
// * 分析:
//*a:
// 创建一个高效的字符输入流对象
// * b:创建集合对象
// * c:读取数据, 把数据存储到集合中
// * d:产生一个随机数, 这个随机数的范围是 0 - 集合的长度.作为:集合的随机索引
// * e:根据索引获取指定的元素
// * f:输出
// * g:释放资源
BufferedReader bfr = new BufferedReader(new FileReader("sss.txt"));
ArrayList<String> list = new ArrayList<>();
String len=null;
while((len=bfr.readLine())!=null){
list.add(len);
}
Collections.shuffle(list);
Random random = new Random();
int i = random.nextInt(list.size());
System.out.println(list.get(i));
bfr.close();
}
}
递归调用复制多级目录
package Demo8;
import java.io.*;
public class MyTest {
public static void main(String[] args) throws IOException {
File yfile = new File("F:\\test");
File mbfile = new File("E:\\test");
if(!mbfile.exists()){
mbfile.mkdirs();
}
copyfile(yfile,mbfile);
System.out.println("复制完成");
}
private static void copyfile(File yfile, File mbfile) throws IOException {
File[] files = yfile.listFiles();
for (File f : files) {
if(f.isFile()){
copyStream(f,mbfile);
}
}
}
private static void copyStream(File f, File mbfile) throws IOException {
FileInputStream in = new FileInputStream(f);
FileOutputStream out = new FileOutputStream(new File(mbfile, f.getName()));
byte[] bytes = new byte[1024 * 8];
int len=0;
while((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
in.close();
out.close();
}
}
获取指定目录下 所有的.java结尾的文件, 打印出文件的绝对路径(包含 子文件夹中的.java文件
package Demo92;
import java.io.File;
public class MyTest {
public static void main(String[] args) {
//编写程序,获取指定目录下 所有的.java结尾的文件, 打印出文件的绝对路径(包含 子文件夹中的.java文件
File file = new File("f:\\aaa");
Pathfile(file);
}
private static void Pathfile(File file) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile()) {
System.out.println(f.getAbsolutePath());
}else{
Pathfile(f);
}
}
}
}
删除 指定目录下的 所有文件与文件夹 (包含子文件夹)
package Demo93;
import java.io.File;
public class MyTest94 {
public static void main(String[] args) {
//编写程序,删除 指定目录下的 所有文件与文件夹 (包含子文件夹)
File file = new File("f:\\aaa");
delectFile(file);
file.delete();
}
private static void delectFile(File file) {
File[] files = file.listFiles();
for (File f : files) {
if(f.isFile()){
f.delete();
}else{
delectFile(f);
f.delete();
}
}
}
}