IO流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 java.io
IO流分类
什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流;如果你什么都不知道,就用字节流
IO流基类概述
a.字节流的抽象基类:
InputStream ,OutputStream
b.字符流的抽象基类:
Reader , Writer
**注:**由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream
如:Reader的子类FileReader
FileOutputStream的构造方法
由一个案例引出使用IO流写数据,由于字节流先出现就先使用字节输出流基类OutputStream,使用具体子类FileOutputStream。
按照操作的数据类型进行划分
a.字节流
字节输入流 InputStream 读
字节输出流 OutputStream 写
b.字符流
字符输入流 Reader 读
字符输出流 Writer 写
需求:往一个文本文件中写一串数据 Hello,IO
分析:
注意事项:
a.调用系统资源创建a.txt文件
b.创建了一个fos对象
c.把fos对象指向这个文件
为什么一定要close()?
public void write(int b):
写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):
写一个字节数组
public void write(byte[] b,int off,int len):
写一个字节数组的一部分
public class Test {
public static void main(String[] args) {
//流的异常处理
FileOutputStream out = null;
try {
out = new FileOutputStream("a.txt");
out.write("abc".getBytes());
//System.out.println(1 / 0);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
System.out.println("进来了");
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//读取文件数据,
int by = in.read(); //一次读取一个字节数据,返回的是你读取到的那个字节
System.out.println(by);
//System.out.println((char) by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
//文件中数据读取完毕,然后读取不到了,返回 -1 我们可以使用 -1 来判断文件是否读取完毕。
by = in.read(); //一次读取一个字节数据
System.out.println(by);
}
}
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//我们创建一个字节数组,作为缓冲区,
byte[] bytes = new byte[100];
//返回的是你实际读取到的字节个数,
int len = in.read(bytes); //把文件中的字节一次读取满,你这个字节数组
System.out.println(len);
//len = in.read(bytes); //读取不到返回-1
//System.out.println(len);
System.out.println("================================");
/* for (byte aByte : bytes) {
System.out.println(aByte);
}*/
String s = new String(bytes, 0, len);
System.out.println(s);
// byte[] bytes1 = s.getBytes();
in.close(); //不要忘了
}
}
public class Test {
public static void main(String[] args) throws IOException {
//复制文件,读取一个字节,写入一个字节来复制
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\MyTest.java");
FileOutputStream out = new FileOutputStream("D:\\test\\MyTest.java");
/* while (true) {
int by = in.read();
if (by == -1) {
break;
}
out.write(by);
}*/
int by = 0;
while ((by = in.read()) != -1) {
out.write(by);
}
in.close();
out.close();
}
}
演示: 字节流一次读写一个字节数组复制MP3
代码如下:
public class Test {
public static void main(String[] args) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("想要复制的文件名称路径");
out = new FileOutputStream("想要复制到指定盘符文件夹下的路径");
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = in.read()) != -1) {
out.flush();
out.write(bytes, 0, len);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally{
try{
if (in != null) {
in.close();
}
if(out != null){
out.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
缓冲思想
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,
也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
BufferedOutputStream的构造方法
该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
BufferedOutputStream(OutputStream out)
BufferedInputStream的构造方法
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力
在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节
演示:BufferedOutputStream写出数据和BufferedInputStream读取数据
代码如下:
public class MyTest {
public static void main(String[] args) throws IOException {
Test();
}
private static void Test1() throws IOException {
FileInputStream in = new FileInputStream("想要复制的文件名称路径");
FileOutputStream out = new FileOutputStream("想要复制到指定盘符文件夹下的路径");
BufferedInputStream bin = new BufferedInputStream(in);
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] bytes = new byte[1024 * 8];
int by = 0;
while ((by = bin.read(bytes)) != -1) {
bout.write(bytes, 0, by);
}
bin.close();
bout.close();
}
public class Test {
public static void main(String[] args) throws IOException {
//test1(); //复制完成耗时:24962毫秒 14毫秒
//test2(); // 复制完成耗时:188毫秒 复制完成耗时:12毫秒
}
private static void test2() throws IOException {
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\烟花易冷Live_林志炫.mp3");
FileOutputStream out = new FileOutputStream("D:\\test\\烟花易冷Live.mp3");
BufferedInputStream bin = new BufferedInputStream(in);
//ctrl+Q 查看方法的文档
//ctrl+P 查看方法的参数
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] bytes = new byte[1024 * 8];
int by = 0;
long start = System.currentTimeMillis();
while ((by = bin.read(bytes)) != -1) {
bout.write(bytes, 0, by);
}
long end = System.currentTimeMillis();
bin.close();
bout.close();
System.out.println("复制完成耗时:" + (end - start) + "毫秒");
}
private static void test1() throws IOException {
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\烟花易冷Live_林志炫.mp3");
FileOutputStream out = new FileOutputStream("D:\\test\\烟花易冷Live.mp3");
byte[] bytes = new byte[1024 * 8];
int by = 0;
long start = System.currentTimeMillis();
while ((by = in.read(bytes)) != -1) {
out.write(bytes, 0, by);
out.flush();
}
long end = System.currentTimeMillis();
in.close();
out.close();
System.out.println("复制完成耗时:" + (end - start) + "毫秒");
}
}
编码:把字符串转换成字节数组
public byte[] getBytes():
使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中
public byte[] getBytes(String charsetName):
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
解码:把字节数组转换成字符串
public String(byte[] bytes):
通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
public String(byte[] bytes, String charsetName):
通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
代码如下:
public class Test {
public static void main(String[] args) {
InputStreamReader readr = null;
OutputStreamWriter writer = null;
try {
readr = new InputStreamReader(new FileInputStream(想要复制的文件名称路径"));
writer = new OutputStreamWriter(new FileOutputStream("想要复制到指定盘符文件夹下的路径"));
char[] chars = new char[200000];
int len = 0;
while ((len=readr.read())!=-1){
writer.flush();
writer.write(chars,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally {
try{
if(readr!=null){
readr.close();
}
if(writer!=null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("c.txt"));
//定义一个字符数组来充当缓冲区
char[] chars = new char[1000];
int len = 0; //记录读取到的实际的字符个数
while ((len = reader.read(chars)) != -1) {
System.out.println(len);
writer.write(chars, 0, len);
writer.flush();
System.out.println("正在复制 ...");
}
reader.close();
writer.close();
}
}
BufferedWriter: public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
BufferedReader: public String readLine():一次读取一行数据 是以换行符为标记的 读到换行符就换行 没读到数据返回null
包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
public class MyTest2 {
public static void main(String[] args) {
BufferedReader reader = null;
BufferedWriter writer = null;
try {
reader = new BufferedReader(new FileReader("a.txt"));
writer = new BufferedWriter(new FileWriter("e.txt"));
/*
BufferedReader
String readLine ()
一次读取一行。*/
/*
BufferedWriter
void newLine ()
写入一个换行符,具有平台兼容。
*/
String line = null;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) throws IOException {
ArrayList<String> list = new ArrayList<>();
list.add("陈更更");
list.add("刘思雨");
list.add("张学友");
list.add("刘思雨");
list.add("周润发");
list.add("李德华");
list.add("张柏芝");
list.add("谢霆锋");
list.add("汪峰");
BufferedWriter writer = new BufferedWriter(new FileWriter("student.txt"));
for (String s : list) {
writer.write(s);
writer.newLine();
writer.flush();
}
writer.close();
}
}
```java
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("student.txt"));
ArrayList<String> list = new ArrayList<>();
while (true) {
String name = reader.readLine();
if (name == null) {
break;
}
list.add(name);
}
reader.close();
//System.out.println(list);
//点名器
Random random = new Random();
int index = random.nextInt(list.size());
String s = list.get(index);
System.out.println(s);
}
}
public class Test {
public static void main(String[] args) throws IOException {
//封装源文件夹
File oldfile = new File("D:\\fxx");
//封装目标文件夹
File newfile = new File("E:\\fxx");
if(!newfile.exists()){
newfile.mkdirs();
}
CopyFiles(oldfile,newfile);
}
//复制文件夹中的文件
private static void CopyFiles(File oldfile, File newfile) throws IOException {
//遍历源文件夹并获取数组
File[] files = oldfile.listFiles();
for (File file : files){
if(file.isFile()) {
CopyFile(file, newfile);
}
else{
}
}
}
private static void CopyFile(File file, File newfile) throws IOException {
FileInputStream in = new FileInputStream(file);
FileOutputStream out = new FileOutputStream(new File(newfile, file.getName()));
byte[] bytes = new byte[430205700];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.flush();
out.write(bytes, 0, len);
}
in.close();
out.close();
}
}
public classCopyFolderDemo {
public static void main(String[] args) throws IOException {
// 封装目录
FilesrcFolder = newFile("e:\\java");
// 封装目的地
FiledestFolder = newFile("e:\\jad");
// 如果目的地目录不存在,就创建
if (!destFolder.exists()){
destFolder.mkdir();
}
// 获取该目录下的java文件的File数组
File[]fileArray = srcFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, Stringname) {
return new File(dir,name).isFile() && name.endsWith(".java");
}
});
// 遍历该File数组,得到每一个File对象
for (File file : fileArray){
// System.out.println(file);
// 数据源:e:\java\DataTypeDemo.java
// 目的地:e:\\jad\DataTypeDemo.java
Stringname = file.getName();
FilenewFile = newFile(destFolder, name);
copyFile(file,newFile);
}
// 在目的地目录下改名
File[]destFileArray = destFolder.listFiles();
for (File destFile :destFileArray) {
// System.out.println(destFile);
// e:\jad\DataTypeDemo.java
// e:\\jad\\DataTypeDemo.jad
Stringname =destFile.getName(); //DataTypeDemo.java
StringnewName = name.replace(".java", ".jad");//DataTypeDemo.jad
FilenewFile = newFile(destFolder,newName);
destFile.renameTo(newFile);
}
}
private static void copyFile(File file,File newFile) throwsIOException {
BufferedInputStreambis = newBufferedInputStream(new FileInputStream(
file));
BufferedOutputStreambos = newBufferedOutputStream(
newFileOutputStream(newFile));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys))!= -1) {
bos.write(bys,0, len);
}
bos.close();
bis.close();
}
}
需求:键盘录入3个学生信息(姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)),按照总分从高到低存入文本文件
分析:
a.创建一个学生类: 姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)
b.因为要排序,所以需要选择TreeSet进行存储学生对象
c.键盘录入学生信息,把学生信息封装成一个学生对象,在把学生对象添加到集合中
d.创建一个高效的字符输出流对象
e.遍历集合,把学生的信息写入到指定的文本文件中
f.释放资源
//学生类
public class Student implements Comparable {
private String name;
private int chineseScore;
private int mathScore;
private int englishScore;
private int totalScore;
public Student() {
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.englishScore = englishScore;
this.totalScore = totalScore;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChineseScore() {
return chineseScore;
}
public void setChineseScore(int chineseScore) {
this.chineseScore = chineseScore;
}
public int getMathPerScore() {
return mathScore;
}
public void setMathPerScore(int mathPerScore) {
this.mathScore = mathPerScore;
}
public int getEnglishScore() {
return englishScore;
}
public void setEnglishScore(int englishScore) {
this.englishScore = englishScore;
}
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chineseScore=" + chineseScore +
", mathPerScore=" + mathScore +
", englishScore=" + englishScore +
", totalScore=" + totalScore +
'}';
}
@Override
public int compareTo(Object o) {
Student s = (Student) o;
int num = this.getTotalScore() > s.getTotalScore() ? -1 : 1;
return num;
}
}
//测试类
public class Test {
public static void main(String[] args)throws IOException {
TreeSet<Student> set = new TreeSet<>();
BufferedWriter bw = new BufferedWriter(new FileWriter("成绩.txt"));
for (int i = 0; i < 2; i++) {
Student s = new Student();
System.out.println("请输入第"+(i+1)+"个学生姓名:");
Scanner sc1 = new Scanner(System.in);
String s1 = sc1.nextLine();
s.setName(s1);
System.out.println("请输入"+s.getName()+"的语文成绩:");
Scanner sc2 = new Scanner(System.in);
int i1 = sc2.nextInt();
s.setChineseScore(i1);
System.out.println("请输入"+s.getName()+"的数学成绩:");
Scanner sc3 = new Scanner(System.in);
int i2 = sc3.nextInt();
s.setMathPerScore(i2);
System.out.println("请输入"+s.getName()+"的英语成绩:");
Scanner sc4 = new Scanner(System.in);
int i3 = sc4.nextInt();
s.setEnglishScore(i3);
s.setTotalScore(s.getChineseScore()+s.getMathPerScore()+s.getEnglishScore());
set.add(s);
}
bw.write("学生成绩表如下:");
bw.newLine();
bw.flush();
bw.write("姓名 语文成绩 数学成绩 英语成绩 总分");
bw.newLine();
bw.flush();
for (Student student : set) {
StringBuilder sb = new StringBuilder();
sb.append(student.getName()).append(" ").append(student.getChineseScore()).
append(" ").append(student.getMathPerScore()).append(" ").
append(student.getEnglishScore()).append(" ").append(student.getTotalScore());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
}
}