IO流-1
File
概述
File对象主要是用来表示文件或者是目录的路径的。类中提供了很多对文件或者文件夹操作的常用方法。
创建对象
绝对路径
以磁盘名开头的路径。例如:D:\Program FilesNJavaljdk1.8.0_172
相对路径
不是以盘符开头的,相对于当前项目下的路径。例如:a.txt
File(String pathname) //通过字符串类型的路径来创建对象
File(String parent, string child) //通过父目录的路径(字符串类型)和文件(文件夹)名称来创建对象
File(File parent, String child) //通过父目录的路径(File类型)和文件(文件夹)名称来创建对象
常用方法
boolean createNewFile() //根据路径创建一个文件,返回值代表创建是否成功
boolean mkdir() //根据路径创建一个文件夹,返回值代表创建是否成功
boolean mkdirs() //根据路径创建一个文件夹,如果父目录不存在会自动创建父目录
boolean exists() //判断文件或者文件夹是否存在
boolean isFi1e() //判断是否是一个文件
boolean isDirectory() //判断是否是一个文件夹
boolean delete() //删除文件,或者删除空文件夹,返回值代表删除是否成功
long length() //获取一个文件的大小,对文件夹无意义
String getName() //获取文件或文件夹的名字
Fi1e getParentFile() //获取父目录的File对象
String getAbsolutePath() //获取Fi1e对象的绝对路径
重要方法
File[] listFiles()//如果当前File对象是一个文件夹,可以获取文件夹下的所有文件或者文件夹的File对象。
注意:如果不是文件夹或者是文件夹的权限受限返回值是null。所以一定要对返回结果做非空判断。
递归
在方法中调用方法本身就是递归。
例如
public int f(int n){
if(n==1){
return 1;
}
return n*f(n-1);
}
注意:我们在使用递归的过程中一定要保证递归能结束,不能无限递归下去不然会出现栈溢出(StackoverflowError)的情况。
小结:如果既可以用递归解决又可以用循环解决。我们一般用循环解决。
IO流-2
IO流概述
当需要进行数据的传输的时候可以使用lO流来进行。例如:把磁盘中文件的数据读取到内存中。把内存中的数据写入到磁盘中。把网络中的数据读取到内存中。
IO流分类
IO流根据处理数据类型的不同分为字符流和字节流,根据数据流向不同分为输入流和输出流,对输入流只能进行读操作,对输出流只能进行写操作。
字节输入流
所有字节输入流的父类是 java.io.InputStream,它是以字节为单位的输入流。
FileInputStream概述
FileInputStream是用来读取文件数据的字节输入流。
FileInputStream对象创建
构造方法如下:
FileInputstream(string name) throws FileNotFoundException//传入文件路径创建对象
FileInputstream(File file) throws FileNotFoundException//传入文件路径的File对象来创建流对象
示例:
public static void main(String[] args) throws FileNotFoundException {
//创建对象
File inputstream fis = new Fi1eInputstream("C:\\Users\\root\\Desktop\\test\\11.txt");
System.out. println(fis);
File file = new File("C:\\users\\root\\Desktop\\test\\11.txt");
FileInputstream fis2 = new FileInputstream(fi1e);
System.out.print1n(fis);
}
读取数据
我们可以使用FilelnputStream来读取文件中的字节数据。
一次读取一个字节
核心方法如下:
public int read() throws IOException//读取一个字节的数据作为返回值返回 返回值为-1时代表没有内容了
范例:
public static void main(String[] args) throws IOException {
FileInputstream fis = new FileInputstream( "C:\\Users\\root\\Desktop\\test\\11.txt");
//读取数据
int b;
while((b=fis.read())!=-1){
System.out.print1n(b);
}
//释放资源
fis.close();
}
一次读取一个字节数组
核心方法如下:
public int read(byte b[]) throws IOException//传入一个字节数组,最多读取一个字节数组的数据,并且会把数据存入数组中,返回值代表本次读取到的字节的个数。 如果返回值为-1,代表读到末尾
范例:
public static void main(String[] args)throws IOException {
FileInputstream fis = new FileInputstream( "C:\\Users\\root\\Desktop\\test\\11.txt");
//读取数据一次读一个字节数组
byte[] bytes = new byte[1024*2];
int len;
while ((1en=fis.read(bytes))!=-1){
System.out.print1n(new string(bytes, 0, 1en));
}
//释放资源
fis.c1ose();
}
资源释放
前面处理异常的时候都同意做了声明抛出的处理。但是这很可能导致在出现了异常时资源没有被正确的释放。所以我们要更合理的处理异常,尤其是处理资源释放的问题。
JDK6版本
private static void test() {
FileInputstream fis = null;
try{
fis = new FileInputstream("C:\\users\\root\\Desktop\\test\\11.txt");
//读取数据一次读一个字节数组
byte[] bytes = new byte[1024*2];
int len;
while((len=fis.read(bytes))!=-1){
System.out.println(new string (bytes ,0 , 1en));
}
}catch (IOException e){
e.printstackTrace();
}fina1ly {
//释放T源
if(fis !=nu11){
try {
fis.c1ose();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
JDK7版本
可以使用try...catch..resource的写法,在try的后面可以加小括号,把需要释放的资源在小括号中定义。我们就不需要自己去释放资源ljvm会帮我们再最后调用close方法释放资源的。
private static void test2(){
try (FileInputstream fis =
new FileInputstream("C:\\users\\root\\Desktop\\test\\11.txt");
){
//读取数据一次读一个字节数组
byte[] bytes = new byte[1024*2];
int len ;
while ((1en=fis .read(bytes)) !=-1){
System.out.println(new string(bytes ,0 , 1en));
}
//释放支援不需要写了
//fis.close();
}catch (IOException e){
e. printstackTrace();
}
}
JDK9版本
资源的定义也可以不放在try的小括号中,只要在try的小括号中声明要释放的资源即可。
private static void test3( throws FileNotFoundException {
FileInputstream fis =new
new FileInputstream("C:\\users\\root\\Desktop\\test\\11.txt");
try(fis ){
//读取数据一次读一个字节数组
byte[] bytes = new byte[1024*2];int 1en;
while ((len=fis .read (bytes)) !=-1){
System.out.print1n(new string (bytes ,0 , 1en));
}
}catch (IOException e){
e. printstackTrace(;
}
}
字节输出流
所有字节输出流的父类是 java.io.OutputStream,它是以字节为单位的输入流。
以FileOutputStream为例进行学习。
FileOutputStream概述
FileOutputStream是用来往文件中写入数据的字节输出流。
FileOutputStream对象创建
常用构造方法如下:
Fi1eOutputstream(string name) throws FileNotFoundException//传入文件路径创建对象
FileOutputStream(File fi1e) throws FiTeNotFoundException//传入文件路径的Fi1e对象来创建流对象
示例:
public static void main(String[] args) throws FileNotFoundException {
FileOutputstream fos = new
FileOutputstream("C:\\users\\root\\Desktop\\test\\11.txt");
File file = new File("C:\\users\\root\\Desktop\\test\\11.txt");
Fileoutputstream fos2 = new FileOutputstream(file);
}
写数据
我们可以使用FileOutputStream来往文件中写入字节数据。
一次写一个字节
核心方法如下:
public void write(int b) throws IOException //传入一个字节数据,把字节数据写入文件
范例:
public static void main(String[] args) throws IOException {
File file = new File("C:\\users\\root\\Desktop\\test\\11.txt");
FileOutputstream fos = new Fi1eOutputstream(file);
fos.write( 'a');
fos .c1ose();
}
一次写一个字节数组
核心方法如下:
public void write(byte b[]) throws IOException //存入一个字节数组,把字节数组中的数据全部写入文件
public void write(byte b[], int off, int 1en) throws IOException//存入一个字节数组,把字节数组中从off索引开始1en个元素写入文件
范例:
public static void main(String[] args) throws IOException {
File file = new File("C:\\users\\root\\Desktop\\test\\11.txt");
FileOutputstream fos = new FileOutputstream(file);
byte[] bytes = "abc".getBytes();
//fos.write(bytes);
fos.write(bytes , 0, 2);
fos.c1ose();
}
文件续写
如果用之前的构造方法创建的流对象,每次流对象创建的时候就会把文件中的内容情况。所以没有办法实现续写的效果。如果需要续写就需要使用另外的构造方法。
FileOutputStream(String name, boolean append) throws FileNotFoundException//第二个参数代表是否续写
FileOutputStream(File file, boolean append)throws FileNotFoundException//第二个参数代表是否续写
使用什么的构造创建流对象,并且第二个参数传入true,就不会清空文件中原有的内容。实现文件续写的效果。
范例:
public static void main(String[] args) throws IOException {
File file = new File("C:\\users\\root\\Desktop\\test\\11.txt");
FileOutputstream fos = new FileOutputstream(file,true);
byte[] bytes = "abc".getBytes();
//fos.write(bytes);
fos.write(bytes , 0, 2);
fos.c1ose();
}
文件复制
要求定义一个方法,该方法能够实现文件的复制
public static void main(String[] args) throws IOException {
//要求定义一个方法,该方法能够实现文件的复制
//文件的复制就是循环的读写,直到操作完所有数据为止
File src = new File("C:\\users\\root\\Desktop\\test\\11.txt");
File destDir = new File("C:\\users\\root\\Desktop\\test\\a");
copyFile(src, destDir);
}
//源文件的路径File srcFi1e
//目标文件的存放目录路径File destDir
public static void copyFi1e(File srcFi1e,File destDir) throws IOException {
//在destDir下创建一个和srEFile同名的文件
File destFile = new File(destDir, srcFile.getName());//读取源文件把读到的数据写入目标文件destFile
FileInputstream fis = new FileInputstream(srcFile);
FileOutputstream fos = new FileOutputstream(destFile,true);
byte[] bytes = new byte[1024];
int len;
while((len=fis.read(bytes))!=-1){
//把读到的内容写入新文件中
fos.write(bytes ,0 , len);
}
//释放资源
fis.close();
fos.close();
}
文件夹复制
要求定义一个方法,该方法能够实现文件夹的复制
public static void main(String[] args) throws IOException {
//要求定义一个方法,该方法能够实现文件夹的复制
File srcDir = new File( pathname:"C:\\Users\\root\\Desktop\ltest");
File dest = new File( pathname:"C:\\Users\lroot\\Desktoplltest2");
copyDir(srcDir, dest);
}
//File srcDir源文件夹
//File dest要复制到哪个目录
public static void copyDir(File srcDir, File dest) throws IOException {
if(!(srcDir. exists() &&srcDir.isDirectory ())(
throw new RuntimeException("源文件夹必须存在并且是一个文件夹");
if(!dest.isDirectory ()){
throw new RuntimeException("目标文件夹必须是一个文件夹");
}
//1.在且标文件夹下创建一个和源文件夹凤名的文佚表destDir
File destDir = newFile(dest, srcDir.getName());
destDir.mkdirs());
//2.获取源文件夹下的所有子文佳
File[] files = srcDir.listFiles();
if(files!=nu11){
//3.遍历数组,复制每一个文件到具标文什夹destDir下
for (File file : files){
if(file.isFile()){
copyFile(file, destDir);
}else{
//复制文件夹
copyDir(file,destDir);
}
}
}
}
编码表
计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。如果编码和解码不是用一个编码表就会出现乱码问题。
常见编码表
ASCII
用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
GBK
最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
Unicode
UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
编码规则:
128个US-ASCII字符,只需一个字节编码
拉丁文等字符,需要二个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字节编码
·ANSI
其实不是具体的编码表,它指代系统的默认编码表。例如:简体中文的Windows系统默认编码是GBK。
字符流
当需要读取的数据是存文本的形式时我们可以使用字符流来进行操作会更加方便。
字符输入流
所有字符输入流的父类是 java.io.Reader,它是以字符为单位的输入流。
我们就以其子类FileReader为例进行学习。
FileReader概述
FileReader是用来从文件中读取数据的字符输入流。
FileReader创建对象
构造方法如下:
public FileReader(string fileName) throws FileNotFoundException//传入文件路径创建对象
public FileReader(File file) throws FileNotFoundException //传入文件路径的File对象来创建流对象
范例:
public static void main(String[] args) throws FileNotFoundException {
FileReader fr = new FileReader("C:\\users\\root\\Desktop\\test\\汉字2.txt");
FileReader fr2 = new FileReader(new File("C:\\users\\root\\Desktop\\test\\汉字2.txt"));
}
读取数据
一次读取一个字符
核心方法如下:
public int read() throws IOException //一次读取一个字符返回,如果读到末尾,返回值为-1
范例:
public static void main(String[] args) throws IOException {
//创建流对象
FileReader fr = new FileReader("C:\\users\\root\\Desktop\\test\\11.txt");
//调用方法
int ch ;
while((ch=fr.read()) !=-1){
System.out.print1n((char)ch);
}
//释放资源
fr.close();
}
一次读取一个字符数组
核心方法如下:
public int read(char cbuf[]) throws IOException //一次读取一个字符数组
范例:
public static void main(String[] args) throws IOException {
//创建流对象
FileReader fr = new FileReader("C:\\users\\root\\Desktop\\test\\11.txt");
//读取
char[] chars = new char[1024];
//调用方法
int len;
while((len=fr.read())!=-1){
System.out.print1n(new string (chars ,0 , 1en));
}
//释放资源
fr.close();
}
字符输出流
所有字符输出流的父类是 java.io.Writer,它是以字符为单位的输出流。
我们就以FileWriter为例进行学习。
FileWriter概述
FileWriter是用来往文件写入数据的字符输出流。
FileWriter对象创建
构造方法如下:
public Filewriter(string fileName) throws IOException//传入文件路径创建对象
public Filewriter(File file) throws IOException //传入文件路径的File对象来创建流对象
范例:
public static void main(String[] args) throws FileNotFoundException {
Filewriter fr = new Filewriter("C:\\users\\root\\Desktop\\test\\汉字2.txt");
Filewriter fr2 = new Filewriter(new File("C:\\users\\root\\Desktop\\test\\汉字2.txt"));
}
写入数据
一次写入一个字符
核心方法如下:
public void write(int c) throws IOException //把一个字符写入目的地
public void flush() throws IOException //把缓存区中的数据写入硬盘
范例:
public static void main(String[] args) throws IOException {
//创建流对象
Filewriter fr = new Filewriter("C:\\users\\root\\Desktop\\test\\11.txt");
//写数据
fw.write('三');
fw.write('更');
fw.flush();
fw.write('草');
fw.write('堂');
//释放资源
fw.c1ose();
}
一次写入一个字符数组
核心方法如下:
public void write(char cbuf[]) throws IOException //把一个字符数组写入目的地
范例:
public static void main(String[] args) throws IOException {
//创建流对象
Filewriter fr = new Filewriter("C:\\users\\root\\Desktop\\test\\11.txt");
//写数据
char[] chars = "三更".tocharArray();
fw.write(chars);
fw.flush();
chars ="草堂".tocharArray(O;
fw.write(chars);
//释放资源
fw.c1ose();
}
一次写入一个字符串
核心方法如下:
public void write(String str) throws IOException //把一个字符串写入目的地
范例:
public static void main(String[] args) throws IOException {
//创建流对象
Filewriter fr = new Filewriter("C:\\users\\root\\Desktop\\test\\11.txt");
//写数据
fw.write("三小只");
fw.flush();
fw.write("取个好的", 0, 2);
//释放资源
fw.c1ose();
}
高效缓存流
概念
对硬盘进行数据的读取相比于从内存中存取数据要慢的多。所以DK为我们提供了高效缓冲流来提高我们Io流的效率。内部原理就是借助内存的缓冲区来减少硬盘IO的次数,提高性能。
分类
字节流
输入流
BufferedInputStream
输出流
BufferedoutputStream
字符流
输入流
BufferedReader
输出流
BufferedWriter
对象的创建
构造方法:
public BufferedInputstream(Inputstream in)
public Bufferedoutputstream(Outputstream out)
public BufferedReader (Reader in)
public Bufferedwriter (writer out)
范例:
public static void main(String[] args) throws IOException {
BufferedInputstream bis = new BufferedInputstream(new
Fi1eInputstream("C:\\users\\root\\Desktop\\test\\汉字.txt"));
BufferedOutputstream bos = new BufferedOutputstream(new
Fileoutputstream("C:\\users\\root\\Desktop\\test\\汉字.txt"));
BufferedReader br = new BufferedReader(new
Fi1eReader("C:\\users\\root\\Desktop\\test\\汉字.txt"));
BufferedWriter bw = new Bufferedwriter(new
FileWriter("C:\\users\\root\\Desktop\\test\\汉字.txt"));
}
特有的方法
范例:
public static void main(String[] args) throws IOException {
// readLine
//创建对象
BufferedReader br = new BufferedReader (new
Fi1eReader("C:\\users\\root\\Desktop\\test\\333.txt"));
//读取数据
String line ;
while( (line=br .readLine() !=nu1l){
//把读到的内容输出
System. out.print1n(line);
}
//释放资源
br.c1ose();
}
public static void main(String[] args) throws IOException {
/ /newLine
//创建对象
BufferedWriter bw = new BufferedWriter(new
Filewriter("C:\\users\\root\\ Desktop\ltest\\444.txt"));
//写入数据
bw.write("你好啊");//写入换号符
bw.newLine();
bw.write("我很好");//释放资源
bw.close():
}