JAVA IO流(一)
(一) 文件
1.概念
文件就是保存数据的地方
-
文件流
文件在程序中是以流的形式来操作的。
java程序(内存) <--------> 文件(磁盘)
输入,输出是针对 内存而言的
- 流:数据在数据源(文件)和程序(内存)之间经历的路径
- 输入流:数据从数据源(文件)到程序(内存)的路径
- 输出流:数据从程序(内存)到数据源(文件)的路径
2.常用文件操作
-
创建文件对象的相关构造器和方法(常用)
- new File(String pathname) //根据路径构建一个File对象
- new File(File parent, String child) //根据父目录文件+子路径构建
- new File(String parent,String) //根据父目录 + 子路径构建
- createNewFile 创建新文件
import java.io.File; import java.io.IOException; public class FileCreate { public static void main(String[] args) { //在d盘下,创建文件 news1.txt,news2.txt,news3.txt,用三种不同方式创建 // FileCreate.create01(); //方式1 // FileCreate.create02(); FileCreate.create03(); } //方式1 new File(String pathname) 根据路径构建一个File对象 // 注意:d:\\不能写成 d , d 表示当前目录下 //创建文件 news1.txt public static void create01() { String filePath = "d:\\news1.txt"; File file = new File(filePath);//此时有file对象,在内存中,但是还没和磁盘发生关系 try { file.createNewFile();//此处真正创建文件到磁盘 System.out.println("文件创建成功!"); } catch (IOException e) { e.printStackTrace(); } } //方式2 new File(File parent, String child) 根据父目录文件+子路径构建 public static void create02() { File parentFile = new File("d:\\");//先创建父目录 String fileName = "news2.txt";//子路径构建 //此时,file在内存中只是一个对象,只有执行createNewFile()方法后,才能在磁盘中创建文件 File file = new File(parentFile, fileName); try { file.createNewFile();//此处真正创建文件到磁盘 System.out.println("文件创建成功!"); } catch (IOException e) { e.printStackTrace(); } } //方式3 new File(String parent,String) //根据父目录 + 子路径构建 public static void create03() { String parentPath = "d:\\"; String fileName = "news3.txt"; File file = new File(parentPath, fileName); try { file.createNewFile();//此处真正创建文件到磁盘 System.out.println("文件创建成功!"); } catch (IOException e) { e.printStackTrace(); } finally {//获取文件相关信息 System.out.println("文件名:"+file.getName()); System.out.println("文件绝对路径:"+file.getAbsolutePath()); System.out.println("文件大小(字节):"+file.length()); System.out.println("文件父级目录:"+file.getParent()); System.out.println("文件是否存在:"+file.exists()); System.out.println("是否为文件:"+file.isFile()); System.out.println("是否为目录:"+file.isDirectory()); } } }
-
File类实现了两个接口:Serializable , Comparable
-
文件对象常用方法:获取文件名:getName();文件绝对路径:getAbsolutePath(); 文件父级目录:getParent(); 文件大小(字节):length(); 文件是否存在:exists(); 是不是一个文件:isFile();是不是一个目录:isDirectory()
-
目录操作
import java.io.File; public class DirectoryDemo { public static void main(String[] args) { DirectoryDemo.method1(); DirectoryDemo.method2(); DirectoryDemo.method3(); } //判断:d:\\news1.txt是否存在,若存在则删除 public static void method1() { String filePath = "d:\\news3.txt"; File file = new File(filePath); if(file.exists()) { if(file.delete()) { //delete方法返回布尔值 System.out.println(filePath + "删除成功"); } else { System.out.println(filePath + "删除失败"); } } else { System.out.println("文件不存在"); } } //判断 D:\\demo02 是否存在,存在就删除 //重点:java中,目录也是一种特殊的文件 public static void method2() { String filePath = "d:\\demo02"; File file = new File(filePath); if(file.exists()) { if(file.delete()) { //delete方法返回布尔值 System.out.println(filePath + "删除成功"); } else { System.out.println(filePath + "删除失败"); } } else { System.out.println("该目录不存在"); } } //判断 d:\\demo\\a\\b\\c 目录是否存在,存在提示存在,否则创建 public static void method3() { String directoryPath = "d:\\demo\\a\\b\\c"; File file = new File(directoryPath); if(file.exists()) { System.out.println(directoryPath + "已存在"); } else { if(file.mkdirs()) {//mkdir()创建一级目录,mkdirs()多级目录,返回值为boolean System.out.println(directoryPath + "创建成功"); } else { System.out.println(directoryPath + "创建失败"); } } } }
(二)IO 流原理及流的分类
-
流的分类
- 按操作数据单位不同分为:字节流(8 bit)(处理二进制文件,无损),字符流(按字符,大小视编码而定)(适用文本文件)
- 按数据流的流向:输入流,输出流
- 按流的角色分:节点流,处理流/包装流
(抽象基类) 字节流 字符流 输入流 InputStream Reader 输出流 OutpurStream Writer 以上四个都为抽象类,使用时必须创建实现子类。Java的IO流40多个类都从4个抽象基类派生,由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
1.File字节/字符流
常用子类
- FileInputStream: 文件输入流
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
1.1 FileInputStream: 文件字节输入流
示例:使用FileInputStream读取hello.txt文件,并将文件内容显示到控制台
/**
* @author jayz
* @version 1.0
* 演示FileInputStream的使用(字节输入流 文件 --> 程序)
*/
public class FileInputStreamDemo {
public static void main(String[] args) {
//readFile01();
readFile02();
}
//单个字节读取,效率较低,优化:使用read(byte[] b)
public static void readFile01() {
String filePath = "d:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
//创建FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
//从该输入流读取一个字节的数据。达到文件末尾,返回-1
//因为字节流每次读取一个字节,若文件中包含汉字,以UTF-8为例,一个汉字占3字节,字节读取一个字节就输出了
//会出现乱码,所以文本文档一般用字符流处理
while((readData = fileInputStream.read()) != -1) {
System.out.print((char)readData); //转成char显示
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//优化:使用read(byte[] b)读取文件
//从输入流读取最多b.length字节的数据到字节数组,返回-1,表示读取完毕。
//如果读取正常,返回的是实际读取的字节数,超出定义的大小,也会自动返回实际读取字节数
public static void readFile02() {
String filePath = "d:\\hello.txt";
int bufLen = 0;
//字节数组
byte[] buffer = new byte[8];//一次读取8个字节
FileInputStream fileInputStream = null;
try {
//创建FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
while((bufLen = fileInputStream.read(buffer)) != -1) {
System.out.print(new String(buffer,0,bufLen)); //转成char显示
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭文件流,释放资源
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.2FileOutputStream:文件字节输出流
示例: 使用FileOutputStream在a.txt文件中,写入“hello,world",如果文件不存在,则创建文件
//new FileOutputStream(filePath),写入内容会覆盖原来的内容。
//new FileOutputStream(filePath,true)此方式创建对象,写入内容会追加到文件末尾
//FileOutputSteam使用案例,将数据写到文件中,文件不存在则创建该文件
public class FileOutputStreamDemo01 {
public static void main(String[] args) {
writeFile();
}
public static void writeFile() {
//创建 FileOutputStream对象
String filePath = "d:\\a.txt";
FileOutputStream fileOutputStream = null;
try {
//得到 FileOutputStream对象
fileOutputStream = new FileOutputStream(filePath,true);
//1.写入一个字节
//fileOutputStream.write('H');
//2.写入字符串
String str = "!!Hello,world~!";
//str.getBytes() 将字符串 -> 字节数组
//fileOutputStream.write(str.getBytes());
//3.write(byte[] b, int off, int len),指定写入起点和长度
fileOutputStream.write(str.getBytes(),0,str.length());
//以上三种方式,每次运行都会覆盖以前文件中的内容
//new FileOutputStream(filePath),写入内容会覆盖原来的内容。
//new FileOutputStream(filePath,true)此方式创建对象,写入内容会追加到文件末尾
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
示例:文件复制,完成文件(图片/音乐)的拷贝
//完成文件拷贝
public class FileCopy {
public static void main(String[] args) {
//思路分析:
//1.创建文件的输入流,将文件读入到程序
//2.创建文件输出流,将读取到的文件数据,写入到指定的文件。
//完成程序时,应该是读取部分数据,就写入到指定文件中,采用循环的方式,若全部读完,文件过大,会超出内存容量
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
String srcfilePath = "D:\\Program Files\\Develop\\Java\\Java basic\\Java lesson\\java basic\\ludashi.jpg";
String destFilePath = "d:\\ludashi1.jpg";
try {
fileInputStream = new FileInputStream(srcfilePath);
fileOutputStream = new FileOutputStream(destFilePath);
//定义字节数组
byte[] buffer = new byte[1024];
int readLen = 0;
while ((readLen = fileInputStream.read(buffer))!=-1) {
//读取到后,就写入到文件,通过fileOutputStream
//即边读边写
//采用write(byte[] b)的方式,每次按照b的大小读,会读多余的空间到文件,造成图片等无法识别
fileOutputStream.write(buffer,0,readLen);//一定要使用这个方法
//fileOutputStream.write(buffer);
}
System.out.println("拷贝成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileOutputStream != null) {
fileOutputStream.close();
}
if(fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1.3 FileReader
**示例:**使用FileReader从study.txt读取内容,并显示
public class FileReaderDemo {
public static void main(String[] args) {
readFile02();
}
//使用read()单个字符逐一读取
public static void readFile01() {
String filePath = "d:\\study.txt";
//1.创建 FileReader对象
FileReader fileReader = null;
int data = 0;
try {
fileReader = new FileReader(filePath);
//1.read(),单个字符逐一读取
while ((data = fileReader.read()) != -1) {
System.out.print((char)data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//使用read(char[] buf)读取文件
public static void readFile02() {
String filePath = "d:\\study.txt";
//1.创建 FileReader对象
FileReader fileReader = null;
int readLen = 0;
char[] buf = new char[8];
try {
fileReader = new FileReader(filePath);
//read(buf),返回的是实际读取到的字符数,如返回-1,说明文件结束
//文件-->读8个字符 ---> buf --> 控制台输出
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf,0,readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.4 FileWriter
示例:将”好好学习,天天向上“写入到note.txt文件
public class FileWriterDemo {
public static void main(String[] args) {
String filePath = "d:\\note.txt";
FileWriter fileWriter = null;
char[] chars = {'a','b','d','d','d','f','d'};
String str = "!!!好好学习,天天向上";
try {
fileWriter = new FileWriter(filePath);//默认覆盖写出
//1.写入单个字符 write(int )
//fileWriter.write('H');
//2. write(char[] ) 写入指定数组
//fileWriter.write(chars);
//3. write(char[],off,len )写入指定数组的指定部分
//fileWriter.write(chars,0,chars.length);
//fileWriter.write("好好学习,天天向上".toCharArray(),0,4);
//4.write(string) 写入整个字符串
//fileWriter.write("!好好学习,天天向上");
//5.write(string, off,len) 写入字符串的指定部分
fileWriter.write(str,0,str.length());
System.out.println("写入成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileWriter != null) {
try {
fileWriter.close();//FileWriter,一定要关闭,或者刷新flush(),close()
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}