黑马程序员之 ---IO

 ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

异常:

概念: java程序运行中 出现的错误情况

异常的分类:

throwable:

|- Error

|- Exception 编译期异常

|- RuntimeExcecptin 运行期异常

异常的处理方式:

方式1

捕获异常

try {

可能出现异常的代码

} catch (异常类名  对象名) {

异常的处理代码

} finally {

一定要执行的代码(特点情况不会执行[JVM退出了])

}

方式2:

抛出异常

修饰符 返回值类型 方法名(参数列表) throws 异常类名 {

code...

}

注意: 异常类名可以是多个, 之间使用"," 逗号分隔

自定义异常:

与 普通的异常 使用方式一样

格式

class 自定义异常类 extends Exception {

//空参数构造方法

public 异常类名() {

super();

}

//String参数的构造方法

public 异常类名(String s) {

super(s);

}

}  

throw 抛出一个异常

异常注意事项

子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

 

面试题:

final\ finally \ finalize 三者的区别?

final: 最终的意思

它修饰的类, 最终类,不能被其他类所继承

它修饰的方法,最终方法, 子类不能重写该方法

它修饰的变量,为常量, 值不能改变

finally: try..catch..finally异常处理语句中的一部分

用来释放资源, 如文件的关闭,对象设置为null等操作

finalize: Object类中方法

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法

throw 与 throws 的区别?

throws

用在方法声明后面,跟的是异常类名

可以跟多个异常类名,用逗号隔开

表示抛出异常,由该方法的调用者来处理

throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

用在方法体内,跟的是异常对象

只能抛出一个异常对象

表示抛出异常,由方法体内的语句处理

throw则是抛出了异常,执行throw则一定抛出了某种异常?

File

构造方法:

public File(String pathname)   根据指定的文件路径或者目录创建一个file对象

public File(String parent, String child) 根据给定的目录路径,和给定的子目录路径或者文件路径创建一个file对象

public File(File parent, String child)根据给定的父类file对象和给定的子目录路径或者文件路径创建一个file对象

方法:

public boolean mkdir()  创建单层文件夹,如果指定的文件夹不存在并成功地创建,则返回true;如果指定的文件夹已存在则返回false

public boolean mkdirs() 创建多层文件夹

public boolean createNewFile()创建文件    如果指定的文件不存在并且创建成功,则返回true; 如果创建的文件已存在则返回false

 

注意:创建文件还是文件夹,看的是方法与文件名无。

 

public boolean delete()   删除此目录表示的文件或者目录(目录必须为空才能删除)

public boolean renameTo(File dest)  重新命名此抽象路径名表示的文件, 如果源File对象与目的地File对象在同一个文件夹中则为重命名功能,

如果源File对象与目的地File对象不再同一个文件夹中则为剪切和重名民功能。

public File getAbsoluteFile()  File对象的绝对路径

   public String getPath()  File对象的相对路径

   public String getName() 获取源File对象的名字

   public long lastModified()  获取源File对象的最后修改时间

   public long length()  获取文件此文件路径表示的文件的长度

public boolean isDirectory()  判断是否为文件夹

public boolean isFile()  判断是否为文件

public boolean exists()  判断file对应的文件呢或文件目录是否存在

public boolean canRead()  判断是否可读

public boolean canWrite() 判断是否可写

public boolean isHidden() 判断是否隐藏

public static File[] listRoots()  列出可用的文件系统根

public String[] list()   返回指定源File对象中所有的文件夹和文件名称

public File[] listFiles() 返回指定源File代表的文件夹中所有的文件夹和文件的File对象(绝对路径)

例题:输出 E:\\resource 目录中 所有.java文件的名称

public class FileTest {

public static void main(String[] args) {

//1: 封装File对象

File file = new File("E:\\resource");

//2: 获取当前目录下 所有的File对象

File[] files = file.listFiles();

//3: 遍历,得到每一个File对象

for (File f : files) {

//得到File对象的名字

String name = f.getName();// FilePath.java

//判断是否是 .java文件

if (name.endsWith(".java")) {

System.out.println(name);

}

}

}

}

递归:

    概述:在方法的内部,调用本方法

    使用递归的前提:

        1:指定递归规则

2: 出口条件

    使用递归的注意事项:

1:递归次数不能过多, 会报出栈溢出异常

递归案例:

1斐波那契数列

public class DiguiTest2 {

public static void main(String[] args) {

//int n = 5;

//int n = 7;

int n = 20;

int num = func(n);//n=5,7,20

System.out.println(num);

}

 

public static int func(int n) {

if (n == 1 || n == 2) {

return 1;

} else {

return func(n-1)  + func(n-2); 

}

}

}

2、删除带内容的目录

public class DiguiTest4 {

public static void main(String[] args) {

//1: 封装目录File对象  E:\resource

File pathFile = new File("E:\\resource");

deletePathFiles(pathFile);

}

 

// 获取当前目录下,所有的FIle对象

public static void deletePathFiles(File pathFile) {

if (pathFile == null) {

return;

}

//2:获取当前目录下,所有的FIle对象

File[] files = pathFile.listFiles();

//3: 通过遍历,得到每一个File对象

for (File file : files) {

//4: 判断当前File对象 是否是文件夹

if (file.isDirectory()) {

//文件夹

//递归,回到步骤2

deletePathFiles(file);

} else {

//文件

//直接删除

System.out.println(file.getAbsolutePath() +"---"+ file.delete());

}

}

//删除文件夹

System.out.println(pathFile.getAbsolutePath() + "---" + pathFile.delete());

}

}

 

IO流:

    概述:用来处理设备之间的数据传输 (如上传文件、下载文件)

    (InputOutput)IO流分类:

根据流向划分:

    输入流: 读取数据

    输出流: 写出数据

根据类型划分:

    字节流:

基本的流:

字节输入流(InputStream):读取数据

字节输出流(OutputStream):写出数据

高效的流:

字节缓冲输入流(BufferedInputStream): 读取数据

字节缓冲输出流(BufferedOutputStream): 写出数据

    字符流:

    字符输入流(Reader):读取数据

字节输出流(Writer):写出数据

字节输出流(OutputStream):

    构造方法:

public OutputStream(String path)

public OutputStream(File path)

    方法:

        public void write(byte by) 写入一个字节

public void write(byte[] buffer) 写入一个字节数组

public void write(byte[] buffer, int start, int len)写入一个字节数组的一部分

public void close() : 释放与流对象相关的资源

    使用字节输出流的步骤:

1: 打开文件(创建字节输出流对象)

2:  写出数据

3:  关闭文件(释放资源)

    数据实现换行和追加写入:

windows : \r\n

Unix Linux : \n

Mac OS : \r

public OutputStream(String path, boolean append)

public OutputStream(File path, boolean append)

 

字节输入流(InputStream):读取数据

    构造方法:

public InputStream(String path)

public InputStream(File path)

    方法:

public int read() : 读取一个字节

public int read(byte[] buffer): 读取一个字节数组, 返回实际读取到的字节数量

    使用字节输入流的步骤:

1: 打开文件(创建字节输入流对象)

2:  读取数据

3:  关闭文件(释放资源)

    读取数据的两种方式:

1: 一次一个字节

int by = 0;

while ((by = fis.read()) != -1) {

    SOP(by);

}

2:  一次一个字节数组

byte[] buffer = new byte[1024];

int len = 0;

while ((len = fis.read(buffer)) != -1) {

    SOP(new String(buffer, 0, len));

}

字节流复制案例:

1、通过字节流 完成 图片的复制

public class FileInputStreamTest2 {

public static void main(String[] args) throws IOException {

//数据源 -- 读数据 -- FileInputStream

FileInputStream fis = new FileInputStream("E:\\resource\\IMG_1692.jpg");

//目的地 -- 写数据 -- FileOutputStream

FileOutputStream fos = new FileOutputStream("1692.jpg");

//创建一个变量,用来记录每次读到的字节

int ch = -1;

//读数据

while ((ch = fis.read()) != -1) {

//写数据

fos.write(ch);

}

//关闭流

fos.close();

fis.close();

}

}

2、字节流一次读写一个字节数组,复制文本文件   

public class FileIntputStreamTest {

public static void main(String[] args) throws IOException {

//封装数据源

FileInputStream fis = new FileInputStream("E:\\resource\\UIUtil.java");

//封装目的地

FileOutputStream fos = new FileOutputStream("UIUtil.java");

//一次读写一个字节数组

byte[] buffer = new byte[1024];

//定义一个变量,用来记录每一次读到的新字节的个数

int len = -1;

//读数据

while ((len = fis.read(buffer)) != -1) {

//写数据

fos.write(buffer, 0, len);

}

//关闭流

fos.close();

fis.close();

}

}

字节缓冲输出流(BufferedOutputStream): 写出数据

    构造方法:

public BufferedOutputStream(OutputStream os)

public BufferedOutputStream(OutputStream os, int size)

    使用字节缓冲输出流的步骤:

1: 打开文件(创建字节缓冲输出流)

2:  写出数据

3:  关闭文件(释放资源)

字节缓冲输入流(BufferedInputStream): 读取数据

    构造方法:

public BufferedInputStream(InputStream os)

public BufferedInputStream(InputStream os, int size)

 

    使用字节缓冲输入流的步骤:

1: 打开文件(创建字节缓冲输入流)

2:  读取数据

3:  关闭文件(释放资源)

高效流案例:

字节流四种方式复制avi并测试效率

/*

 * 复制视频

 *  4种方式             共耗时(毫秒)

 *  基本的字节流,一次一个字节    115471

 *  基本的字节流,一次一个字节数组          249

 *  高效的字节流,一次一个字节     717

 *  高效的字节流,一次一个字节数组  40

 */

public class CopyVideo {

public static void main(String[] args) throws IOException {

long start = System.currentTimeMillis();

//method1("少女时代.flv", "少女时代1.flv");

method2("少女时代.flv", "少女时代2.flv");

//method3("少女时代.flv", "少女时代3.flv");

//method4("少女时代.flv", "少女时代4.flv");

 

long end = System.currentTimeMillis();

System.out.println(end - start);

}

//高效字节数组

public static void method4(String str, String str2) throws IOException {

//数据源

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(str));

//目的地

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(str2));

//读取数据

byte[] buffer = new byte[1024];

int len = -1;

while((len = bis.read(buffer)) != -1){

//x

bos.write(buffer, 0, len);

}

//关闭

bis.close();

bos.close();

}

//高效字节

public static void method3(String str, String str2) throws IOException {

//数据源

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(str));

//目的地

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(str2)) ;

//读取数据

int ch = -1;

while((ch = bis.read()) != -1){

//

bos.write(ch);

}

//关闭

bis.close();

bos.close();

}

 

public static void method2(String str, String str2) throws IOException {

//数据源

FileInputStream fis = new FileInputStream(str);

//目的地

FileOutputStream fos = new FileOutputStream(str2);

//读取数据

byte[] buffer = new byte[1024];

int len = -1;

while((len = fis.read(buffer)) != -1){

//

fos.write(buffer, 0, len);

}

//关闭

fis.close();

fos.close();

}

 

public static void method1(String str, String str2) throws IOException {

//数据源

FileInputStream fis = new FileInputStream(str);

//目的地数据

FileOutputStream fos = new FileOutputStream(str2);

//

int ch = -1;

while((ch = fis.read()) != -1){

//

fos.write(ch);

//System.out.println(fos.write(ch));

}

//关闭

fis.close();

fos.close();

}

}

  

IO流的分类:

流向分类:

输入流

输出流

类型分类:

字节流

字节输入流:

InputStream 字节输入流 超类

|- FileInputStream 基本的流

|- BufferedInputStream 高效的流

字节输出流:

OutputStream 字节输出流 超类

|- FileOutputStream 基本的流

|- BufferedOutputStream 高效的流

字符流

字符输入流:

Reader 字符输入流 超类

|- InputStreamReader 转换流  属于 字符输入流

|- FileReader 基本的流

|- BufferedReader 高效的流

字符输出流:

Writer 字符输出流 超类

|- OutputStreamWriter 转换流 属于 字符输出流

|- FileWriter 基本的流

|- BufferedWriter 高效的流

IO流中常见的方法:

如何实现文件中数据的追加?

构造方法中实现, 构造方法的第二个参数设置为true

FileOutputStream

FileWriter

读数据:

读字节:

int read() 一个字节

int read(byte[] buffer) 一个字节数组

读字符

int read(); 一个字符

int read(char[] buffer) 一个字符数组

String readLine() 一行字符串(高效字符输入流中使用)

写数据:

写字节:

void write(int ch) 写入一个字节

void write(byte[] buffer) 写入一个字节数组

void write(byte[] buffer, int startIndex, int len) 写入字节数组的一部分

写字符:

void write(int ch) 写入一个字符

void write(char[] buffer) 写入一个字符数组

void write(char[] buffer, int startIndex, int len) 写入字符数组的一部分

void write(String str) 写入一个字符串

void write(String str, int startIndex, int len) 写入字符串的一部分

其他方法:

void flush() 刷新

void close() 关闭

void newLine()换行高效字符输出流特有方法

字符编码表:

编码表

由字符及其对应的数值组成的一张表

常见的编码表:

ASCII: 7位来表示一个数据

ISO-8859-1: 在西欧使用,用8位来表示一个数据

GB2312: 简体中文, 使用2个字节来表示一个汉字

GBK:  简体中文

GB18030:  简体中文替代GBK

BIG5: 繁体中文, 台湾、香港 使用

Unicode: 国际码,统一码2个字节表示一个数据java中使用的码表就是Unicode

utf-8:国际码,统一码表示一个数据,所使用的字节数是变化的,使用1-4位字节来表示一个数据,  表示一个汉字使用3个字节 

编码:把看懂的 转换成 看不懂的

解码:把看不懂的 转换成 看懂的

转换流OutputStreamWriter

把基本的字节流,使用给定的编码表,进行数据的编码

转换流InputStreamReader

把基本的字节流,使用给定的编码表,进行数据的解码

LineNumberReader: 带有行号的字符缓冲流

public int getLineNumber()获得当前行号。 

public void setLineNumber(int lineNumber)设置当前行号。 

案例:

1转换流复制文本文件

public class copyTextFile {

public static void main(String[] args) throws IOException {

//数据源

InputStreamReader isr = new InputStreamReader(new FileInputStream("面试题.txt"));

//目的地

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("copyText.txt"));

//读数据

char[] buffer = new char[1024];

int len = -1;

while ((len = isr.read(buffer)) != -1) {

//写数据

osw.write(buffer, 0, len);

}

//关闭

isr.close();

osw.close();

}

}

2FileWriterFileReader复制文本文件

public class copyTextFile2 {

public static void main(String[] args) throws IOException {

//数据源

FileReader fr = new FileReader("面试题.txt");

//目的地

FileWriter fw = new FileWriter("copyText.txt");

//读数据

int ch = -1;

while ((ch = fr.read()) != -1) {

//写数据

fw.write(ch);

}

//关闭流

fr.close();

fw.close();

}

}

3把集合中的数据存储到文本文件

public class CollectionToFile {

public static void main(String[] args) throws IOException {

//1:集合

ArrayList<String> list = new ArrayList<String>();

//2:向集合中添加字符串数据

list.add("班长");

list.add("日天");

list.add("杜泽宇");

//3:创建一个字符输出流  BufferedWriter

BufferedWriter bw = new BufferedWriter(new FileWriter("arraylist.txt"));

//4:遍历,获取到集合中每一个元素

Iterator<String> it = list.iterator();

while (it.hasNext()) {

String str = it.next();

//5:把每个元素 写到 文件中

bw.write(str);

bw.newLine();

bw.flush();

}

//6:关闭流

bw.close();

}

}

/4随机获取文本文件中的姓名

public class GuessNameTest {

public static void main(String[] args) throws IOException {

//2: 创建字符输入流BufferedReader, 读数据 

BufferedReader br = new BufferedReader(new FileReader("name.txt"));

//3: 创建一个ArrayList集合

ArrayList<String> names = new ArrayList<String>();

//4: 把每个同学的名字 存储到集合中

String line = null;

while ((line = br.readLine()) != null) {

names.add(line);

}

//5: 随机的在集合中获取一个元素

//a: 产生一个 0 -- names.size()-1的随机数

for (int i = 0; i < 3; i++) {

int randomIndex = (int)(Math.random() * (names.size()));

//6: 显示结果

System.out.println(names.get(randomIndex));

}

}

}

/5复制单级文件夹

public class CopyDir {

public static void main(String[] args) throws IOException {

//1: 封装数据源 (文件夹)

File srcPath = new File("E:\\resource无子目录");

//2: 封装目的地(文件夹)

File destPath = new File("NoDir");

//创建目的地文件夹

destPath.mkdir();

//获取数据源中所有的File对象,得到每个File对象

File[] files = srcPath.listFiles();

//3: 获取到数据源所对应的目录中,每一个File对象

for (File file : files) {

String name = file.getName();

//4: 文件的复制,

File dest = new File(destPath, name);

copyFile(file, dest);

}

}

//文件的复制

public static void copyFile(File src, File dest) throws IOException {

//数据源

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));

//目的地

BufferedOutputStream bos =new BufferedOutputStream(new FileOutputStream(dest));

//

byte[] buffer = new byte[1024];

int len = -1;

while ((len = bis.read(buffer)) != -1) {

//

bos.write(buffer, 0, len);

}

//关闭流

bis.close();

bos.close();

}

}

/6复制多级文件夹

public class CopyDirs {

public static void main(String[] args) throws IOException {

//1: 封装数据源

File srcPath = new File("E:\\date");

//2: 封装目的地

File destPath = new File("YesDir");

//复制文件夹

copyDirectorys(srcPath, destPath);

}

//复制文件夹

public static void copyDirectorys(File srcPath, File destPath) throws IOException {

//3: 创建目的地文件夹

destPath.mkdir();

//4: 获取到数据源中所有的File对象

File[] files = srcPath.listFiles();

//5: 遍历,获取到每一个File对象

for(File file : files) {

//6:  判断当前File对象 是否为 文件夹

if (file.isDirectory()) {

String name = file.getName();

File dest = new File(destPath, name);

//递归,封装好目的地,回到步骤3

copyDirectorys(file, dest);

} else {

//文件

//得到新文件的名称[File对象]

String name = file.getName();

File dest = new File(destPath, name);

//开始复制文件

copyFile(file, dest);

}

}

}

//复制文件

public static void copyFile(File src, File dest) throws IOException {

//数据源

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));

//目的地

BufferedOutputStream bos =new BufferedOutputStream(new FileOutputStream(dest));

//

byte[] buffer = new byte[1024];

int len = -1;

while ((len = bis.read(buffer)) != -1) {

//

bos.write(buffer, 0, len);

}

//关闭流

bis.close();

bos.close();

}

}

打印流概述

字节流打印流

字符打印流

打印流特点

只能操作目的地,不能操作数据。

可以操作任意类型的数据。

如果启动了自动刷新,能够自动刷新。

可以操作文件的流

案例:

通过打印流,完成文本文件的复制

    public class CopyText {

public static void main(String[] args) throws IOException {

//数据源

BufferedReader br = new BufferedReader(new FileReader("问题.txt"));

//目的地

PrintWriter pw = new PrintWriter("目的地.txt");

//

String line= null;

while ((line = br.readLine()) != null) {

//

//pw.write(line);

//pw.newLine();

//pw.flush();

pw.println(line);

}

//关闭流

br.close();

pw.close();

}

}

 

序列化流new出来的对象 写到流所对应的文件中

ObjectOutputStream

反序列化流: 从流所对应的文件中, 把对象读出来

ObjectInputStream

序列化流/反序列化流 除了可以存储在文件中, 还可以实现数据在网络中传输

注意: 只能将支持 java.io.Serializable 接口的对象写入流中

writeObject 方法用于将对象写入流中

Properties集合

属于Map集合它是Hashtable的子类

与 IO 流进行 交互的一个集合

键和值的数据类型 都是String类型

构造方法:

public String getProperty(String key) 根据键 找 对应的值

public String getProperty(String key, String defaultValue)根据键 找 对应的值如果,没有找到对应的值,返回defaultValue

public Enumeration<?> propertyNames() 获取集合中所有的键

public Object setProperty(String key, String value)调用 Hashtable 的方法 put

 

方法:

public void list(PrintStream out)把集合中的数据 写到流 所对应的文件中

public void list(PrintWriter out)把集合中的数据 写到流 所对应的文件中

 

public void load(InputStream inStream) 把流 所对应的文件中的数据  存储到指定的Properties 集合中

public void load(Reader reader) 把流 所对应的文件中的数据  存储到指定的Properties 集合中

 

public void store(OutputStream out, String comments) 把集合中的数据 写到流 所对应的文件中

public void store(Writer writer, String comments) 把集合中的数据 写到流 所对应的文件中

参数comments - 属性列表的描述

案例:

我有一个文本文件prop.txt,我知道数据是键值对形式的,但是不知道内容是什么。

 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其实为”100

public class PropertiesTest {

public static void main(String[] args) throws IOException {

//1: 创建一个空集合

Properties prop = new Properties();

//2: 把文件中的数据 读取出来, 存储到集合

FileInputStream fis = new FileInputStream("prop.txt");

prop.load(fis);//把文件中的内容 加载到集合中

fis.close();

//3: 遍历集合,判断有没有键为"lisi"

Set<Object> keys = prop.keySet();

for (Object key : keys) {

if ("lisi".equals(key)) {

//有: 把list对应的值 该为100

//prop.put(key, 100);//不行

prop.setProperty((String)key, "100");

}

}

System.out.println(prop);

//4: 把集合  存储到流所对应的文件中

FileOutputStream fos = new FileOutputStream("prop.txt");

prop.store(fos, "20150322 classes");

fos.close();

}

}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值