黑马程序员—API-Io

------- android培训java培训、期待与您交流! ----------

IO:包含

 

异常、File、递归、字节流、转换流、字符流、其他流。

 

异常的概述:异常就是Java程序在运行过程中出现的错误。
异常由来:问题也是现实生活中一个具体事务,也可以通过java 的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。

我们见过的异常,角标越界异常,空指针异常。

 异常的分类:

    Throwable:

    1)Error 错误 (我们解决不了, 只能重写设计java代码)

    2)Exception 异常 ( 编译期异常,学习它的解决方式)

     a)RuntimeException 运行期异常 (可以通过代码编写的更加严谨来避免)

        不是 RuntimeException 子类的异常, 就属于  Exception 异常

异常案例:

public class ExceptionDemo {

public static void main(String[] args) {

//System.out.println( 3/0 );//java.lang.ArithmeticException: / by zero

int[] arr = {1,2,3};

System.out.println(arr[3]);//java.lang.ArrayIndexOutOfBoundsException: 3

//编译期异常

SimpleDateFormat sdf = new SimpleDateFormat();

try {

Date date = sdf.parse("2014-12-12");

} catch (ParseException e) {

e.printStackTrace();

}

}

}

JVM的默认处理方案:

  当程序运行的过程中,一旦出现了异常,会有2种解决方式

  方式1: 在程序代码中,自己把异常解决处理掉, 程序代码 继续向下执行 方式2: 我不知道该如何处理异常,把这个异常交给Java虚拟机,由JVM帮助我们处理该异常

Java虚拟机是如何帮助我们处理异常的?

   1: 当代码执行的过程中,出现了异常,java虚拟机会把正在运行的程序 结束掉, 后面的代码不会运行。

   2: 在控制台会打印出异常的信息。

 异常处理的方式:

   方式1: 出现了异常,我自己解决问题。

   try...catch...finally

   格式:

  try{

   可能出现异常的代码

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

   该异常处理的代码

   } finally {

   我一定要执行的代码 (特殊情况会不执行,catch中jvm停止工作,如:System.exit(0))

   }

  

   方式2: 出现了异常,我不知道如何解决, 我把异常交给其他人帮我解决

   throws

单个异常处理案例:

public class ExceptionDemo3 {

public static void main(String[] args) {

try{

System.out.println(3/0);

//ArithmeticException  算术异常

//当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。 

} catch (ArithmeticException e) {

System.out.println("对不起,除数不能为0");

}

System.out.println("over");

}

}

 多个异常 如何处理?

   方式1:  每一个异常 单独处理

  

   方式2:  所有的异常, 统一处理 (推荐)

   特点: 当try语句中 处理了异常的时候,会执行对应的catch语句中的代码, 然后 执行 try...catch语句 外 后面的代码

   注意,try语句中,后面的代码不再执行

  

  

   try {

   可能出现异常的代码

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

   ...

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

   ...

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

   ...

   } 

 public class ExceptionDemo4 {

public static void main(String[] args) {

/*  

 方式1

int x = 5;

int y = 0;

try{

System.out.println(x/y);//ArithmeticException

} catch (ArithmeticException e) {

System.out.println("除数不能为0");

}

int[] arr = {1,2,3};

try {

System.out.println(arr[3]);//ArrayIndexOutOfBoundsException

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("数组角标越界异常");

}

arr = null;

try{

System.out.println(arr[0]);//NullPointerException

} catch (NullPointerException e) {

System.out.println("空指针异常");

}

System.out.println("over");

*/

//方式2 所有的异常, 统一处理 (推荐)

 

int x = 5;

int y = 5;

int[] arr = {1,2,3};

try {

System.out.println(x/y);//ArithmeticException

System.out.println(arr[3]);//ArrayIndexOutOfBoundsException

} catch (ArithmeticException e) {

System.out.println("除数不能为0");

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("数组角标越界");

}

System.out.println("over");

}

jdk7新的方式3: 所有异常一起处理

   格式:

   一个try  对应着一个catch,但是,在catch中,包含多个异常对象

  

   try{

   可能出现异常的代码

   } catch (异常类名1 | 异常类名2 | 异常类名3 | ...  对象名)  {

   异常处理的代码

   }

方式3案例:

public class ExceptionDemo5 {

public static void main(String[] args) {

int x = 5;

int y = 5;

int[] arr = {1,2,3};

try {

System.out.println(x/y);//ArithmeticException

System.out.println(arr[3]);//ArrayIndexOutOfBoundsException

} catch(ArithmeticException|ArrayIndexOutOfBoundsException e) {

System.out.println("程序出错");

}

System.out.println("over");

}

}

 运行期异常: 在java中 ,我们不需要手动处理

   可以通过代码编写的更加严谨,来避免这种异常的发生

 编译期异常: 在java中,我们必须手动处理

案例:

 public class ExceptionDemo7 {

public static void main(String[] args) {

//运行期异常

int x = 6;

int y = 2;//0;

if (y != 0) {

System.out.println(x/y);

}

//编译期异常

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

Date date = null;

try {

date = sdf.parse("2015-04-20");//错误格式

//date = sdf.parse("2015年04月20日");//正确格式

} catch (ParseException e) {//表示解析时出现意外错误。

e.printStackTrace();

}

System.out.println(date);

}

}

 异常处理常用的方法:

  String getMessage()

获取异常信息,返回字符串。

获取异常原因

String toString()

获取异常类名和异常信息,返回字符串。

获取异常类名和异常原因

void printStackTrace()  信息打印到控制台--内存中

获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

获取异常类名和异常原因和异常的位置

void printStackTrace(PrintStream s)  信息打印到文件中--硬盘中

通常用该方法将异常内容保存在日志文件中,以便查阅。 

   获取异常类名和异常原因和异常的位置

public class ExceptionDemo {

public static void main(String[] args) {

int x = 5;

int y = 0;

try {

System.out.println(x/y);

} catch (Exception e) {

//System.out.println(e.getMessage() );//异常原因   / by zero

//System.out.println(e.toString());//异常名称+异常原因  java.lang.ArithmeticException: / by zero

e.printStackTrace();

}

System.out.println("over");

}

}

throws: 抛出异常

   格式:

  声明方法的后面使用

   修饰符 返回值类型 方法名() throws 异常类名1,异常类名2,异常类名3,异常类名4... {}

  例如:

  public static void method() throws ParseException {}

案例:

public class ExceptionDemo {

public static void main(String[] args){

try {

method();

} catch (ParseException e) {

e.printStackTrace();

}

System.out.println("Over");

}

public static void method() throws ParseException {

//编译期异常

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

//Date date = sdf.parse("2015年04月20日");

Date date = sdf.parse("2015-04-20");

System.out.println(date);

}

finally关键字的特点及作用:

   try{

   可能出现异常的代码

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

   该异常处理的代码

   } finally {

   我一定要执行的代码 (特殊情况会不执行,后面讲)

   释放资源

   }  

  finally的特点:

被finally控制的语句体一定会执行。特殊情况除外:在执行到finally之前jvm退出了(比如System.exit(0))。

finally的作用:

用于释放资源,在IO流操作和数据库操作中会见到

 

public class ExceptionDemo {

public static void main(String[] args) {

//正常情况下执行finally

try {

System.out.println(3/0);

} catch (Exception e) {

e.printStackTrace();

} finally {

System.out.println("Over");

}

//特殊情况, finally不运行

try {

System.out.println(3/0);

} catch (Exception e) {

e.printStackTrace();

System.exit(0);//退出JVM

} finally {

System.out.println("Over");

}

//System.out.println("Over");

}

}

  如果catch里面有return语句,请问finally的代码还会执行吗? 如果会,请问是在return前还是return后。

    会,中间执行

public class ExceptionDemo2 {

public static void main(String[] args) {

int x = method(10);

System.out.println("Over");

System.out.println("x:" + x);

}

public static int method(int x) {

try {

x = 20;

System.out.println(x/0);

//异常后面的代码执行不到

x = 30;

} catch (Exception e) {

e.printStackTrace();

x = 40;

return x;// 40

} finally {

x = 50;

System.out.println("finally:" + x);

//return x;//50

}

return x;

}

}

异常的注意事项:

子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)。

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

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

案例:

class Fu {

public void method () throws ParseException, IOException {

//public void method () throws Exception {

System.out.println("method");

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.parse("12345678");

System.out.println(3/0);

}

public void function() {

}

}

 

class Zi extends Fu {

//public void method () throws ParseException ,ArithmeticException {

//public void method () throws ParseException{

public void method () throws ParseException, IOException{

//public void method () throws Exception {

System.out.println("method");

SimpleDateFormat sdf = new SimpleDateFormat();

sdf.parse("12345678");

//System.out.println(3/0);

int arr[] = {1,2,3};

System.out.println(arr[3]);

}

@Override

public void function() {

System.out.println("method");

SimpleDateFormat sdf = new SimpleDateFormat();

try {

sdf.parse("12345678");

} catch (ParseException e) {

e.printStackTrace();

}

}

}

File类概述: 

文件和目录路径名的抽象表示形式(理解为就是代表文件名和文件夹名称)。

 File 构造方法:

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

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

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

public class FileDemo {

public static void main(String[] args) {

//public File(String pathname)

File file1 = new File("d:\\aaa\\123.txt");

//public File(String parent, String child)

File file2 = new File("d:\\aaa", "123.txt");

//public File(File parent, String child)

File parent = new File("d:\\aaa");

File file3 = new File( parent, "123.txt");

}

}

  创建功能:

   创建文件夹:

   public boolean mkdir()

   创建单层文件夹

  

   如果指定的文件夹不存在并成功地创建,则返回 true;

如果指定的文件夹已经存在,则返回 false 

 

  public boolean mkdirs()

  创建多层文件夹

 

  创建文件:

  public boolean createNewFile()

如果指定的文件不存在并成功地创建,则返回 true;

如果指定的文件已经存在,则返回 false 

骑白马不一定是白马王子, 有可能是唐僧

 案例:

public class FileMethodDemo {

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

//创建File对象

//创建文件

//File file = new File("F:\\aaa\\abc.txt");//java.io.IOException: 系统找不到指定的路径

// File file = new File("d:\\aaa\\abc.txt");

// boolean flag = file.createNewFile();

// System.out.println(flag);

//创建文件夹

// File file2 = new File("d:\\aaa\\bbb");

// boolean flag = file2.mkdir();

// System.out.println(flag);

// File file3 = new File("d:\\aaa\\a\\b\\c");

// boolean flag = file3.mkdirs();

// System.out.println(flag);

//File f = new File("d:\\aaa\\hello");

//f.createNewFile();

File f = new File("d:\\bbb\\world.java");//骑白马不一定是白马王子, 有可能是唐僧

boolean bo=f.mkdirs();

System.out.println(bo);

}

}

删除功能:

  public boolean delete()

   删除此抽象路径名表示的文件或目录。

   如果此路径名表示一个目录,则该目录必须为空才能删除。

 案例:

public class FileMethodDemo2 {

public static void main(String[] args) {

//删除文件

//File file = new File ("D:\\temp\\123.txt");

//File file = new File ("D:\\temp\\*.txt");

//System.out.println(file.delete());

//删除文件夹

//File file = new File ("D:\\temp\\aaa");

//System.out.println(file.delete());

File file = new File ("D:\\temp\\bbb");

System.out.println(file.delete());

}

}

  绝对路径: d:\\aaa\\123.txt

  相对路径 : aaa\\123.txt

   在eclipse中 如果写的是 相对路径 ,那么,会在当前项目的跟目录创建对应的文件夹或文件

 重命名功能

  public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。

  如果File对象与目的地File对象在同一个文件夹是重命名功能。  

  如果 源File对象与目的地File对象不在同一个文件夹,是剪切+重命名功能。 

 案例:

public class FileMethodDemo3 {

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

File file = new File("123.txt");

file.createNewFile();

File file2 = new File("abc");

file2.mkdir();

File file3 = new File("abc\\haha.txt");

file3.createNewFile();

File srcName = new File("d:\\123.txt");

//File destName = new File("d:\\456.txt");

File destName = new File("e:\\456.txt");

System.out.println( srcName.renameTo(destName) );

}

}

 File的获取功能:

   public File getAbsoluteFile(): 获取File对象的绝对路径

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

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

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

   public long length(): 获取文件的大小

 

public class FileMethodDemo4 {

public static void main(String[] args) {

// File file = new File ("d:\\temp\\123.txt");

File file = new File ("abc\\haha.txt");

System.out.println("getAbsoluteFile:"+file.getAbsolutePath());

System.out.println("getPath:"+file.getPath());

System.out.println("getName:"+file.getName());

long lastModified = file.lastModified();

Date d = new Date(lastModified);

System.out.println("lastModified:"+d);

System.out.println("length:"+file.length());

}

}

 

  判断功能

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

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

public boolean exists() 判断File对应的文件或文件夹 是否存在

public boolean canRead() 判断是否可读

public boolean canWrite() 判断是否可写

public boolean isHidden() 判断是否为隐藏

方法解析案例:

 public class FileMethodDemo5 {

public static void main(String[] args) {

File file = new File("d:\\temp\\123.txt");

//public boolean isDirectory()

System.out.println("isDirectory:" + file.isDirectory());

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

System.out.println("isFile:" + file.isFile());

//public boolean exists()

System.out.println("exists:" + file.exists());

//file = new File ("d:\\temp\\haha.txt");

//System.out.println("exists:"+ file.exists());

//public boolean canRead()

System.out.println("canRead:" + file.canRead());

//public boolean canWrite()

System.out.println("canWrite:" + file.canWrite());

//public boolean isHidden()

System.out.println("isHidden:" + file.isHidden());

}

}

 高级获取功能

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

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

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

案例:

public class FileMethodDemo6 {

public static void main(String[] args) {

//public static File[] listRoots()

File[] listRoots = File.listRoots();

System.out.println(Arrays.toString(listRoots));

System.out.println("------------------");

File file = new File("e:\\itcast");

//public String[] list()

String[] list = file.list();

for (int i = 0; i < list.length; i++) {

System.out.println(list[i]);

}

System.out.println("-------------------");

File[] listFiles = file.listFiles();

for (int i = 0; i < listFiles.length; i++) {

System.out.println(listFiles[i]);

}

}

}

递归概述:

方法定义中调用方法本身的现象。

递归注意实现:

要有出口,否则就是死递归。

次数不能太多,否则就内存溢出。

构造方法不能递归使用。

递归解决问题的思想

找到出口

练习:

需求: 求出5的阶乘结果

n == 1, 结果为1

找到规律

n * (n-1)!

1*2*3*4*5*n = sum  得到n的阶乘的结果

public class DiguiDemo {

public static void main(String[] args) {

int sum = jc(5);

System.out.println(sum);

//计算阶乘

public static int jc(int n) {

if (n == 1) {

return 1;

} else {

return n * jc(n-1);

}

}

}

IO流概述:用来处理设备之间的数据传输。

  上传文件和下载文件。

  Java对数据的操作是通过流的方式。

  Java用于操作流的对象都在IO包中。

IO流 按照数据流向分类:

输入流 读入数据   InputStream

输出流 写出数据   OutputStream

IO流 按照数据类型:

字节流    Reader

字符流     Writer

读数据:

读字节:

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()换行, 高效字符输出流特有方法

 

  OutputStream : 字节输出流

  此抽象类是表示输出字节流的所有类的超类 

  FileOutputStream: 文件字节输出流

   文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流

  构造方法:

   public FileOutputStream(File file) 通过给定的File对象 创建 字节输出流对象

public FileOutputStream(String name)通过给定的文件字符串路径 来 创建 字节输出流对象

             throws FileNotFoundException 如果该文件存在,但它是一个目录,而不是一个常规文件;或者该文件不存在,但无法创建它;抑或因为其他某些原因而无法打开 

//案例: 

public class FileOutputStreamDemo {

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

File file = new File("123.txt");

//public FileOutputStream(File file)

//打开文件,如果文件不存储,创建后,打开

FileOutputStream fos = new FileOutputStream(file);

//public FileOutputStream(String name)

//打开文件,如果文件不存储,创建后,打开

FileOutputStream fos2 = new FileOutputStream("abc.txt");

}

}

 字节输出流 OutputStream 中的方法

  

   public abstract void write(int b) 写一个字节  

   public void write(byte[] b) 写一个字节数组内容

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

public void close() 关闭此输出流并释放与此流有关的所有系统资源

public void flush() 刷新此输出流并强制写出所有缓冲的输出字节

案例:

public class FileOutputStreamDemo2 {

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

//打开文件

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

//写数据

fos.write(97);

fos.write(98);

fos.write(99);

fos.write("hello, Java".getBytes());

byte[] bys = {97,98,99,100};

fos.write(bys, 1, 2);

//关闭文件

fos.close();

}

}

package cn.itcast_02_FileOutputStream;

 

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

 

如何实现原有数据的追加与换行? 

 实现原有数据的追加:

   public FileOutputStream(File file, boolean append)

public FileOutputStream(String name, boolean append)

   换行:

    \r\n  windows

    \n    Linux Unix

    \r    Mac OS 

//案例:

public class FileOutputStreamDemo3 {

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

//打开文件

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

//打开文件,并开启追加模式

//FileOutputStream fos = new FileOutputStream("abc.txt", true);

//写数据

fos.write(97);

fos.write(98);

fos.write('b');

//fos.write("A 哪去了?\r\n".getBytes());

//关闭文件

fos.close();

}

}

 

 InputStream: 字节输入流

  此抽象类是表示字节输入流的所有类的超类。 

 

 FileInputStream:

  FileInputStream 从文件系统中的某个文件中获得输入字节

 

 构造方法:

  public FileInputStream(File file) 通过给定的File对象 创建一个 字节输入流对象

public FileInputStream(String name) 通过给定的文件的名字路径, 创建一个 字节输入流对象

方法:

public int read(): 读取一个数据字节。 读取到了流的末尾,返回-1

//案例:

public class FileInputStreamDemo {

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

//打开文件

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

//读数据

int ch = -1;//用来记录读取到了数据

//获取数据, 赋值, 比较

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

System.out.print((char)ch);

}

//关闭文件

fis.close();

}

}

InputStream:字节输入流:

   public int read(byte[] b) 一次读一个字节数组长度的内容

   返回结果: 代表着每一次读取到了几个有效字节数量

public class FileInputStreamDemo {

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

//打开文件

FileInputStream fis = new FileInputStream("StringCode.java");

//读数据

byte[] bys = new byte[5];

System.out.println(fis.read(bys)); // 5 读一个数组的长度

System.out.println(new String(bys));// abcde

System.out.println(fis.read(bys)); // 5 读一个数组的长度

System.out.println(new String(bys));// /r/nabc

System.out.println(fis.read(bys)); // 5 读一个数组的长度

System.out.println(new String(bys));// de/r/na

System.out.println(fis.read(bys)); // 4 剩余长度

System.out.println(new String(bys));// bcdea 

//关闭文件

fis.close();

}

}

//一次读取一个字节数组复制文本文件练习:

  练习: 字节流一次读写一个字节数组,复制文本文件

  数据源:E:\resource\UIUtil.java

  目的地:UIUtil.java

  分析:

   1: 封装数据源 与 目的地

   2: 从数据源中 读 数据

   3: 把数据写到 目的地

   4: 关闭流

 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[100];

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

int len = -1;

//读数据

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

//写数据

fos.write(buffer, 0, len);

}

//关闭流

fos.close();

fis.close();

}

}

 字节缓冲输入流(高效的):

BufferedInputStream

构造方法:

public BufferedInputStream(InputStream in)

public BufferedInputStream(InputStream in, int size)

案例:

public class BufferedInputStreamDemo {

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

//创建流对象

// InputStream is = new FileInputStream("Fis.txt");

// BufferedInputStream bis = new BufferedInputStream(is);

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bos.txt"));

/*

//读数据

//一次一个字节

int ch = -1;//记录每次读的字节

//读数据

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

//写数据

System.out.print((char)ch);

}

*/

//一次一个字节数组

byte[] buffer = new byte[100];

int len = -1;//用来每次读的新字节的个数

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

//写数据

System.out.println( new String(buffer, 0, len) );

//System.out.println( new String(buffer) );//错误的结果

}

//关闭流

bis.close();

}

}

 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,

 这是加入了数组这样的缓冲区效果,java本身在设计的时候, 也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流

字节缓冲输出流

BufferedOutputStream

字节缓冲输入流

BufferedInputStream

 

BufferedOutputStream 字节缓冲输出流, 构造方法:

public BufferedOutputStream(OutputStream out) 把基本的字节输出流,包装成一个高效的 字节缓冲输出流对象

默认的缓冲区大小为 8K  8192个字节

public BufferedOutputStream(OutputStream out, int size)

案例:

public class BufferedOutputStreamDemo {

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

//创建一个流对象

//OutputStream os = new FileOutputStream("fos.txt");

//BufferedOutputStream bos = new BufferedOutputStream(os);

BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("bos.txt") );

//写数据

bos.write("hello".getBytes());

//关闭流

bos.close();

}

}

package cn.itcast_01_CharCoding;

 

import java.io.UnsupportedEncodingException;

import java.util.Arrays;

 字符编码表:

   编码表

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

常见的编码表:

ASCII: 用7位来表示一个数据

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

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

GBK:  简体中文

GB18030:  简体中文, 替代GBK

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

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

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

 字符串中的编码问题

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

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

  

   解码:

   public String(byte[] bytes)用系统平台默认的字符集 进行解码指定的 byte 数组

   public String(byte[] bytes, String charsetName) 通过指定的编码表,进行解码指定的 byte 数组

  

   编码:

   public byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

   public byte[] getBytes(String charsetName)使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 

  

   数据的编解码操作要 字符编码表要统一

 案例:

public class StringCoding {

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

//byte[] bys = "天子".getBytes();// 编码

//byte[] bys = "天子".getBytes("gbk");// 编码

byte[] bys = "天子".getBytes("utf-8");// 编码

System.out.println(Arrays.toString(bys));

//String result = new String(bys);//解码

String result = new String(bys, "utf-8");//解码

System.out.println(result);

}

}

 OutputStreamWriter: 转换流

  它是Writer的子类,Writer是字符流

 

作用: 可以将 字节流中的数据,按照指定的编码表进行数据的编码,生产的结果成为了字符流

   字节流 -->  字符流

 

 OutputStreamWriter: 字符输出流 

  构造方法:

  public OutputStreamWriter(OutputStream out)

  创建使用默认字符编码(gbk)的 OutputStreamWriter。

  public OutputStreamWriter(OutputStream out,String charsetName)

创建使用指定字符集的 OutputStreamWriter。

//案例: 

public class OutputStreamWriterDemo {

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

//创建流对象

//OutputStream os = new FileOutputStream("fos.txt");

//OutputStreamWriter转换流 ,将 字节输出流OutputStream 通过默认的码表 转换为 字符流

//OutputStreamWriter osw = new OutputStreamWriter(os);

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

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "utf-8");

//写数据

osw.write("黑马");

//关闭流

osw.close();

}

}

InputStreamReader: 转换流

   构造方法:

   public InputStreamReader(InputStream in) 使用平台默认的字符集, 进行数据的解码

public InputStreamReader(InputStream in,String charsetName) 使用给定的字符集,进行数据的解码

  

   将InputStream 字节输入流, 使用字符流进行解码操作,返回的结果是InputStreamReader字符输入流

 

public class InputStreamReaderDemo {

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

//创建流对象

//InputStream is = new FileInputStream("osw.txt");

//使用InputStreamReader, 将InputStream字节输入流中的数据进行解码操作

//InputStreamReader isr = new InputStreamReader(is);

//InputStreamReader isr=new InputStreamReader(newFileInputStream("osw.txt"));

InputStreamReader isr=new InputStreamReader(newFileInputStream("osw.txt"), "utf-8");

//读数据

int ch = -1;

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

System.out.print(ch);

}

//关闭流

isr.close();

}

}

字符流基本流复制文件的案例:

 使用转换流 完成 文本文件的复制

  

   数据源: 面试题.txt  -- InputStream -- InputStreamReader

   目的地:copyText.txt -- OutputStream -- OutputStreamWriter

 

public class copyTextFile {

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

//数据源

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

//目的地

OutputStreamWriter osw = new OutputStreamWriter(newFileOutputStream("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();

}

}

 使用转换流 完成 文本文件的复制

   数据源: 面试题.txt  -- InputStream -- InputStreamReader -- FileReader

   目的地:copyText.txt -- OutputStream -- OutputStreamWriter -- FileWriter

   发现上一个版本,使用转换流 太麻烦, 有没有简化的方式,应该有

   大多数情况下,我们都是使用平台的默认字节集 进行的编解码操作,没有必要使用转换流,可以使用更简化的流

   FileReader:用来读取字符文件的便捷类

   FileWriter:用来写入字符文件的便捷类

   

   Reader

    |- InputStreamReader

    |- FileReader

   Writer

    |- OutputStreamWriter

    |- FileWriter

 

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();

}

}

  BufferedWriter 字符缓冲输出流

   构造方法

   public BufferedWriter(Writer out)

   public BufferedWriter(Writer out, int size)

 案例:

public class BufferedWriterDemo {

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

//创建流对象

//Writer w = new FileWriter("fw.txt");

//BufferedWriter bw = new BufferedWriter(w);

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

//写数据

bw.write("今天天气不错");

bw.flush();

//关闭流

bw.close();

}

}

  BufferedReader: 字符缓冲输入流

   构造方法:

   public BufferedReader(Reader in)

   public BufferedReader(Reader in, int sz)

 

public class BufferedReaderDemo {

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

//创建流对象

//Reader r = new FileReader("fr.txt");

//BufferedReader br = new BufferedReader(r);

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

//读数据

char[] buffer = new char[1024];

int len = -1;

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

System.out.println(new String(buffer, 0 , len));

}

//关闭流

br.close();

}

}

  特殊功能

BufferedWriter 字符缓冲输出流

public void newLine() 根据当前的系统,写一个换行符。

BufferedReader

public String readLine():读取一行字符串, 读取到 回车换行结束

当没有获取到有效数据的时候,返回null。

public class BufferedMethod {

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

//writer();

reader();

}

//读

public static void reader() throws IOException {

//创建流对象

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

//读数据

String line = null;

//获取数据,赋值, 判断

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

System.out.println(line);

}

//关闭

br.close();

}

//写

public static void writer() throws IOException {

//创建流对象

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

//写数据

for (int i = 1; i <= 10; i++) {

bw.write("HelloWorld"+i);

bw.newLine();//写一个换行符

bw.flush();//刷新数据到目的地

}

//关闭

bw.close();

}

}

LineNumberReader 带有行号的字符输入流

  

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

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

 //案例

public class LineNumberReaderDemo {

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

//创建流对象

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

lnr.setLineNumber(100);

//读数据

String line = null;

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

int lineNumber = lnr.getLineNumber();

System.out.println(lineNumber +": "+ line);

}

//关闭流

lnr.close();

}

}

 打印流概述

字节打印流: PrintStream

字符打印流       PrintWriter

打印流特点

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

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

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

可以操作文件的流

 

 

PrintWriter是字符输出流,把PrintWriter 作为字符输出流使用

public class PrintWriterDemo {

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

//创建流对象

PrintWriter pw = new PrintWriter("pw.txt");

//写数据

pw.write("打印流演示");

pw.flush();

//关闭流

pw.close();

}

}

 

 打印流 完成 数据的自动刷新操作

  

  如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,

  

  构造方法

    public PrintWriter(OutputStream out, boolean autoFlush)

   public PrintWriter(Writer out, boolean autoFlush)

  方法:

   public void print(String s) 把任意类型的数据写入到目的地

   public void println(String s) 把任意类型的数据写入到目的地, 同时完成换行

 

public class PrintWriterDemo2 {

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

//创建流对象

//PrintWriter pw = new PrintWriter("pw2.txt");

//开启自动刷新

//PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);

//开启自动刷新的同时, 实现数据的追加

PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt", true), true);

//写数据

//pw.write("第一次");

pw.println("第二次");

//关闭流

pw.close();

}

}

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

  PrintWriter:  复制的文本文件

  PrintStream:  复制各种文件

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();

}

}

  Properties 集合 :

   属于Map集合, 它是Hashtable的子类

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

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

 

public class PropertiesDemo {

public static void main(String[] args) {

//创建集合对象

Properties prop = new Properties();

//添加元素到集合

prop.put("常尚权", 85);

prop.put("班长", 18);

prop.put("妹子", 18);

//遍历

//键 找 值

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

for (Object key : keys) {

Object value = prop.get(key);

System.out.println(key +"..."+ value);

}

}

}

 

 

 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 class PropertiesMethod {

public static void main(String[] args) {

//创建集合对象

Properties prop = new Properties();

//添加元素

prop.setProperty("班长", "19");

prop.setProperty("妹子", "18");

//遍历

Enumeration names = prop.propertyNames();

while (names.hasMoreElements()) {

String name = (String)names.nextElement();

//键找值

String value = prop.getProperty(name);

System.out.println(name+"..."+value);

}

}

}

 Properties集合 与IO相关的操作

 

 方法:

  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 - 属性列表的描述

public class PropertiesMethod2 {

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

//method1();

method2();

//method3();

}

 

private static void method3() throws IOException {

//创建集合对象

Properties prop = new Properties();

//添加元素

prop.setProperty("班长", "19");

prop.setProperty("妹子", "18");

//存储到文件中

FileWriter fw = new FileWriter("store.properties");

prop.store(fw, "hello world");

fw.close();

}

 

private static void method2() throws IOException {

//创建集合对象

Properties prop = new Properties();

//FileReader fr = new FileReader("prop.txt");

FileReader fr = new FileReader("store.properties");

prop.load(fr);

fr.close();

System.out.println(prop);

}

 

private static void method1() throws IOException {

//创建集合对象

Properties prop = new Properties();

//添加元素

prop.setProperty("班长", "19");

prop.setProperty("妹子", "18");

PrintWriter pw = new PrintWriter("prop.txt");

prop.list(pw);

pw.close();

}

}

 

练习:

 需求:

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

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

 

  分析:

   1: 创建一个空集合 Properties

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

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

   有: 把list对应的值 该为100

   否:

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

 

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、付费专栏及课程。

余额充值