目录
一、File类
1、File类的作用
java.io.File类是对存储在磁盘上的文件信息的一个抽象表示,主要用于文件的创建、查找和删除。
2、File类的使用
常用构造方法
public File(string pathname);//通过将给定的字符串路径名转换为抽象路径名来创建File实例
public File(string parent, string child) ;
//通过给定的字符父级串路径和字符串子级路径来创建File实例
public File(File parent, string child);//通过父级抽象路径名和字符串子路径创建File实例
例子
package IO_files;
import java.io.File;
public class test1 {
public static void main(String[] args) {
//以下三种文件生成方法结果都是"F:\\a\\b\\c.txt"
File file1=new File("F:\\a\\b\\c.txt");
File file2=new File("F:\\a\\b","c.txt");
File parent=new File("F:\\a\\b");
File file3=new File(parent,"c.txt");
}
}
获取文件相关信息方法
public string getAbsolutepath(); //获取文件的绝对路径
public string getName();//获取文件的名字
public string getpath();//获取文件的路径
public File getParentfile();//获取文件的父文件
public string getParent();//获取文件的父文件路径public long length();//获取文件的大小
public long lastModified();//获取文件最后修改时间
例子
package IO_files;
import java.io.File;
public class test2 {
public static void main(String[] args) {
File file1=new File("F:\\a\\b\\c.txt");
//获取文件的绝对路径
String absPath=file1.getAbsolutePath();
System.out.println(absPath);
//获取文件的路径,可能是相对路径,也可能是绝对路径
String path=file1.getPath();
System.out.println(path);
String name=file1.getName();//获取文件名
System.out.println(name);
//获得文件的父级文件夹对象
File parentFile=file1.getParentFile();
System.out.println(parentFile);
//获得文件的父级路径
String parentPath=file1.getParent();
System.out.println(parentPath);
//获取文件的大小,单位是字节
long length=file1.length();
System.out.println(length);
//获取文件的最后修改时间
long lastUpdateTime=file1.lastModified();
System.out.println(lastUpdateTime);
//获取系统当前时间:单位毫秒
long currentTime=System.currentTimeMillis();
System.out.println(currentTime);
File file2=new File("chapter4\\c.txt");
System.out.println(file2.getAbsolutePath());
System.out.println(file2.getPath());
}
}
文件的相关判断方法
public boolean canRead();//是否可读
public boolean canwrite();//是否可写
public boolean exists();//是否存在
public boolean isDirectory()://是否是目录
public boolean isFile();//是否是一个正常的文件
public boolean isHidden();//是否隐藏
public boolean canExecute();//是否可执行
public boolean createNewFile() throws IOException;
//创建新的文件
public boolean delete();//删除文件
public boolean mkdir();//创建目录,一级
public boolean mkdirs();//创建目录,多级
public boolean renameTo(File dest);//文件重命名
例子
package IO_files;
import java.io.File;
import java.io.IOException;
public class test3 {
public static void main(String[] args) {
File file1=new File("D:\\:record\\stu.txt");
//判断文件是否可读
boolean readable=file1.canRead();
System.out.println("文件是否可读:"+readable);
//判断文件是否可写
boolean writeable=file1.canWrite();
System.out.println("文件是否可写:"+writeable);
//判断文件是否存在
boolean exists=file1.exists();
System.out.println("文件是否存在:"+exists);
//判断文件是否是目录
boolean isDirectory=file1.isDirectory();
System.out.println("文件是否是目录:"+isDirectory);
File parent=file1.getParentFile();
System.out.println("父级文件是否是目录:"+parent.isDirectory());
//判断文件是否是隐藏文件
boolean hidden=file1.isHidden();
System.out.println("文件是否是隐藏文件:"+hidden);
//判断文件是否可执行
boolean executable=file1.canExecute();
//可执行文件定义:是指双击后有反应的文件
System.out.println("文件是否可执行:"+executable);
//创建新的文件
File newFile=new File("D:\\test\\new.txt");
File parentFile=newFile.getParentFile();
if(!parentFile.exists()){ //exists 通常会与创建目录的方法配合使用
//创建父级目录,但只能创建一级
// parentFile.mkdir();
//创建多级父级目录
parentFile.mkdirs();
}
if(!newFile.exists()){
try {
//创建文件时,必须保证该文件的父级目录存在,否则,创建将报IO异常
boolean success=newFile.createNewFile();
System.out.println("文件创建是否成功:"+success);
} catch (IOException e) {
e.printStackTrace();
}
}
boolean deleteSuccess=file1.delete();
System.out.println("文件是否被删除:"+deleteSuccess);
//删除文件夹时,必须保证文件夹中没有任何文件,也就是保证文件夹是空的
boolean deleteFolderSuccess=parentFile.delete();
System.out.println("文件夹删除是否成功:"+deleteFolderSuccess);
File renameFiles=new File("F:\\test\\stu_new\\new.txt");
//文件重命名至目标文件夹时,必须保证目标文件夹存在。重命名操作成功后,
//原来的文件就移动过去了。
boolean renameSuccess=newFile.renameTo(renameFiles);
System.out.println("文件重命名是否成功:"+renameSuccess);
}
}
注:删除文件夹时,必须保证文件夹为空,否则将删除失败。
文件列表相关方法
public File[ ] listFiles(); //列出文件夹下所有文件
public File[ ] listFiles(FileFilter filter); //列出文件夹下所有满足条件的文件
例子
package IO_files;
import java.io.File;
import java.io.FileFilter;
public class test4 {
public static void main(String[] args) {
File directory=new File("D:\\java study\\IDEA_list");
//列出文件夹中所有的文件
File[] files=directory.listFiles();
//需要做非空判断,因为目录可能是非法的,也可能是不存在的
// if(files!=null){
for (int i=0;i<files.length;i++){
File file=files[i];
}
for (File file:files){//增强for循环,效果与上面注释代码相同
System.out.println(file.getPath());
}
File folder=new File("D:\\idea\\IntelliJ IDEA 2020.1\\bin");
//FileFilter是一个匿名内部类,相当于将类的名字隐藏起来
FileFilter filter=new FileFilter() {
//accept表示接受文件的条件
@Override
public boolean accept(File file) {
String name=file.getName();//获取文件名,也包含后缀在内
return name.endsWith(".exe");//表示将后缀为".exe"的文件返回
//startsWith("") 表示检测到以""内的内容为开头的字符串
}
};
File[] childFiles=folder.listFiles(filter);
if(childFiles!=null){
for (File file:childFiles){
System.out.println(file);
}
}
}
}
递归学习
认知概念:
在方法内部再调用自身就是递归。递归分为直接递归和间接递归。
直接递归就是方法自己调用自己。
间接递归就是多个方法之间相互调用,形成一个闭环,从而构成递归。
使用递归时必须要有出口,也就是使递归停下来。否则,将导致栈内存溢出。
例子
package IO_files;
public class test5 {
public static void main(String[] args) {
int result=sum(5);
System.out.println(result);
int result1=multiply(5);
System.out.println(result1);
}
public static int sum(int number){//递归实现累加求和
if(number==1)
return 1;
return number+sum(number-1);
}
public static int multiply(int number){//递归实现阶乘
if(number==0||number==1)
return 1;
return number*multiply(number-1);
}
}
思考学习——任何删除一个文件夹
代码如下:
package IO_files;
import java.io.File;
import java.io.FileFilter;
public class test6 {
public static void main(String[] args) {
File folder = new File("D:\\java study");
recursiveFolder(folder);
}
public static void recursiveFolder(File folder) {
if (folder.isDirectory()) {//检查是否是文件夹
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {//如果是文件夹,就再调用方法看看
recursiveFolder(file);
} else {
System.out.println(folder.getPath());
}
}
} else { //不是文件夹就直接打印文件的路径
System.out.println(folder.getPath());
}
}
}
//实现文件夹删除
public static void deleteFolder(File folder){
if(folder.isDirectory()) {//是文件夹就需要再进去看
File[] files = folder.listFiles();
if(files!=null){
for(File file:files){
if(file.isDirectory()){
deleteFolder(file);
} else {
file.delete();
}
}
folder.delete();//文件夹中文件删除完毕后,文件夹也要删除
}
} else {//不是文件夹,直接删除
folder.delete();
}
}
}
二、I/O流学习
1、初步了解
I/O的来源
I/O是Input和Ouput两个单词的首字母,表示输入输出。其参照物就是内存,写入内存,就是输入,从内存读取数据出来,就是输出。
Java中的I/O流
磁盘和内存是两个不同的设备,它们之间要实现数据的交互,就必须要建立一条通道, 在Java中实现建立这样的通道的是I/0流。Java中的I/0流是按照数据类型来划分的。分别是字节流(缓冲I、二进制数据流和对象流)、字符流。
2、字节流
说明
程序使用字节流执行8位字节的输入和输出,所有字节流类均来自InputStream和OutputStream。
字节流仅仅适用于读取原始数据(基本数据类型)。
OutputStream常用方法
public abstract void write(int b); //写一个字节
public void write(byte b[ ]) throws IOException;
//将给定的字节数组内容全部写入文件中//将给定的字节数组中指定的偏移量和长度之间的内容写入文件中
public void write(byte b[ ], int off, int len) throws IOExCeption;
public void flush() throws IOException;
//强制将通道中数据全部写出public void close() throws IOException;//关闭通道
文件输入流 FileOutputStream 构造方法
public Fileoutputstrean(string name) throws FileNotFoundException;
//根据提供的文件路径构建条一条文件输出通道
//根据提供的文件路径构建一条文件输出通道,并根据append的值决定是将内容追加到末尾还是直接覆盖public Fileoutputstrean(string name, boolean append) throws Fi leNotFoundException;
public Fileoutputstream(File file) throws FileNotFoundException;
//根据提供的文件信息构建一条文件输出通道
//根据提供的文件信息构建一条文件输出通道,并根据append的值决定是将内容追加到末尾还是直接覆盖public Fileoutputstream(File file, boolean append) throws FileNotFoundException;
示例:将"IO流学习"写入磁盘中
代码如下:
package ByteStreams;
import java.io.*;
public class test1 {
public static void main(String[] args) {
//将内容写入文件时,需要保证这个文件的父级目录一定存在,否则将报文件未找到异常
try {
File dir=new File("D:\\as");
if(!dir.exists()){
dir.mkdirs();
}
File file=new File(dir,"io.txt");
//OutputStream os=new FileOutputStream("D:\\as\\io.txt"); 与上面功能相同
//实现内容再写入一次
OutputStream os=new FileOutputStream(file,true);
String text="IO流学习";
byte[] bytes=text.getBytes();
// for(byte b:bytes){
// os.write(b);//一次写一个字节至文件中
// }
//向通道中一次将所有字节数组中的内容发送过去
//os.write(bytes);
//使用偏移量和长度的时候要考虑数组下标越界
os.write(bytes,1,bytes.length);//偏移一个字节
//在通道关闭之前使用,强制将通道中的数据写入文件中
os.flush();
os.close();//关闭通道
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputStream常用方法
public abstract int read() throws IOException; //读取一个字节
public int read(byte b[ ]) throws IOException; //读取多个字节存储至给定的字节数组中
//读取多个字节按照给定的偏移量及长度存储在给定的字节数组中
public int read(byte b[ ],int off, int len) throws IOException;
public void close() throws IOException;//关闭流, 也就是关闭磁盘和内存之间的通道
public int available() throws IOException;// 获取通道中数据的长度
文件输入流 FileInputStream构造方法
public abstract int read() throws IOException; //读取一个字节
public int read(byte b[ ]) throws IOException; //读取多个字节存储至给定的字节数组中
示例:使用文件输入流将文件信息从磁盘中读取到内存中来,并在控制台输出
代码如下:
package ByteStreams;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/*
使用文件输入流将文件信息从磁盘中读取到内存中来,并在控制台输出
*/
public class test2 {
public static void main(String[] args) {
try {
InputStream is=new FileInputStream("D:\\as\\io.txt");
int length=is.available();//获取通道中的长度
//根据通道中数据长度构建字节数组,但需要考虑到一点,
//如果通道中数据长度过长,那么字节数组构建太大,则
//可能导致内存不够,比如使用流读取一个大小为10G的文
//件,这种方式存在弊端
byte[] buffer=new byte[length];
int index=0;
// while(true){
// //读取通道中的数据,一次读取一个字节,如果读到末尾,则返回-1
// byte b=(byte) is.read();
// if(b==-1)
// break;
// buffer[index++]=b;
// }
//read() 有返回值,返回值是输入总字节数
is.read(buffer);//上面代码与此代码效果相同
System.out.println(new String(buffer));
is.close();//关闭通道
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
补充学习代码
package ByteStreams;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class test3 {
public static void main(String[] args) {
try {
InputStream is=new FileInputStream("D:\\as\\io.txt");
//实际开发过程中字节数组的长度一般定义为1024的整数倍
byte[] buffer=new byte[30];//构建了一个长度为30的字节数组
while(true){
//从通道中读取数据存入字节数组buffer中,返回值就是读取的字节长度
//如果读取到数据末尾,则返回-1
int len=is.read(buffer);
if(len==-1) break;
System.out.println(len);
}
// int count1=is.read(buffer);//输出30
// int count2=is.read(buffer);//输出30
// int count3=is.read(buffer);//输出1
// int count4=is.read(buffer);//输出-1
// System.out.println(count1);
// System.out.println(count2);
// System.out.println(count3);
// System.out.println(count4);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注:如果通道中数据长度过长,那么根据通道中数据的长度来构建字节数组,则可能导致内存不够,比如使用流读取一个大小10G的文件那么通道中就应该存在10G长的数据。
思考代码:
package ByteStreams;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class test4 {
public static void main(String[] args) {
try {
InputStream is=new FileInputStream("D:\\as\\io.txt");
byte[] buffer=new byte[1024];
int offset=0;
while ((true)){
int len=is.read(buffer,offset,40);
if(len==-1) break;
System.out.println(len);
offset+=len;
}
//System.out.println(new String(buffer));//输出文本内容
System.out.println(new String(buffer,0,offset));//效果与上面代码一样
is.close();
// int pos1=is.read(buffer,0,40);
// int pos2=is.read(buffer,40,40);
// int pos3=is.read(buffer,80,40);
// System.out.println(pos1);
// System.out.println(pos2);
// System.out.println(pos3);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
练习:使用字节流实现磁盘文件拷贝功能
代码如下:
package ByteStreams;
import java.io.*;
/**
* 使用字节流实现磁盘文件拷贝功能
*/
public class test5 {
public static void main(String[] args) {
String soureFile = "D:\\as\\io.txt";//目标文件
String destFile = "D:\\at\\iu.txt";//新的文件
copyFile(soureFile,destFile);
}
public static void copyFile(String soureFile,String destFile){
File file=new File(destFile);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();//检测父级目录是否存在,不存在就创建一个
try {
InputStream is=new FileInputStream(soureFile);
OutputStream os=new FileOutputStream(destFile);
byte[] buffer=new byte[4096];//1024*4
while(true){
int len=is.read(buffer);
if(len==-1) break;
os.write(buffer,0,len);
}
os.flush();
is.close();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
进阶版:
package ByteStreams;
import java.io.*;
/**
* 使用字节流实现磁盘文件拷贝功能(改进版)
*/
public class test6 {
public static void main(String[] args) {
String soureFile = "D:\\as\\io.txt";//目标文件
String destFile = "D:\\at\\iu.txt";//新的文件
copyFile1(soureFile, destFile);
}
public static void copyFile1(String soureFile, String destFile) {
File file = new File(destFile);
File parent = file.getParentFile();
if (!parent.exists()) parent.mkdirs();//检测父级目录是否存在,不存在就创建一个
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(soureFile);
os = new FileOutputStream(destFile);
byte[] buffer = new byte[4096];//1024*4
while (true) {
int len = is.read(buffer);
if (len == -1) break;
os.write(buffer, 0, len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {//清除缓存
// if (is != null){
// try {
// is.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// if (os != null) {
// try {
// os.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
close(is, os);//效果与上述注释代码相同
}
}
//Cloneable...c 是不定长自变量,它本质是一个数组,在使用不定长自变量
//作为方法的参数时,必须为该方法参数列表的最后一个参数
public static void close(Closeable... closeables) {
for (Closeable c : closeables) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void copyFile2(String soureFile, String destFile) {
File file = new File(destFile);
File parent = file.getParentFile();
if (!parent.exists()) parent.mkdirs();//检测父级目录是否存在,不存在就创建一个
//try(){}catch(){} JDK 1.7及其后续版本才能使用
//写在括号中的代码只能够实现AutoClosable接口的类
//不需要考虑关闭操作
try(InputStream is = new FileInputStream(soureFile);
OutputStream os = new FileOutputStream(destFile);) {
byte[] buffer = new byte[4096];//1024*4
while (true) {
int len = is.read(buffer);
if (len == -1) break;
os.write(buffer, 0, len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、字符流
说明
a、Java平台使用unicode约定存储字符值。字符流I/O会自动将此内部格式与本地字符集转换。在西方语言环境中, 本地字符集通常是ASCII的8位超集。
b、所有字符流类均来自Reader和Writer。与字节流一样, 也有专门用于文件I/O的字符流类: FileReader和Filewriter。
Writer常用方法
public void write(int c) throws IOException; //写一个字符
public void write(char cbuf[ ]) throws IOException;//将给定的字符数组内容写入到文件中
//将给定的字符数组中给定偏移量和长度的内容写入到文件中
abstract public void write(char cbuf[ ], int off, int len) throws IOException;
public void write(string str) throws IoException;//将字符写入到文件中
abstract public void flush() throws IOException;//强制将通道中的数据全部写出
abstract public void close() throws IOException;//关闭通道
FileWriter构造方法
public Filewriter(string fileName) throws IOException;//根据提供的文件路径构建一条文件输出通道
//根据提供的文件路径构建一条文件输出通道,并根据append的值决定是将内容追加到末尾还是直接覆盖public Filewriter(string fileName, boolean append) throws IOException;
public Filewriter(File file) throws IOException:;//根据提供的文件信息构建一 条文件输出通道
//根据提供的文件信息构建一条文件输出通道,并根据append的值决定是将内容追加到末尼还是直接覆盖public Filewriter(File file, boolean append) throws IOExCeption;
示例:使用字符流将"IO流学习"写入磁盘文件中
代码如下:
package IO_char;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class test1 {
public static void main(String[] args) {
File file=new File("D:\\as\\io.txt");
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
//Writer类实现了AutoCloseable接口,因此可以将Writer类对象的构建方法
//写在try后面的()中
try(Writer writer=new FileWriter("D:\\as\\io.txt",true);) {
String text="IO流学习";
// char[] values=text.toCharArray();
// for(char c:values){
// writer.write(c);
// }
// writer.write(values);//重写一遍内容到文件中
// writer.write(values,0,values.length);//进行偏移,重写一遍内容到文件中
writer.write(text);//重写一遍内容到文件中
writer.flush();//强制将通道中的数据写入文件
} catch (IOException e) {
e.printStackTrace();
}
}
}
Reader常用方法
public int read() throws IOException; //读取一个字符
public int read(char cbuf[ ]) throws IOException; //读取字符到给定的字符数组中I
//将读取的字符按照给定的偏移量和长度存储在字符数组中
abstract public int read(char cbuf[ ], int off,int len) throws IOExCeption;
abstract public void close() throws IOException;//关闭通道
FileReader构造方法
public FileReader(string filename) throws FilenotFoundException;//根据提供的文件路径构建一 条文件输入通道
public FileReader(File file) throws FilenotFoundException://根据提供的文件信息构建一条文件输入通道
示例:使用字符流将文件信息从磁盘中读取到内存中,并在控制台输出
代码如下:
package IO_char;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class test2 {
public static void main(String[] args) {
try(Reader reader=new FileReader("D:\\as\\io.txt");) {
// StringBuilder builder=new StringBuilder();
// while(true){
// int c=reader.read();
// if(c==-1) break;
// builder.append((char)c);
// }
// System.out.println(builder);
char[] buffer=new char[4096];
int offset=0;
while(true){
// int len=reader.read(buffer);
int len=reader.read(buffer,offset,30);
if(len==-1) break;
offset+=len;
}
System.out.println(new String(buffer,0,offset));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
练习:使用字符流实现磁盘文件拷贝功能
代码如下:
package IO_char;
import java.io.*;
/**
* 使用字符流实现磁盘文件拷贝功能
*/
public class test3 {
public static void main(String[] args) {
String soureFile = "D:\\as\\io.txt";
String destFile = "D:\\at\\ix.txt";
copyFile(soureFile,destFile);
}
public static void copyFile(String sourceFile,String destFile){
File file=new File(destFile);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(Reader reader=new FileReader(sourceFile);
Writer writer=new FileWriter(destFile)) {
char[] buffer=new char[4096];
while (true){
int len=reader.read(buffer);
if(len==-1) break;
writer.write(buffer,0,len);
}
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4、缓冲流
说明
到目前为止,我们看到的大多数示例都使用无缓冲的I/O。这意味着每个读取或写入请求均由基础操作系统直接处理。由于每个这样的请求通常会触发磁盘访问,网络活动或某些其他相对昂贵的操作,因此这可能会使程序的效率大大降低。
为了减少这种开销,Java平台实现了缓冲的I/O流。缓冲的输入流从称为缓冲区的存储区中读取数据;仅当缓冲区为空时才调用本机输入API。同样, 缓冲的输出流将数据写入缓冲区,并且仅在缓冲区己满时才调用本机输出API。
有四种用于包装非缓冲流的缓冲流类:BufferedInputstream 和Bufferedoutputstream创建缓冲的字节流,而BufferedReader和Bufferedwriter创建缓冲的字符流。
BufferedOutputStream构造方法
public Bufferedoutputstream(outputstream out);//根据给定的字节输出流创建一个缓冲输出流,缓冲区大小使用默认大小
public Bufferedoutputstream(outputstream out, int size) ;//根据给定的字节输出流创建一个缓冲输出流, 并指定缓冲区大小
BufferedInputStream构造方法
public BufferedInputstream(Inputstream in); //根据给定的字节输入流创建一个缓冲输入流,缓冲区大小使用默认大小
public BufferedInputstream(Inputstream in, int size);//根据给定的字节输入流创建一个缓冲输入流,并指定缓冲区大小
练习:缓冲字节流实现文件拷贝
代码如下:
package IO_char;
import java.io.*;
/**
* 缓冲字节流实现文件拷贝
*/
public class test4 {
public static void main(String[] args) {
String soureFile = "D:\\as\\io.txt";
String destFile = "D:\\at\\ix.txt";
copyFile(soureFile,destFile);
}
public static void copyFile(String soureFile,String destFile){
File file=new File(destFile);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(InputStream is=new FileInputStream("");
BufferedInputStream bis=new BufferedInputStream(is);
OutputStream os=new FileOutputStream("");
BufferedOutputStream bos=new BufferedOutputStream(os)){
byte[] buffer=new byte[4096];
while (true){
int len=bis.read(buffer);
if(len==-1) break;
bos.write(buffer,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
练习:缓冲字符流实现文件拷贝
代码如下:
package IO_char;
import java.io.*;
/**
* 缓冲字符流实现文件拷贝
*/
public class test5 {
public static void main(String[] args) {
String soureFile = "D:\\as\\io.txt";
String destFile = "D:\\at\\ix.txt";
copyFile(soureFile,destFile);
}
public static void copyFile(String soureFile,String destFile){
File file=new File(destFile);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(Reader reader=new FileReader("");
BufferedReader br=new BufferedReader(reader);
Writer writer=new FileWriter("");
BufferedWriter bw=new BufferedWriter(writer)) {
char[] buffer=new char[4096];
while (true){
int len=br.read(buffer);
if(len==-1) break;
bw.write(buffer,0,len);
}
bw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
补充内容
package IO_char;
import java.io.*;
public class test6 {
public static void main(String[] args) {
String sourceFile = "D:\\buffer\\io.txt";
String destFile = "D:\\copy\\copy.txt";
}
public static void copyFile(String sourceFile,String destFile){
File file=new File(destFile);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(Reader reader=new FileReader(sourceFile);
BufferedReader br=new BufferedReader(reader);
Writer writer=new FileWriter(file);
BufferedWriter bw=new BufferedWriter(writer)) {
while (true){
String line=br.readLine();//读行
if(line==null) break;
bw.write(line);//写行
bw.newLine();//换行 => 相当于写入了一个 \r\n
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readLine(){
String path="D:\\buffer\\io.txt";
try(Reader reader=new FileReader(path);
BufferedReader br=new BufferedReader(reader)) {
while (true){
String line=br.readLine();
if(line==null) break;
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeLine(){//写行
String path="D:\\buffer\\io.txt";
File file=new File(path);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(Writer writer=new FileWriter(file);
BufferedWriter bw=new BufferedWriter(writer)) {
bw.write("这是第一行");
bw.newLine();
bw.write("这是第二行");
bw.newLine();
bw.write("这是第三行");
bw.newLine();
/*
文件内容如下:
这是第一行
这是第二行
这是第三行
*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
5、数据流
说明
数据流支持原始数据类型值(布尔值,char,字节,short, int, long. float 和double)以及String值的二进制I/O。所有数据流都实现DataInput接口或Dataoutput接口。本 节重点介绍这些接口的最广泛使用的实现,即DataInputStream和DataOutputStream。
DataOutput 接口常用方法
void writeBoolean(boolean v) throws IOException;
//将布尔值作为1个字节写入底层输出通道
void writeByte(int v) throws IOException;//将字节写入底层输出通道
void writeShort(int v) throws IOException;//将短整数作为2个字节(高位在前)写入底层输出通道
void writeChar(int v) throws IOException;//将字符作为2个字节写(高位在前)入底层输出通道
void writeInt(int v) throws IOException;//将整数作为4个字节写(高位在前)入底层输出通道
void writeLong(long v) throws IOException;//将长整数作为8个字节写(高位在前)入底层输出通道
void writeFloat(float v) throws IOException;//将单精度浮点数作为4个字节写(高位在前)入底层输出通道
void writeDouble(double v) throws IOException;//将双精度浮点数作为8个字节写(高位在前)入底层输出通道
void writeUTF(string s) throws IoException;//将UTF-8编码格式的字符串以与机器无关的方式写入底层输出通道
DataOutputStream构造方法
public DataOutputStream(OutputStream out); 根据给定的字节输出流创建一个二进制输出流
使用示例
private static void writeData(){
String path="D:\\data\\io.txt";
File file=new File(path);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(OutputStream os=new FileOutputStream(file);
DataOutputStream dos=new DataOutputStream(os)) {
dos.writeByte(-1);
dos.writeShort(-2);
dos.writeInt(1);
dos.writeLong(100);
dos.writeFloat(1.0f);
dos.writeDouble(100.0);
dos.writeChar('a');
dos.writeBoolean(true);
dos.writeUTF("这是UTF-8编码格式的字符串");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
DataInput 接口常用方法
boolean readBoolean() throws IOException;
//读取一 个字节,如果为0,则返回false: 否则返回true
byte readByte() throws IOException;//读取一个字节
int readunsignedByte() throws IOException;//读取一个字节,返回0-255之间的整数
short readShort() throws IOException;//读取2个字节,然后返一个短整数
int readunsignedshort() throws IOException;//读取2个字节, 返回一个0-65535之间的整数
char readChar() throws IOException;//读取2个字节, 然后返回一个字符
int readInt() throws IOException;//读取4个字节,然后返回一个整数
long readLong() throws IOException;//读取8个字节, 然后返一个长整数
float readFloat() throws IOException;//读取4个字节, 然后返一个单精度浮点数
double readDouble() throws IOException;//读取8个字节, 然后返回一个双精度浮点数
string readUTF() throws IOException;//读取一个使用UTF-8编码格式的字符串
DataInputStream构造方法
public DataInputstream(InputStream in) ;//根据给定的字节输入流创建个二进制输入流
使用示例
public static void main(String[] args) {
String path = "D:\\data\\io.txt";
try(InputStream is=new FileInputStream(path);
DataInputStream dis=new DataInputStream(is)) {
byte b=dis.readByte();
System.out.println("读取字节"+b);
short s=dis.readShort();
System.out.println("读取短整数"+s);
int i=dis.readInt();
System.out.println("读取整数"+i);
long l=dis.readLong();
System.out.println("读取长整数"+l);
float f=dis.readFloat();
System.out.println("读取单精度浮点数"+f);
double d=dis.readDouble();
System.out.println("读取双精度浮点数"+d);
char c=dis.readChar();
System.out.println("读取字符"+c);
boolean bool=dis.readBoolean();
System.out.println("读取布尔值"+bool);
String str=dis.readUTF();
System.out.println("读取字符串"+str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (EOFException e){//EndofFile
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
注意:Datastreams通过捕获EOFException来检测文件结束条件,而不是测试无效的返回值。DataInput方法的所有实现都使用EOFException而不是返回值。
6、对象流
说明
正如二进制数据流支持原始数据类型的I/O一样,对象流也支持对象的I/O。大多数(但不是全部)标准类支持其对象的序列化。那些类实现了序列化标记接口Serializable才能够序列化。
ObjectOutput 接口常用方法
public void writeobject(object obj) throws IOException;//将对象写入底层输出通道
ObjectOutputSteam构造方法
public objectoutputstrean(outputstream out) throws IOException;
//根据给定的字节输出流创建一个对象输出流
使用示例
package ObjectStreams;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
private static void writeObject(){
String path="D:\\Object\\obj.txt";
File file=new File(path);
File parent=file.getParentFile();
if(!parent.exists()) parent.mkdirs();
try(OutputStream os=new FileOutputStream(file);
ObjectOutputStream oos=new ObjectOutputStream(os)) {
oos.writeObject(new Student("ash",20));
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
注:将一个对象从内存中写入磁盘文件中的过程称之为序列化。序列化必须要求该对象所有类型实现序列化的接口。
ObjectInput 接口常用方法
public object readobject() throws ClassnotFoundException, IOExCeption;//读取一个对象
ObjectInputStream构造方法
public objectInputstrean(Inputstream in) throws IOException;
//根据给定的字节输入流创建一个对象输入流
使用示例
package ObjectStreams;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
private static void readObject(){
String path="D:\\Object\\obj.txt";
try(InputStream is=new FileInputStream(path);
ObjectInputStream ois=new ObjectInputStream(is)) {
Student s= (Student) ois.readObject();
System.out.println(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
注:将磁盘中存储的对象信息读入内存中的过程称之为反序列化,需要注意的是,反序列化必须保证与序列化时使用的JDK版本一致。
三、将一个字节流转换成一个字符流
代码如下:
import java.io.*;
public class IOConverter {
public static void main(String[] args) {
write();
read();
}
private static void write(){
try(OutputStream os=new FileOutputStream("D:\\as\\line.txt");
OutputStreamWriter osw=new OutputStreamWriter(os);
BufferedWriter bw=new BufferedWriter(osw)) {
String[] lines={
"这是写入的第一行",
"这是写入的第一行,",
"这是写入的第一行,",
"这是写入的第一行,"
};
for (String line:lines){
bw.write(line);
bw.newLine();//实现换行
}
bw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void read(){
try(InputStream is=new FileInputStream("D:\\as\\line.txt");
InputStreamReader isr=new InputStreamReader(is);
BufferedReader reader=new BufferedReader(isr);) {
while (true){
String line=reader.readLine();
if(line==null) break;
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}