1. 程序的异常
严重问题:Error 不处理,问题严重,比如内存溢出
问题:Exception:
编译器问题:不是运行期RuntimeException的异常,必须进行处理,不处理将不能通过编译
运行期问题:RuntimeException 这种问题也不处理,程序的严谨性问题
如果程序出现了问题,我们没有处理,虚拟机将默认进行处理:把异常问题,出现的原因输出在控制台,同时结束程序
1.1 try...catch...finally处理格式
try {
//可能出现问题的代码,代码量越少越好,虚拟机需要开辟新的问题处理这个问题
}catch(异常名称) {
//针对问题的处理
}finally {
//释放资源
}
// 变形格式
try {
//可能出现问题的代码,try问题出现以后,将会去catch里面查找,但是不能继续执行try里面的代码
}catch(异常名称) {
//异常名称写成Exception可以接收所有的异常,能明确尽量明确,针对问题的处理,需要有处理方式
}
例如:
public static void main(String[] args) {
int a = 20;
int b = 0;
try {
System.out.println(a / b);
}catch(ArithmeticException s) {
System.out.println("除数不能为0");
}
System.out.println("over");
}
JDK7异常处理新特性:
public static void method2() {
int a = 0;
int b = 0;
int[] arr = {1, 2, 3};
try {
System.out.println(a / b);
System.out.println(arr[3]);
}catch(ArithmeticException | ArrayIndexOutOfBoundsException s){
System.out.println("有问题");
}
System.out.println("over");
注意:异常必须是同级关系,不能够是继承关系,并且所有的异常执行同一种操作
异常的几个常用方法:
public String getMessage():返回异常的消息字符串
public String toString():返回throwable的简短描述,将由一下字符串拼接而成:
此对象的类的名称(全路径名)
": "冒号和一个空格
调用此对象getLocalizedMessage()方法的结果
public String getLocalizedMessage():创建throwable的本地化描述,子类可以重写此方法,以便生成特定语言环境的消息,对于不重写此方法的子类,将默认返回与getMessage()的结果
void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回void
void printStackTrace(PrintStream s):通常用该方法将异常的内容存储到日志文件中,以便日后查看
public static void main(String[] args) {
String s = "2014-01";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse(s);
System.out.println(d);
} catch (ParseException e) {
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
}
}
finally:finally控制的语句一定会得到执行,但是如果执行finally之前jvm退出,将不能执行
finally主要用于释放资源,在IO流和数据库的操作中会经常遇到,try...finally可以单独使用
final:最终的意思,可以修饰类,成员变量,成员方法
修饰类:类不能够被继承
修饰变量:该变量是常量
修饰方法:方法不能够被重写
finalize:是Object类的一个方法,用于垃圾回收。
1.2 throws处理格式
特点:自身不能处理或者没有权限处理,抛出后是编译器的异常必须要处理,运行期可以不处理
public static void main(String[] args) {
System.out.println("今天的天气很好");
try {
method();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("就是有点热");
}
public static void method() throws ParseException {
String s = "2015-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//不能处理或者没有权限处理
Date d = sdf.parse(s);
}
1.3 throw以及与throws的区别
throws:
用在方法声明后面,后面跟的是异常的名称
可以跟多个异常类名称,用逗号隔开
表示抛出异常,由该方法的调用者来处理这个异常
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw:
用在方法体中,跟的是异常的对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定是抛出了某种异常
public static void main(String[] args) {
method1();
try {
method2();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void method1() {
int a = 10;
int b = 0;
if (b == 0) {
throw new ArithmeticException();
}else {
System.out.println(a / b);
}
}
public static void method2() throws Exception {
int a = 10;
int b = 0;
if(b == 0) {
throw new Exception();
}else {
System.out.println(a / b);
}
}
throws和try到底应该用哪个:
如果后续程序需要继续运行就执行try
如果后续程序不需要继续运行就执行throws
面试题:如果catch里面由return语句,那么finally里面的代码是否会执行,如果会,请问在return 前还是在return 后:会,前,但是return 的返回路径已经确定,准确的说finally在return 的中间
public static void main(String[] args) {
System.out.println(getInt());
}
public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
}catch(ArithmeticException e) {
System.out.println("出错啦");
a = 30;
return a;
}finally {
System.out.println("到底在哪里呢");
a = 40;
}
return a;
}
程序运行结果:
出错啦
到底在哪里呢
30
1.4 自定义异常
public class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
}
public class Teacher {
public void check(int score) throws MyException {
if(score > 100 || score < 0) {
throw new MyException("分数必须在0到100之间");
}else {
System.out.println("分数没有问题");
}
}
}
异常的注意事项:
1. 子类重写父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类,
2. 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者它的子类的异常,子类不能够抛出父类没有的异常
3. 如果被重写的方法没有异常抛出,那么子类的方法绝对不能够通过throw抛出异常,如果子类方法有异常发生,那么子类只能用try不能用throw
2. 文件操作
2.1 File类和构造方法
定义:文件或者目录路径名的抽象表现形式,未必真实存在
构造方法:一下三种方式的效果相同,一般采用第一种方法:
public File(String pathname):根据路径得到一个File对象
public File(String parent, String child):根据一个目录和一个子文件得到File对象
public File(File parent, String chile):根据一个父File对象和一个子文件/目录得到File对象
2.2 成员方法
创建功能:
public boolean createNewFile():创建文件,如果存在,就不创建并返回false
public boolean mkdir():创建文件夹,如果存在,不创建并返回false
public boolean mkdirs():创建文件夹,如果父文件夹不存在,也会创建,多层。
注意:创建文件或者文件夹时需要选择正确的方法。
如果没有写盘符文件,默认在项目文件路径下
删除文件:
public boolean delete():删除文件或者文件夹,删除最后一层,Java删除时不走回收站,
删除文件夹时,只有是空文件夹只能删除
重命名功能:
public boolean renameTo(File dest):重命名file文件夹成dest
路径名相同重命名,不同时先剪切在重命名
判断功能:
public boolean isDirectory():判断是否是目录
public boolean isFile():判断是否是文件
public boolean exists():判断是否存在
public boolean canRead():判断是否可读
public boolean isHidden():判断是否隐藏
public static void main(String[] args) {
File file1 = new File("D:\\Wet_Download\\Xunlei_Download\\wangwangwang");
System.out.println("mkdir:" + file1.mkdir());
System.out.println("mkdir:" + file1.mkdir());
File file2 = new File("D:\\Wet_Download\\Xunlei_Download\\xiaojingzi.txt");
try {
System.out.println("mkdir:" + file2.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
File file3 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\xio.txt");
System.out.println("mkdirs:" + file3.mkdirs());
System.out.println("delete:" + file3.delete());
System.out.println("delete:" + file3.delete());
System.out.println("delete:" + file1.delete());
System.out.println("delete:" + file2.delete());
File file4 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\hello.txt");
File file5 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\gulao.txt");
System.out.println(file4.renameTo(file5));
System.out.println("------------");
File file6 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy");
System.out.println(file6.isDirectory());
System.out.println(file6.isFile());
System.out.println(file6.exists());
System.out.println(file6.canRead());
System.out.println(file6.canWrite());
System.out.println(file6.isHidden());
}
获取功能:
public String getAbsolutePath():获取绝对路径
public String getPath():获取相对路径
public String getName():获取名称
public long length():获取字节数
public long lastModified():获取最后一次修改时间,毫秒值
public static void main(String[] args) {
File file = new File("D:\\Wet_Download\\Xunlei_Download\\wyy");
System.out.println("getAbsolutePath:" + file.getAbsolutePath());
System.out.println("getPath:" + file.getName());
System.out.println("getName:" + file.getName());
System.out.println("length:" + file.length());
System.out.println("lastModified:" + file.lastModified());
Date d = new Date(1533819207190l);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
System.out.println(s);
Date da = new Date(); // 获取现在的时间
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String st = sdf.format(da);
System.out.println(st);
}
插入:时间转字符串以及字符串转时间
// 时间转字符串输出:
Date d = new Date(1533819207190l); // 毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
System.out.println(s);
Date da = new Date(); // 获取现在的时间
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String st = sdf.format(da);
System.out.println(st);
// 字符串转时间输出:
String s = "2015-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//不能处理或者没有权限处理
Date d = sdf.parse(s);
高级获取功能:
public String[] list():返回指定文件夹或文件字符串文件名数组
public File[] listFiles():返回指定文件夹或文件的文件类数组
public static void main(String[] args) {
File file = new File("D:\\Wet_Download");
String[] st = file.list();
System.out.println(Arrays.toString(st));
File[] fi = file.listFiles();
System.out.println(Arrays.toString(fi));
}
文件名称过滤器:
public String[] list(FilenameFilter filter):根据过滤器返回指定文件夹或文件字符串文件名数组
public File[] listFiles(FilenameFilter filter):根据过滤器返回指定文件夹或文件的文件类数组
public static void main(String[] args) {
File file = new File("D:\\Wang_File\\Home_Work\\dynamic_convolution");
String[] strArray = file.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
/* File fil = new File(dir, name);
if(fil.isFile()) {
if(name.endsWith(".jpg")) {
return true;
}
}
return false;*/
return new File(dir, name).isFile() && name.endsWith(".jpg");
}
});
System.out.println(Arrays.toString(strArray));
}
3. IO流
3.1 递归
递归:方法内部调用方法本身的现象
注意事项
1. 递归需要有出口,否则就是死递归
2. 递归的次数不能够太多,否则就会导致内存溢出
3. 构造方法不能够递归调用
public static int calc(int n) {
if(n == 1) {
return 1;
}else {
return n * calc(n - 1);
}
}
public static void deleteFolder(File srcFolder) {
File[] fileArray = srcFolder.listFiles();
for(File file : fileArray) { // 删除文件
if(file.isDirectory()) {
deleteFolder(file);
}else {
System.out.println(file.getName() + "----" + file.delete());
}
}
System.out.println(srcFolder.getName() + "----" + srcFolder.delete()); // 删除文件夹
}
3.2 java IO流的分类:
按照流向:输入流:写数据,输出流:读数据
按照数据类型:字节流:都可以使用字节流来传输
输入字节流:读取数据 InputStream
输出字节流:写出数据 OutputStream
字符流:如果是文本类型的数据,可以使用记事本打开,就可以采用字符流来传输
输入字符流:读取数据 Reader
输出字符流:写出数据 Writer
3.2.1 OutputStream
FileOutputStream的构造方法:
FileOutputStream(File file):
FileOutputStream(String name):调用系统功能创建文件,创建fos对象,把fos对象指向这个文件
FileOutputStream(String name, boolean append):true时追加
FileOutputStream(File file, boolean append):true时追加
close():
A 让流对象变成垃圾,这样就可以被垃圾回收器回收了
B 通知系统去释放文件相关的资源
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 {
OutputStream fos = new FileOutputStream("fos.txt");
fos.write("hello,Io".getBytes());
fos.write("xiaojingzi".getBytes());
fos.write(382);
fos.write("xiaojingzi".getBytes(), 2, 3);
byte[] bys = {'a', 'b', 'c'};
fos.write(bys);
fos.close(); // A 让流对象变成垃圾,这样就可以被垃圾回收器回收了 B 通知系统去释放与该文件有关的资源
}
加入异常处理的字节输出流操作
FileOutputStream fos = null;
try {
fos = new FileOutputStream("fos1.txt");
fos.write("wa".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close(); // 只有fos不是null才能够调用
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2.2 OutputStream
构造方法:
FileInputStream(File file):
FileInputStream(FileDescriptor fdObj):
FileInputStream(String name):
public static void main(String[] args) throws IOException {
FileInputStream fos = new FileInputStream("fos.txt");
int by = 0;
while((by = fos.read()) != -1) {
System.out.print((char)by);
}
}
文件的复制:可以复制中文,IO流先读再写,没有做任何转换,所以可以做正常显示
public static void main(String[] args) throws IOException {
FileInputStream file = new FileInputStream("fos.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
int by = 0;
while((by = file.read()) != -1) {
fos.write(by);
}
fos.close();
file.close();
}
!字节流适用于任意格式的文件
高效率读取:
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
byte[] bys = new byte[5];
int len = 0;
while((len = fis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
}
最终版:数组的长度一般是1024或者1024的整数倍
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
byte[] bys = new byte[1024];
int len = 0;
while((len = fis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
}
3.3 字节缓冲流
字节流读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java在本身设计时考虑到这样的设计思想,提供了字节缓冲区流
字节缓冲输出流:BufferedOutputStream
构造方法:一般使用默认的缓冲器大小即可
BufferedOutputStream(OutputStream out):使用默认输出缓冲区的缓冲字符输出流
BufferedOutputStream(OutputStream out, int size):指定输出缓冲区的缓冲字符输出流
字节缓冲输入流:BufferedInputStream
BufferedInputStream(InputStream out):使用默认输出缓冲区的缓冲字符输出流
BufferedInputStream(InputStream out, int size):指定输出缓冲区的缓冲字符输出流
例:传输视频文件:
public static void main(String[] args) throws IOException {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream("D:\\Wet_Download\\Baiduyun_Download\\day20\\avi\\20.01_IO流(递归概述和注意事项).avi"));
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream("D:\\Wet_Download\\copy.avi"));
byte[] bys = new byte[1024];
int len;
while((len = buf.read(bys)) != -1) {
bof.write(bys, 0, len);
}
}
3.4 转换流
字符流=字节流+编码表
编码表:由现实世界额字符和对应的数值组成的一张表
ASCII码表,最高位为符号位,其余为数值位
ISO-8859-1,拉丁码表,8位表示一个数据
gb2313:中文编码表
gbk:
Unicode:国际标准码,融合了一个文字,所有文字都用两个字节表示,java使用的都是Unicode
Utf-8:最多用三个字节来表示一个字符,使用尽可能少的字节数来表示一个字符
String类中的编码与解码问题:
String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
byte[] getBytes(string charsetName):使用指定的字符集合将字符串编码为字节数组
windows:默认本地系统编码为GBK
public static void main(String[] args) throws UnsupportedEncodingException {
byte[] bys = "你好".getBytes("GBK");
System.out.println(Arrays.toString(bys));//[-60, -29, -70, -61]
String ss = new String(bys, "GBK");
System.out.println(ss);
byte[] bts = "你好".getBytes("UTF-8");
System.out.println(Arrays.toString(bts));//[-28, -67, -96, -27, -91, -67]
String bs = new String(bts, "UTF-8");
System.out.println(bs);
}
3.4.1 字符流(转换流)
3.4.1 OutputStreamWriter
构造方法:
OutputStreamWriter(OutputStream out):创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs):创建一个使用给定字符集的OutputStreamWriter
OutputStreamWriter(OutputStream out, CharsetEncoder enc):创建一个使用给定字符集编码器的OutputStreamWriter
OutputStreamWriter(OutputStream out, Striing charsetName):创建一个使用命名字符集的OutputStreamWriter
public static void main(String[] args) throws IOException {
OutputStreamWriter osv = new OutputStreamWriter(new FileOutputStream("xiaojignzi.txt"), "UTF-8");
osv.write("中国");
osv.close();
}
接口方法:
public void write(int c):写一个字符
public void write(char[] cbuf):写一个字符数组
public void write(char[] cbuf,int off, int len):写一个字符数组的一部分
public void write(Striing str):写一个字符串
public void write(String str, int off, int len):写一个字符串的一部分
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("xiaojignzi.txt"));
char[] ch = {'a', 'b', 'c'};
osw.write("小镜子");
osw.write(ch);
osw.write(ch, 0, 1);
osw.write("小君子", 0, 1);
osw.flush();
osw.close(); //先刷新后关闭
}
3.4.2 InputStreamReader
构造方法:
InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader
InputSteamReader(InputStream in, Charset cs):创建一个使用给定字符集的InputStreamReader
InputStreamReader(InputStream in, CharsetDecoder dec):创建一个使用给定字符集编码器的InputStreamReader
InputStreamReader(InputStream in, String charsetName):创建一个使用命名字符集的InputStreamReader
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("xiaojignzi.txt"), "GBK");
int ch = 0;
while((ch = isr.read()) != -1) {
System.out.print((char)ch);
}
isr.close();
}
使用什么编码方式写的数据,则以哪种编码方式写数据
接口方法:
public int read():一次读取一个字符
public read(char[] chs):一次读取一个字符数组
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("xiaojingzi.txt"), "UTF-8");
osw.write("xiaojingzi\r\n微信开发者工具");
osw.close();
InputStreamReader ops = new InputStreamReader(new FileInputStream("xiaojingzi.txt"), "UTF-8");
OutputStreamWriter ors = new OutputStreamWriter(new FileOutputStream("xiaojunzi.txt"), "UTF-8");
char[] ch = new char[1024];
int len = 0;
while((len = ops.read(ch)) != -1) {
ors.write(ch, 0, len);
}
ors.close();
ops.close();
}
3.4.3 FileWriter:采用本地的编码方式
OutputStreamWriter的子类
构造方法:
FileWriter(File file):File指定文件名
FileWriter(File file, boolean append):File指定文件名,并确定是否追加
FileWriter(FileDescriptor fd):
FileWriter(String fileName):用String指定文件名
FileWriter(String fileName, boolean append):用String指定文件名,并确定是否追加
3.4.4 FileReader:采用本地的编码方式
InputStreamReader的子类
构造方法:
FileReader(File file):指定的file读取
FileReader(FileDescriptor fd):给定的FileDescriptor读取
FileReader(String fileName):给出读取文件的名称
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("D:\\Wet_Download\\Baiduyun_Download\\04.Python3.5 装饰器编程 18课\\源码\\内置方法.py");
FileWriter fw = new FileWriter("D:\\wang.txt");
char[] ch = new char[1024];
int len = 0;
while((len = fr.read(ch)) != -1) {
fw.write(ch, 0, len);
}
fw.close();
fr.close();
}
3.4.5 字符缓冲输出流:BufferedWriter,如果是追加写,FileWriter("文件名", true)
构造方法:
BufferedWriter(Writer in):创建使用默认大小的输入缓冲区缓冲区字符输入流
BufferedWriter(Writer in, int sz):创建使用指定大小的输入缓冲区字符输入流
接口方法:
public void newLine():根据系统来产生一个换行符
3.4.6 字符缓冲输入流:BufferedReader
构造方法:
BufferedReader(Reader in):创建使用默认大小的输入缓冲区缓冲区字符输入流
BufferedReader(Reader in, int sz):创建使用指定大小的输入缓冲区字符输入流
接口方法:
public String readLine():一次读取一行数据
不包含换行符,读不到新行放回null
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new FileReader("xiaojingzi.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("wanwang.txt"));
char[] chs = new char[1024];
int len = 0;
while((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
br.close();
bw.close();
}
按照行复制文件的案例:
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("xiaojingzi.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("hh.txt"));
String line = null;
while((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
}
复制多级文件的案例
package dat_20;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MoreFile {
public static void main(String[] args) throws IOException {
File srcFile = new File("D:\\简历");
File destFile = new File("D:\\move");
System.out.println(destFile.mkdir());
copyFolder(srcFile, destFile);
}
public static void copyFolder(File srcFile, File destFile) throws IOException {
if(srcFile.isDirectory()) {
File newFolder = new File(destFile, srcFile.getName());
newFolder.mkdir();
File[] fileArray = srcFile.listFiles();
for(File file : fileArray) {
copyFolder(file, newFolder);
}
}else {
File newFile = new File(destFile, srcFile.getName());
copyFile(srcFile, newFile);
}
}
public static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len = 0;
while((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
学生类根据总分从分高到低排序:
public static void main(String[] args) throws IOException{
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
int num1 = o2.getSum() - o1.getSum();
int num2 = num1 == 0 ? o2.getChinese() - o1.getChinese() : num1;
int num3 = num2 == 0 ? o2.getMath() - o1.getMath() : num2;
int num4 = num3 == 0 ? o2.getName().compareTo(o1.getName()) : num3;
return num4;
}
});
for(int x = 0; x < 5; x++){
Student st = new Student();
Scanner sc = new Scanner(System.in);
System.out.println("please input student grade" + x);
System.out.println("please input student name");
st.setName(sc.nextLine());
System.out.println("please input chinese grade");
st.setChinese(sc.nextInt());
System.out.println("please input math grade");
st.setMath(sc.nextInt());
System.out.println("please input english grade");
st.setEnglish(sc.nextInt());
ts.add(st);
}
BufferedWriter bw = new BufferedWriter(new FileWriter("Student"));
bw.write("学生成绩如下:");
bw.newLine();
bw.flush();
bw.write("姓名,语文成绩,数学成绩,英语成绩");
bw.newLine();
bw.flush();
for(Student s : ts){
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
System.out.println("学生信息存储完毕");
}
模拟BufferedReader 的readLine()功能
public class MyBufferedReader {
private Reader r;
public MyBufferedReader(Reader r){
this.r = r;
}
public String readLine() throws IOException{
StringBuffer sb = new StringBuffer();
int ch = 0;
while((ch = r.read()) != -1){
if(ch == '\r'){
continue;
}else if(ch == '\n'){
return sb.toString();
}else{
sb.append((char)ch);
}
}
if(sb.length() > 0){
return sb.toString();
}
return null;
}
public void close() throws IOException{
this.r.close();
}
}
3.4.7 LineNumberReader(BufferedReader的子类)
int getLineNumber():获取行号
void setLineNumber(int):设置行号
public static void main(String[] args) throws IOException{
LineNumberReader lnr = new LineNumberReader(new FileReader("s"));
lnr.setLineNumber(10);
String line = null;
while((line = lnr.readLine()) != null){
System.out.println(lnr.getLineNumber() + ":" + line);
}
lnr.close();
}
3.4.8 为了保证文件只创建一次,可以使用静态代码块
private static File file = new File("文件名");
static {
try{
file.createNewFile();
}catch(IOException e){
System.out.println("创建文件夹失败"); }
}
3.5 操作基本数据类型的流
3.5.1 DataInputStream:数据输出流允许应用程序将适当方式将基本Java数据类型输入流中,应用数据可以使用数据输入流将数据读入
构造方法:DataOutputStream(OutputStream out):创建一个新的数据输入流,将数据写入指定基础输出流
3.5.2 DataOutputStream:数据输出流使应用程序以便携式方式将原始Java数据类型写入输出流。 然后应用程序可以使用数据输入流来读取数据。
构造方法:DataInputStream(InputStream input):创建一个新的数据输出流,将数据读出
public static void main(String[] args) throws IOException{
//write();
read();
}
public static void write() throws IOException{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
dos.writeByte(10);
dos.writeShort(100);
dos.writeInt(1000);
dos.writeChar('a');
dos.writeFloat(23.878f);
dos.writeDouble(343.38);
}
public static void read() throws IOException{
DataInputStream dip = new DataInputStream(new FileInputStream("dos.txt"));
byte b = dip.readByte();
short s = dip.readShort();
int i = dip.readInt();
char c = dip.readChar();
float f = dip.readFloat();
double d = dip.readDouble();
dip.close();
System.out.println((int)c);
}
3.6 内存操作流
操作字节数组:
ByteArrayInputStream:包含了一个内部缓冲区,该缓冲器可以从流中读取字节,内部计数器跟踪read方法要提供的下一个字节,关闭ByteArrayInputStream无效,此类中的方法在关闭此流后仍可以被调用,而不会产生任何的IOException.
ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个byte数组,缓冲区会随着数据的不断写入自动增长,可以使用toByteArray()和toString()获取数据
操作字符数组:
CharArrayReader
CharArrayWrite
操作字符串:
StringReader
StringWriter
public static void main(String[] args) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(int x = 0; x < 20; x++){
baos.write(("hello" + x).getBytes());
}
byte[] bys = baos.toByteArray();
System.out.println(Arrays.toString(bys));
//不需要释放资源
ByteArrayInputStream bais = new ByteArrayInputStream(bys);
int by = 0;
while((by = bais.read()) != -1){
System.out.print((char)by);
}
}
3.7 打印流:
字节打印流:PrintStream
字符打印流:PrintWriter:
特点:
1. 只能操作目的地,不能操作数据
2. 可以操作任意类型的数据
3. 如果启动了自动刷新,可以自动刷新
4. 可以操作文件的流
public static void main(String[] args) throws IOException{
PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"), true);//带true实现了自动刷新的功能,但是需要调用println方法才可以
pw.write("hello");
pw.write("world");
pw.write("java");
//pw.close();
pw.print(true);
pw.print(100);
pw.print("heool");
pw.print("wangjing");
pw.println("xiaojingzi"); //实现了换行
/*println相当于实现了
*write();
*newLine();
*flush();
*三种方法的操作
*/
pw.close();
}
使用打印流实现复制文本文件
public static void main(String[] args) throws IOException{
/*BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java"));
BufferedReader br = new BufferedReader(new FileReader("Student"));
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();*/
BufferedReader br = new BufferedReader(new FileReader("Student"));
PrintWriter pw = new PrintWriter(new FileWriter("copy.java"), true);
String line = null;
while((line = br.readLine()) != null){
pw.println(line);
}
br.close();
pw.close();
}
3.8 标准输入输出流
System类中有两个成员变量:
public static final InputStream in "标准"输入流
public static final PrintStream out "标准"输出流
InputStream is = System.in;
PrintStream ps = System.out;
public static void main(String[] args){
//本质是把IO流输出到控制台(默认输出设备控制台,输入设备是键盘)
System.out.println("helloworld");
PrintStream ps = System.out;
ps.println("xiaojignzi");
//ps.print(); 报错
ps.println();
}
键盘录入数据:
A:main方法的args接收数据
B:Scanner(JDK5以后)
Scanner sc = new Scanner(System.in)
String s = sc.nextLine();
注:Scanner容易出现的小问题
先获取Int再获取字符串时,导致输入一个Int以后便不需要再输入,然后字符串读取的只是回车符。
C:通过字符缓冲流包装标准的输入流实现:BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); /*上述的语句等价为
* InputStream is = System.in;
* InputStreamReader isr = new InputStreamReader(is);
* BufferedReader br = new BufferedReader(isr);
*/
System.out.println("请输入一个字符串");
String line = br.readLine();
System.out.println("您输入的字符串是:" + line);
System.out.println("请输入一个整数");
int i = Integer.parseInt(br.readLine());
System.out.println("您输入的整数是:" + i);
}
输出数据到控制台
public static void main(String[] args) throws IOException{
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
/*
* PrintStream ps = System.out;
* OutputStream os = ps; (OutputStream os = System.out;) 多态
* OutputStreamWriter osw = new OutputStreamWriter(os)
* BufferedWriter bw = new BufferedWriter(osw);
*/
bw.write("hello");
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("xiaojignzi");
bw.flush();
}
3.9 RandomAccessFile
RandomAccessFile类不属于任何流,是Object类的子类,融合了InputStream和OutputStream的功能,支持对随机访问文件的读取和写入
有四种模式,常用是rw可以同时读写,文件不存在将尝试创建
public static void main(String[] args) throws IOException {
write();
read();
}
public static void read() throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
int i = raf.readInt();
System.out.println(i);
System.out.println("当前文件的指针是:" + raf.getFilePointer()); //4 int 类型数据占四个字节
char ch = raf.readChar();
System.out.println(ch);
System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); //6 char 类型数组占两个字节
String s = raf.readUTF();
System.out.println(s);
System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); //14 先读取两个字节,再读取后面的字节
raf.seek(4);
ch = raf.readChar();
System.out.println(ch); //a
raf.close();
}
public static void write() throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
raf.writeInt(100);
raf.writeChar('a');
raf.writeUTF("小哈");
raf.close();
}
3.10 SequenceInputStream表示其它输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到文件的末尾,接着从第二个输入流读取,依次类推,直到最后一个输入流文件的末尾为止
合并流读取两个文件的内容复制到一个文件中
public static void main(String[] args) throws IOException{
InputStream is1 = new FileInputStream("dos.txt");
InputStream is2 = new FileInputStream("pw.txt");
SequenceInputStream sis = new SequenceInputStream(is1, is2);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy"));
byte[] bys = new byte[1024];
int len = 0;
while((len = sis.read(bys)) != -1){
bos.write(bys, 0, len);
}
bos.close();
sis.close();
}
合并多个文件:
public static void main(String[] args) throws IOException{
Vector<InputStream> v = new Vector<InputStream>();
InputStream s1 = new FileInputStream("copy");
InputStream s2 = new FileInputStream("dos.txt");
InputStream s3 = new FileInputStream("copy.java");
v.add(s1);
v.add(s2);
v.add(s3);
Enumeration<InputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("xiaojigzi"));
byte[] byt = new byte[1024];
int len = 0;
while((len = sis.read(byt)) != -1){
bos.write(byt, 0, len);
}
sis.close();
bos.close();
}
3.11 序列化与反序列化流
序列化流:ObjectOutputStream:将JAVA对象的基本数据类型写入OutputStream,可以使用ObjectInputStream读取(重构对象),可以使用文件来实现对象的持久存储,如果流是网络套接字节流,可以再另一台主机或者另一个进程中重构对象
反序列化流:ObjectInputStream
NotSerializableException:未序列化异常
类通过实现java.io.Serializable 接口以启用序列化功能,未实现此接口无法进行任何的序列化和反序列化。该接口中没有任何的方法需要实现。没有方法的接口被称为标记接口。
private static final long serialVersionUID = 1087170578858793875L;产生序列化
public static void main(String[] args) throws IOException, ClassNotFoundException{
//write();
read();
}
public static void write() throws IOException, IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("xiao"));
Person p = new Person("wangjing", 20);
oos.writeObject(p);
oos.close();
}
public static void read() throws IOException, ClassNotFoundException{
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("xiao"));
Object obj = oos.readObject();
oos.close();
System.out.println(obj); // 多态调用的是子类的方法
}
如何不序列化对象的成员变量:使用transient修饰 private transient int age;
3.12 Properties类:属性集合类,是一个可以和IIO流相结合的集合类
表示一个持久的属性集,Properties可以保存在流中或者从流中加载,属性列表中每个键和对应的值都是一个字符串
Properties作为map集合使用
public static void main(String[] args){
Properties prop = new Properties();
prop.put("it001", "hello");
prop.put("it002", "world");
prop.put("it003", "java");
Set<Object> set = prop.keySet();
for(Object key : set){
Object value = prop.get(key);
System.out.println(key + "-----" + value);
}
}
Properties的特殊功能使用
public Object setProperty(String key, String value):添加元素
public String getProperty(String key):获取元素
public Set<String> stringPropertyNames():获取所有键的集合
public static void main(String[] args){
Properties prop = new Properties();
prop.setProperty("张三", "30");
prop.setProperty("李四", "40");
prop.setProperty("王五", "30");
Set<String> set = prop.stringPropertyNames();
for(String key : set){
String value = prop.getProperty(key);
System.out.println(key + "----" + value);
}
}
Properties与IO流结合使用
public void load(Reader reader):把文件中的数据读取到集合中
public void store(Writer writer, String comments):把集合中的数据存储到文件
public static void main(String[] args) throws IOException{
myStore();
}
public static void myLoad() throws IOException{
Properties prop = new Properties();
Reader r = new FileReader("prop.txt");
prop.load(r);
r.close();
System.out.println("prop" + prop);
}
public static void myStore() throws IOException{
Properties prop = new Properties();
prop.setProperty("wangjing", "30");
prop.setProperty("ixaoxiao", "10");
prop.setProperty("wang", "30");
Writer w = new FileWriter("wang.txt");
prop.store(w, "heoolworld"); //"heoolworld"是注释
w.close();
}
判断文件中是否有指定的键,如果有就修改值
public static void main(String[] args) throws IOException{
Properties prop = new Properties();
Reader r = new FileReader("wang.txt");
prop.load(r);
r.close();
Set<String> set = prop.stringPropertyNames();
for(String key : set){
if("wang".equals(key)){
prop.setProperty(key, "100"); // 替换
break;
}
}
Writer w = new FileWriter("wang.txt");
prop.store(w, null);
w.close();
}
3.13 NIO包下的IO流
JDK4出现NIO,新IO和传统的IO有相同的目的,都是用于进行输入输出的额,但新的IO使用了不同的方式来处理输入输出的,采用内存映射文件的方式。将文件或者文件的一段区域映射到内存中,就可以像访问内存一样的来访问文件了,这样的效率比旧的IO要高很多。
Path:路径
Paths:有一个静态方法返回一个路径
public static Path get(URI uri)
Files:提供了静态方法供我们使用
public static long copy(Path source, OutputStream out)
public static Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options)
public static void main(String[] args) throws IOException, IOException{
Files.copy(Paths.get("prop.txt"), new FileOutputStream("copy.java")); // 复制文件
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("wrold");
array.add("java");
Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
}
|