------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
输入流和输出流是相对于内存而言的:
将外设中的数据读取到内存中:输入。
将内存中的数据写到外设上:输出。
流按操作分为两种:字节流和字符流。
字符流的由来:其实就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字信息,在对这个文字操作。简单理解为:字节流+编码表
字符流的抽象类:Reader,Writer
其他有着四个类派生出来的子类都是以其父类为后缀名。
如把文字写入硬盘中的例子:
ps:这里使用 FileWriter
代码:
注意:如果构造函数为,FileWriter fw = new FileWriter("a.txt",true);那么是对文件进行续写。
close方法为关闭流。一般在finally语句中。而且有几个流对象就要对应关闭几个流。
练习:
读取一个文件,将读到的字符打印到控制台上。
1.read()方法:读取一个字符对应的ASK码值,若读到最后返回-1。
代码:
2.read(char[])方法:读取一定长度的数据。读到末尾返回-1。
代码:
字符流缓冲区:缓冲区的出现提高了数据的书写效率。
对应的类为:BufferedReader(对应有readLien())和BufferedWriter(对应有newLine())
LineNumberReader
跟踪行号的缓冲字符流:此类定义了方法setLineNumber(int)和getLineNumber(),他们可以分别用于设置和获取当前行号。
字节流的三种读取方式:
1、read(new byte[fis.available]):当文件字节数很少的时候,通过available()方法获得其长度,创建一个刚好的数组。
2、read(new byte[1024]):一次读取1024个字节。
3、read():一次读取一个,效率太低。
字节流也有对应的缓冲区:BufferedInputStream和BufferedOutputStream 缓冲区的出现提高了效率。
接收的对象分别为InputStream和OutPutStream;其实字节流转字符流就是解码过程,就应该有对应的编码表,不写则为默认的GBK。
转换流的简写:
键盘录入(因为键盘录入都是字符,而底层System.in为字节流,因此用到了转换流提高效率):
BufferedReader bufr = new BufferedReader(new InputStream(System.in));
ps:键盘录入一般都写了判断终止的语句。
什么时候用转换流呢:
1、源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本操作的便捷。
2、操作涉及到编码表时,必须使用转换流
练习:读取一个键盘录入数据,并变成大写打印在控制台上。
代码:
总结流操作的基本规律:
1、明确源和目的:
源:输入流 InputStream和Reader
目的: 输出流 OutputStream和Writer
2、数据操作是否为纯文本。
是:字符流
否:字节流
3、是否要使用具体的对象:
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
4、是否需要额外的更能增强。
是就用Buffered
例:
需求1: 复制一个文本文件
1、明确源和目 的。
源: InputStream Reader
目的: OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:硬盘 File
目的:硬盘 File
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
4、需要额外功能吗?
需要高效
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
需求2:读取键盘录入信息, 并写入到一个文件中
1、明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:键盘 System.in
目的:硬盘 File
FileReader fr = new System.in;
FileWriter fw = new FileWriter("b.txt");
//这样做可以完成, 但是麻烦。 将读取的字节数据转成字符串, 再由字符流操作。
4、需要额外功能吗?
需要转换,将字节流转成字符流,因为明确的源是Reader,这样操作文本数据更快捷。
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("b.txt");
还需要功能吗?
需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
File f1 = new File("d:\\demo\\a.txt");//将已存在的文件封装成对象。
File f1 = new File("d:\\demo"); //将已存在的文件夹封装成对象。
File对象的常见方法:
1.获取
获取文件名称:f1.getName();
获取文件路径:f1.getPath();f1.getAbsolutePath();getParent();
获取文件大小:f1.length();
获取最后一次修改时间: f1.lastModified();
2.创建和删除
创建:boolean creatNewFile();若文件已存在则返回false,和输出流不一样,输出流是覆盖已有文件。
boolean mkdir();创建文件夹
boolean mkdirs();创建多级文件夹
删除:boolean delet();文件删除失败返回false
void deletOnExit:程序退出时删除文件
3.判断
文件是否存在:f1.exists();
是否是文件:f1.isFile();
是否是文件夹:f1.isDirectory();
是否是隐藏文件:f1.isHidden();
路径是否是绝对路径:f1.isAbsolute();
4.重命名
f1.renameTo(f2):
5.其他
File[] files = File.listRoots():返回可用的根目录。
File file = new File("d:\\");
file.getFreeSpace();//返回D盘剩余空间
file.getTotalSpace();//返回D盘总空间
file.getUsableSpace();//返回D盘可用空间
String[] names = new File("c:\\").list();//返回C盘里面的所有文件和文件夹名称
File[] files = new File("c:\\").listFiles();//返回C盘里所有的文件和文件夹对象
list()和listFiles()方法可传入指定的文件名,返回目录下指定的文件的数组。
例:
ps:
1.递归一定要明确条件,否则容易栈溢出。
2.注意递归的次数
3.递归一般都和嵌套在循环内,每次循环都好比褪去一层皮。
需求:获取目录下的所有文件名称
代码:
需求:用递归求6的二进制值
代码:
运行结果:
110
1、给集合中的键值对都是字符串
2、集合中的数据可以和保存到流中,或者可以从流中获取。
3、通常该集合用于操作以键值对存在的配置文件。
重要方法:
1)设置和获取
设置或者修改:p.setProperty("zhangsan","30");//Map中是put
获取键对应的值:String value = p.getProperty("zhangsan");//Map中是get(key)
获取所有键; String[] names = p.stringPropertyNames();
2)与流相结合:
读取流的键值对:load(InputStream/Reader i/r);
向流中写入数据:store(OutputStream/Writer o/w);
一般用PrintWriter,他可以在建立对象时接收File、String(路径)、OutoutStream、Writer。并且加上参数true,可以每次读取后自动flush。
他的println()方法为写数据后立马另起一行。
序列流:SequenceInputStream
可把多个有关系的流合并为一个流操作。多用于合并文件。
IO流
1.1 IO流概述
IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的对象都放在IO包中。输入流和输出流是相对于内存而言的:
将外设中的数据读取到内存中:输入。
将内存中的数据写到外设上:输出。
流按操作分为两种:字节流和字符流。
字符流的由来:其实就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字信息,在对这个文字操作。简单理解为:字节流+编码表
1.2 IO流中常见的基类--字符流
字节流的抽象类:InputStream,OutputStream字符流的抽象类:Reader,Writer
其他有着四个类派生出来的子类都是以其父类为后缀名。
如把文字写入硬盘中的例子:
ps:这里使用 FileWriter
代码:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException//IO流存在IO异常需要处理
{
FileWriter fw = new FileWriter("a.txt");//使流与文件相关联,如文件不存在则创建,如存在则覆盖
fw.write("abcdef");//调用Writer的write方法写数据,其实把数据写入到缓冲区里了
fw.flush();//刷新,将数据写到目的地中。
fw.close();//关闭流,关闭资源。
}
}
注意:如果构造函数为,FileWriter fw = new FileWriter("a.txt",true);那么是对文件进行续写。
close方法为关闭流。一般在finally语句中。而且有几个流对象就要对应关闭几个流。
练习:
读取一个文件,将读到的字符打印到控制台上。
1.read()方法:读取一个字符对应的ASK码值,若读到最后返回-1。
代码:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("a.txt");
int c ;
while ((c=fr.read())!=-1)
{
System.out.print((char)c);
}
fr.close();
}
}
2.read(char[])方法:读取一定长度的数据。读到末尾返回-1。
代码:
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("a.txt");
char[] arr = new char[3];
int len = 0;
while ((len=fr.read(arr))!=-1)
{
System.out.print(new String(arr,0,len));
}
fr.close();//
}
}
字符流缓冲区:缓冲区的出现提高了数据的书写效率。
对应的类为:BufferedReader(对应有readLien())和BufferedWriter(对应有newLine())
LineNumberReader
跟踪行号的缓冲字符流:此类定义了方法setLineNumber(int)和getLineNumber(),他们可以分别用于设置和获取当前行号。
1.3 IO流常见的基类--字节流
字节流不仅可以操作字符,还可从操作媒体文件。字节流的三种读取方式:
1、read(new byte[fis.available]):当文件字节数很少的时候,通过available()方法获得其长度,创建一个刚好的数组。
2、read(new byte[1024]):一次读取1024个字节。
3、read():一次读取一个,效率太低。
字节流也有对应的缓冲区:BufferedInputStream和BufferedOutputStream 缓冲区的出现提高了效率。
1.4 转换流(把字节流转换成字符流)
分别为:InputStreamReader和OutputSreamWriter接收的对象分别为InputStream和OutPutStream;其实字节流转字符流就是解码过程,就应该有对应的编码表,不写则为默认的GBK。
转换流的简写:
键盘录入(因为键盘录入都是字符,而底层System.in为字节流,因此用到了转换流提高效率):
BufferedReader bufr = new BufferedReader(new InputStream(System.in));
ps:键盘录入一般都写了判断终止的语句。
什么时候用转换流呢:
1、源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本操作的便捷。
2、操作涉及到编码表时,必须使用转换流
练习:读取一个键盘录入数据,并变成大写打印在控制台上。
代码:
import java.io.*;
class ReadKey
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line=bufr.readLine())!=null){
if(line.equals("over"))
break;
else{
System.out.println(line.toUpperCase());
}
}
bufr.close();
}
}
总结流操作的基本规律:
1、明确源和目的:
源:输入流 InputStream和Reader
目的: 输出流 OutputStream和Writer
2、数据操作是否为纯文本。
是:字符流
否:字节流
3、是否要使用具体的对象:
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
4、是否需要额外的更能增强。
是就用Buffered
例:
需求1: 复制一个文本文件
1、明确源和目 的。
源: InputStream Reader
目的: OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:硬盘 File
目的:硬盘 File
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
4、需要额外功能吗?
需要高效
BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
需求2:读取键盘录入信息, 并写入到一个文件中
1、明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:键盘 System.in
目的:硬盘 File
FileReader fr = new System.in;
FileWriter fw = new FileWriter("b.txt");
//这样做可以完成, 但是麻烦。 将读取的字节数据转成字符串, 再由字符流操作。
4、需要额外功能吗?
需要转换,将字节流转成字符流,因为明确的源是Reader,这样操作文本数据更快捷。
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("b.txt");
还需要功能吗?
需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
1.5 File类
File类用来将文件或者文件夹封装成对象,方便对文件和文件夹的属性进行操作。File对象可以作为参数传递给流的构造函数。File f1 = new File("d:\\demo\\a.txt");//将已存在的文件封装成对象。
File f1 = new File("d:\\demo"); //将已存在的文件夹封装成对象。
File对象的常见方法:
1.获取
获取文件名称:f1.getName();
获取文件路径:f1.getPath();f1.getAbsolutePath();getParent();
获取文件大小:f1.length();
获取最后一次修改时间: f1.lastModified();
2.创建和删除
创建:boolean creatNewFile();若文件已存在则返回false,和输出流不一样,输出流是覆盖已有文件。
boolean mkdir();创建文件夹
boolean mkdirs();创建多级文件夹
删除:boolean delet();文件删除失败返回false
void deletOnExit:程序退出时删除文件
3.判断
文件是否存在:f1.exists();
是否是文件:f1.isFile();
是否是文件夹:f1.isDirectory();
是否是隐藏文件:f1.isHidden();
路径是否是绝对路径:f1.isAbsolute();
4.重命名
f1.renameTo(f2):
5.其他
File[] files = File.listRoots():返回可用的根目录。
File file = new File("d:\\");
file.getFreeSpace();//返回D盘剩余空间
file.getTotalSpace();//返回D盘总空间
file.getUsableSpace();//返回D盘可用空间
String[] names = new File("c:\\").list();//返回C盘里面的所有文件和文件夹名称
File[] files = new File("c:\\").listFiles();//返回C盘里所有的文件和文件夹对象
list()和listFiles()方法可传入指定的文件名,返回目录下指定的文件的数组。
例:
File[] files = new File("c:\\").listFiles(new FileByHidden());
class FileByHidden implements FilenameFiler{
public boolean accept(File dir , String name){
return dir.isHidden();
}
}
1.6 递归
函数自身直接或者间接的调用自身,一个功能在被重复的使用,每次使用时,参与运算的结果和上一次有关,这时可以使用递归来解决问题。ps:
1.递归一定要明确条件,否则容易栈溢出。
2.注意递归的次数
3.递归一般都和嵌套在循环内,每次循环都好比褪去一层皮。
需求:获取目录下的所有文件名称
代码:
import java.io.*;
class FileDemo
{
public static void main(String[] args)
{
File f = new File("e:\\java资料\\java007");
getFileName(f);
}
public static void getFileName(File f){
if(f.isFile())
System.out.println(f.getName());
//if(f.getnName().ehdsWith(".java"))也可以判断是否为某一文件
if(f.isDirectory()){
System.out.println(f);
File[] files = f.listFiles();
for(File file : files){
getFileName(file);
}
}
}
}
需求:用递归求6的二进制值
代码:
class ToBinary
{
public static void main(String[] args)
{
int num = 6;
toBinary(num);
}
public static void toBinary(int i){
if(i>0){
toBinary(i/2);
System.out.print(i%2);//这里的递归和输出顺序问题,让递归底层的想打印就把输出语句放在递归后面
}
}
}
运行结果:
110
1.7 Properties集合(为Hashtable子类)
特点:1、给集合中的键值对都是字符串
2、集合中的数据可以和保存到流中,或者可以从流中获取。
3、通常该集合用于操作以键值对存在的配置文件。
重要方法:
1)设置和获取
设置或者修改:p.setProperty("zhangsan","30");//Map中是put
获取键对应的值:String value = p.getProperty("zhangsan");//Map中是get(key)
获取所有键; String[] names = p.stringPropertyNames();
2)与流相结合:
读取流的键值对:load(InputStream/Reader i/r);
向流中写入数据:store(OutputStream/Writer o/w);
1.8 IO流其他类
打印流:PrintStream和PrintWriter一般用PrintWriter,他可以在建立对象时接收File、String(路径)、OutoutStream、Writer。并且加上参数true,可以每次读取后自动flush。
他的println()方法为写数据后立马另起一行。
序列流:SequenceInputStream
可把多个有关系的流合并为一个流操作。多用于合并文件。