一、IO流
1.1、IO流概述
IO流用来处理设备之间的数据传输
上传文件和下载文件
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
1.2、IO流分类
按照数据流向
输入流 读入数据
输出流 写出数据
按照数据类型
字节流
字符流
什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
1.3、IO流常用基类
字节流的抽象基类:
InputStream ,OutputStream。
字符流的抽象基类:
Reader , Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
二、字节流
2.1、字节流写数据
FileOutputStream的构造方法
FileOutputStream(File file)
FileOutputStream(String name)
字节流写数据的方式
public void write(int b)
public void write(byte[] b)
public void write(byte[] b,int off,int len)
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\lx\\Desktop\\b.txt");
fileOutputStream.write("helloworld".getBytes());
fileOutputStream.close();
}
如何实现数据的换行?
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\lx\\Desktop\\c.txt");
for (int i = 0; i < 10; i++) {
fileOutputStream.write("hello".getBytes());
fileOutputStream.write("\n".getBytes());
}
fileOutputStream.close();
}
如何实现数据的追加写入?
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\lx\\Desktop\\c.txt",true);
for (int i = 0; i < 10; i++) {
fileOutputStream.write("hello".getBytes());
fileOutputStream.write("\n".getBytes());
}
}
加入异常处理的IO流操作
public static void main(String[] args) {
FileOutputStream fos=null;
try{
fos = new FileOutputStream("C:\\Users\\lx\\Desktop\\b.txt");
fos.write("helloworld".getBytes());
}catch (FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2、字节流读取数据
FileInputStream的构造方法
FileInputStream(File file)
FileInputStream(String name)
FileInputStream的成员方法
public int read()
public int read(byte[] b)
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\lx\\Desktop\\b.txt");
int read = fis.read();
System.out.println(read);
System.out.println((char)read);
fis.close();
}
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\lx\\Desktop\\b.txt");
int by=0;
while((by=fis.read())!=-1){
System.out.print((char)by);
}
fis.close();
}
2.3、字节流复制数据
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\lx\\Desktop\\b.txt");
FileOutputStream fos = new FileOutputStream("C:\\Users\\lx\\Desktop\\c.txt");
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}
fos.close();
fis.close();
}
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\lx\\Desktop\\b.txt");
FileOutputStream fos = new FileOutputStream("C:\\Users\\lx\\Desktop\\c.txt");
byte[] bytes=new byte[1024];
int len=0;
while((len=fis.read(bytes))!=-1){
fos.write(bytes);
System.out.println(new String(bytes,0,len));
}
fis.close();
fos.close();
}
2.4、字节缓冲流
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流
字节缓冲输出流
BufferedOutputStream
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("C:\\Users\\lx\\Desktop\\b.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("hello".getBytes());
bos.close();
}
字节缓冲输入流
BufferedInputStream
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\lx\\Desktop\\b.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int by=0;
while((by=bis.read())!=-1){
System.out.print((char)by);
}
System.out.println("=============");
int len=0;
byte[] bys=new byte[1024];
while((len=bis.read(bys))!=-1){
System.out.print(new String(bys,0,len));
}
}
三、字符流
3.1、字符流的继承关系
3.2、转换流OutputStreamWriter的使用
OutputStreamWriter的构造方法
OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
public static void main(String[] args) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("C:\\Users\\lx\\Desktop\\a.txt"));
out.write("abc");
out.flush();
}
3.3、字符流的5种写数据的方式
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) 写一个字符串的一部分
public static void main(String[] args) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("C:\\Users\\lx\\Desktop\\a.txt"));
out.write(97);
out.write(new char[]{'a','b','c'});
out.write(new char[]{'v','b'},0,2);
out.write("xxxxxxxx");
out.write("123456",0,3);
out.close();
}
3.4、转换流InputStreamReader的使用
InputStreamReader的构造方法
InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
InputStreamReader in = new InputStreamReader(new FileInputStream("C:\\Users\\lx\\Desktop\\a.txt"));
3.5、字符流的2种读数据的方式
public int read() 一次读取一个字符,如果没有读到 返回-1
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("C:\\Users\\lx\\Desktop\\a.txt"));
int by=0;
while((by=in.read())!=-1){
System.out.println((char)by);
}
}
public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("C:\\Users\\lx\\Desktop\\a.txt"));
int len=0;
char[] chars=new char[1024];
while((len=in.read(chars))!=-1){
System.out.println(new String(chars,0,len));
}
}
3.5、字符流复制文件
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(new FileInputStream("C:\\Users\\lx\\Desktop\\a.txt"));
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\lx\\Desktop\\b.txt"));
int len=0;
char[] chars=new char[1024];
while((len=reader.read(chars))!=-1){
writer.write(chars,0,len);
writer.flush();
}
reader.close();
writer.close();
}
3.6、FileWriter和FileReader复制文本文件
字符流便捷类: 因为转换流的名字太长了,并且在一般情况下我们不需要制定字符集,
于是java就给我们提供转换流对应的便捷类
转换流 父类 便捷类 子类
- OutputStreamWriter ------- FileWriter
- - InputStreamReader ------- FileReader
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("C:\\Users\\lx\\Desktop\\a.txt");
FileWriter writer = new FileWriter("C:\\Users\\lx\\Desktop\\b.txt");
int len=0;
char[] chars=new char[1024];
while((len=reader.read())!=-1){
writer.write(chars);
writer.flush();
}
writer.close();
reader.close();
}
3.7、字符缓冲流的基本使用
高效的字符输出流: BufferedWriter
构造方法: public BufferedWriter(Writer w)
高效的字符输入流: BufferedReader
构造方法: public BufferedReader(Reader e)
字符缓冲流的特殊功能
BufferedWriter: public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
BufferedReader: public String readLine():一次读取一行数据 是以换行符为标记的 读到换行符就换行 没读到数据返回null
public static void main(String[] args) throws IOException {
BufferedReader bfr = new BufferedReader(new FileReader("C:\\Users\\lx\\Desktop\\a.txt"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("C:\\Users\\lx\\Desktop\\b.txt"));
String s=null;
while((s=bfr.readLine())!=null){
bfw.write(s);
bfw.newLine();
bfw.flush();
}
bfr.close();
bfw.close();
}
3.7、练习
把集合中的数据存储到文本文件
public static void main(String[] args) throws IOException {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("hello");
arrayList.add("world");
arrayList.add("java");
BufferedWriter writer = new BufferedWriter(new FileWriter("C:\\Users\\lx\\Desktop\\b.txt"));
for (String s : arrayList) {
writer.write(s);
writer.newLine();
writer.flush();
}
writer.close();
}
把文本文件中的数据存储到集合中
public static void main(String[] args) throws IOException {
ArrayList<String> arrayList = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\lx\\Desktop\\b.txt"));
String s=null;
while((s=reader.readLine())!=null){
arrayList.add(s);
}
reader.close();
for (String ss : arrayList) {
System.out.println(ss);
}
}
随机获取文本文件中的姓名
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\lx\\Desktop\\b.txt"));
ArrayList<String> arrayList = new ArrayList<>();
String s=null;
while((s=reader.readLine())!=null){
arrayList.add(s);
}
reader.close();
Random random = new Random();
int index = random.nextInt(arrayList.size());
String name=arrayList.get(index);
System.out.println(name);
}
复制单级文件夹
public static void main(String[] args) throws IOException {
File aa = new File("C:\\Users\\lx\\Desktop\\aa");
File bb = new File("C:\\Users\\lx\\Desktop\\bb");
if(!bb.exists()){
bb.mkdir();
}
File[] files = aa.listFiles();
for (File file : files) {
String name=file.getName();
File newfile = new File(bb,name);
capyFile(file,newfile);
}
}
private static void capyFile(File file, File newfile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newfile));
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
bis.close();
bos.close();
}
复制指定目录下指定后缀名的文件并修改名称
public static void main(String[] args) throws IOException {
File aa = new File("C:\\Users\\lx\\Desktop\\aa");
File bb = new File("C:\\Users\\lx\\Desktop\\bb");
if(!bb.exists()){
bb.mkdir();
}
File[] files = aa.listFiles();
for (File file : files) {
if(file.getName().endsWith(".java")){
String name1 = file.getName();
String name2=name1.replace(".java",".jad");
File newfile = new File(bb,name2);
capyFile(file,newfile);
}
}
}
private static void capyFile(File file, File newfile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newfile));
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
bis.close();
bos.close();
}
键盘录入3个学生信息(姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)),按照总分从高到低存入文本文件
- 分析:
- a: 创建一个学生类: 姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)
- b: 因为要排序,所以需要选择TreeSet进行存储学生对象
- c: 键盘录入学生信息,把学生信息封装成一个学生对象,在把学生对象添加到集合中
- d: 创建一个高效的字符输出流对象
- e: 遍历集合,把学生的信息写入到指定的文本文件中
- f: 释放资源
public class Test {
public static void main(String[] args) throws IOException, IOException {
TreeSet<Student> Students = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//总分排序
//int num = s1.sum() - s2.sum(); // 小 --> 大
int num = s2.sum() - s1.sum(); // 高 --> 低
//名字
int num2 = (num==0)? (s1.getName().compareTo(s2.getName())) : num;
return num2;
}
});
File destPath = new File("Student.txt");
//3: 键盘输入数据, 把数据封装成学生对象, 存储到集合中
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
//键盘输入数据
System.out.println("请输入学生姓名:");
String name = sc.nextLine();
System.out.println("请输入语文成绩:");
String chinese = sc.nextLine();
System.out.println("请输入数学成绩:");
String math = sc.nextLine();
System.out.println("请输入英语成绩:");
String english = sc.nextLine();
Student s = new Student();
s.setName(name);
s.setChinese(Integer.valueOf(chinese));
s.setMath(Integer.valueOf(math));
s.setEnglish(Integer.valueOf(english));
Students.add(s);
}
BufferedWriter bw = new BufferedWriter(new FileWriter(destPath));
bw.write("学生姓名\t");
bw.write("语文成绩\t");
bw.write("数学成绩\t");
bw.write("英语成绩\t");
bw.write("总分\t");
bw.newLine();
bw.flush();
for (Student s : Students) {
String name = s.getName();
int chinese = s.getChinese();
int math = s.getMath();
int english = s.getEnglish();
int sum = s.sum();
bw.write(name+"\t");
bw.write(chinese+"\t");
bw.write(math+"\t");
bw.write(english+"\t");
bw.write(sum+"\t");
bw.newLine();
bw.flush();
}
bw.close();
}
}
public class Student {
private String name;
private int chinese;
private int math;
private int english;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int sum(){
return chinese + math + english;
}
}