一、IO的主要内容
- io(input、output)
二、File类
- 只能操作文件本身,但不能操作文件内容。
- 以上所示方法实现如下代码,以上方法的作用在代码注解中。
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
File file =new File("K:\\test\\filetest.txt");//这个时候file就是filetest.txt文件
File file2 =new File("K:/test/filetest.txt");
File file3 = new File("K:"+File.separator+"test/filetest.txt");
File file4 = new File("src/Test.java");
// File file1 = new File( "K:","test\\filetest.txt");//这个file1也是filetest.txt文件,这种使用较少。
//注意,\在文件中是路径分隔符,但是早java编程中一个\的意思是转义符,在java中\\或者/才是文件的分隔符
//也可以使用File.separator
System.out.println(file.getName()); //获取文件或者文件名或者当前文件夹名称
System.out.println(file4.getPath()); // 获取文件或者文件夹的路径
System.out.println(file4.getAbsolutePath());//获取当前文件的绝对路径
System.out.println(file4);
System.out.println(file4.getAbsoluteFile());//返回一个用绝对路径构建的file对象
System.out.println(file4.getParent());//返回当前文件夹的父级路径
// file.renameTo(new File("K:\\test\\filetest1.txt"));//给文件或文件夹重命名
System.out.println(file.exists()); // 判断文件或者文件夹是否存在
System.out.println(file.canRead());//是否可读
System.out.println(file.canRead());//是否可写
System.out.println( file.isFile());//判断当前的file对象是不是文件
System.out.println(file.isDirectory());//判断当前的file对象是不是文件目录
System.out.println(file.lastModified());//获取当前文件最后的修改时间,返回时一个毫秒数
System.out.println(file.length() ); // 返回当前文件的长度,单位时字节数
File file6 = new File("K:/test/ft1.txt");
if (!file6.exists()){
try {
file6.createNewFile(); //创建一个没有的文件
} catch (IOException e) {
e.printStackTrace();
}
}
file6.delete();//删除文件
File file7 = new File("K:/test/test");
file7.mkdir();//创建单层目录,如果使用这一方法来创建多层目录,就得一层一层的只从mkdir()
File file8 = new File("K:/test/lbw/nb/nb" );
file8.mkdirs(); // 这个方法是直接用来创建多层目录
System.out.println("-------------"+"file.list"+"------------");
File file9 = new File("K:/test"); // 返回的是当前文件夹的子集的名称,包括目录和文件
String[] f9 = file9.list();
for (String s :f9){
System.out.println(s);
}
System.out.println("-------------"+"file.listFile"+"------------");
File file10 = new File("K:/test");
File[] f10 = file10.listFiles();// 返回的是当前文件夹的子集的file对象,包括目录和文件夹
for (File s :f10){
System.out.println(s);
}
}
}
输出:
三、流的分类
- 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为:输入流,输出流
- 按流的角色的不同分为:节点流,处理流
四、文件字节流
输入和输出常常让人搞混,其实可以这样理解,将JVM作为主体,而不是被操作的文件。这样JVM->文件即为写出,文件->JVM写入。
- 文件的字节输入流使用FileInputStream对象和其read()方法。
/**
* 文件字节输入流FileInputStream
* 。
* 在读取文件时,必须保证该文件已存在,否则出异常
*/
public static void testFileInputStream(){
try {
FileInputStream in = new FileInputStream("D:/test/abc/tt1.txt");
byte[] b = new byte[10];//设置一个byte数组接收读取的文件的内容
int len = 0;//设置一个读取数据的长度
// in.read(b);//in.read方法有一个返回值,返回值是读取的数据的长度,如果读取到最后一个数据,还会向后读一个,这个时候返回值就是-1
//也就意味着当in.read的返回值是-1的时候整个文件就读取完毕了
while((len = in.read(b)) != -1){
System.out.println(new String(b,0,len));
//new String(b,0,len),参数1是缓冲数据的数组,参数2是从数组的那个位置开始转化字符串,参数3是总共转化几个字节
}
in.close();//注意。流在使用完毕之后一段要关闭
} catch (Exception e) {
e.printStackTrace();
}
}
- 文件的字节输出流使用FileOutputStream对象和其wirte方法。
为什么循环in.read(b)?
原因:每次从in对象中读取 b对象的字节长度 的字节流,循环多次进行in->b->控制台或者内存。若是in对象存的字节长度小于b对象字节长度,则一次性多玩。in.read()还有数据未写到b中,则返回此次对出的字节长度,否则返回0.
为什么还要调用flush方法呢?
原因:数据先传入缓冲区 塞满后一块传到硬盘 重复多次 若最后一组数据没塞满缓冲区 则会残留 此时close就会丢失其中的数据 所以要先flush手动传输一次数据 清空缓冲区
```java
/**
* 文件字节输出流FileOutputStream
* 在写入一个文件时,如果目录下有同名文件将被覆盖
*/
public static void testFileOutputStream(){
try {
FileOutputStream out = new FileOutputStream("D:/test/abc/tt4.txt");//指定行tt4输出数据
String str = "knsasjadkajsdkjsa";
out.write(str.getBytes());//把数据写到内存
out.flush();//把内存中的数据刷写到硬盘
out.close();//关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
- 字节流复制文件
由此实验可以知道FileOutputStream若是没有该文件,则创建该文件。
/**
* 复制文件到指定位置
* @param inPath 源文件路径
* @param outPanth 复制到的文件夹位置
*/
public static void copyFile(String inPath, String outPanth){
try {
FileInputStream in = new FileInputStream(inPath);//读取的源文件
FileOutputStream out = new FileOutputStream(outPanth);//复制到哪里
byte[] b = new byte[100];
int len = 0;
while((len = in.read(b)) != -1){
out.write(b, 0, len);//参数1是写的缓冲数组,参数2是从数组的那个位置开始,参数3是获取的数组的总长度
}
out.flush();//把写到内存的数据刷到硬盘
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
- 注意:文件字节流非常通用,可以用来操作字符的文档,还可以操作任何的其他类型文件(图片、音乐、压缩包等等),引用字节流直接使用二进制。
五、文件字符流
- 文件的字符输入流使用FileReader对象和其read()方法。
/**
* 文件字符输入流FileReader
* 在读取文件时,必须保证该文件已存在,否则出异常
* @param inPath
*/
public static void testFileReader(String inPath){
try {
FileReader fr = new FileReader(inPath);//创建文件字符输入流的对象
char[] c = new char[10];//创建临时存数据的字符数组
int len = 0;//定义一个输入流的读取长度
while((len = fr.read(c)) != -1){
System.out.println(new String(c, 0, len));
}
fr.close();//关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
- 文件的字符输入流使用FileWriter对象和其write()方法。
/**
* 文件字符输出流FileWriter
* 在写入一个文件时,如果目录下有同名文件将被覆盖
* @param text 输出的内容
* @param outPath 输出的文件
*/
public static void testFileWriter(String text,String outPath){
try {
FileWriter fw = new FileWriter(outPath);
fw.write(text);//写到内存中
fw.flush();//把内存的数据刷到硬盘
fw.close();//关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 字符流完成拷贝文件,字符流只适合操作内容是字符文件
* @param inPaht
* @param outPath
*/
public static void copyFile(String inPaht, String outPath){
try {
FileReader fr = new FileReader(inPaht);
FileWriter fw = new FileWriter(outPath);
char[] c = new char[100];
int len = 0;
while((len = fr.read(c)) != -1){//读取数据
fw.write(c,0,len);//写数据到内存
}
fw.flush();
fw.close();
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
六、注意
在写入一个文件时,如果目录下有同名文件将被覆盖。
在读取文件时,必须保证该文件已存在,否则出异常。