文件操作&IO流

JAVA文件操作&IO流

java文件操作

File类

File类是对文件和文件夹操作的一个类,它有以下几个功能:

  • 创建文件/文件夹
  • 删除文件/文件夹
  • 查找文件/文件夹(判断是否存在)
  • 获取文件/文件夹
  • 遍历文件夹
  • 获取文件大小
    由于不同操作系统的分隔符可能不同,所以File类有以下成员变量用于表示分隔符:
  • 默认名称分隔符:File.separatorr,即""
  • 默认路径分隔符:File.pathSeparator,即";"

File类的创建

File的构造方法有三种:
一个参数:其参数是文件的路径,创建File的对象,其参数表示的文件可以不存在;
两个参数:前者表示父路径,后者表示子路径,组合起来表示文件路径;
两个参数:前者表示父类文件,后者表示子类文件;
当我们直接打印File对象时,将会打印出file的路径,即传递的参数:

File file1 = new File("D:/IDEA/FileMode/1.txt");
System.out.println(file1);       //D:\IDEA\FileMode\1.txt

File file2 = new File("D:/IDEA/FileMode/""1.txt");
System.out.println(file2);       //D:\IDEA\FileMode\1.txt

File file3 = new File("D:/IDEA/FileMode/");
File file4 = new File(file1,"1.txt");
System.out.println(file4);       //D:\IDEA\FileMode\1.txt 

File类的方法

1.获取文件路径,名称,大小

  • String getPath(); //获取文件路径
  • String getName(); //获取文件名
  • long length(); //获取文件大小
File file = new File("D:/IDEA/FileMode/1.txt");
System.out.println(file.getAbsolutePath());           //D:\IDEA\FileMode\1.txt
System.out.println(file.getName());                  //1.txt
System.out.println(file.getAbsoluteFile());           //D:\IDEA\FileMode\1.txt
System.out.println(file.getPath());                    //D:\IDEA\FileMode\1.txt
System.out.println(file.length());                  //15

2.判断文件类型及是否存在

  • boolean exists(); //判断文件是否存在
  • boolean isFile(); //判断文件是否位文件
  • boolean isDirectory(); //判断文件是否为文件夹
File file = new File("D:/IDEA/FileMode/1.txt");
System.out.println(file.exists());              //true
System.out.println(file.isFile());              //true
System.out.println(file.isDirectory());         //false

3.创建,删除文件/文件夹(路径中的后缀无效,默认为名称)

  • boolean createNewFile(); //创建新文件
  • boolean delete(); //删除文件/文件夹
  • boolean mkdir(); //创建单级目录
  • boolean mkdirs(); //创建单级目录或多级目录
File file1 = new File("D:/javaTestFile/temp1.txt");
//创建文件
try{
    if(!file1.exists()) file1.createNewFile();
}catch (IOException e){
    System.out.println("文件创建失败");
}

//创建单级文件夹
File file2 = new File("D:/javaTestFile/temp2");
try {
    if(!file2.exists()) file2.mkdirs();
}catch (NullPointerException e) {
    System.out.println("创建目录失败");
}

//创建多级文件夹
File file3 = new File("D:/javaTestFile/temp3/temp3_1/temp3_2");
try {
    if(!file3.exists()) file3.mkdirs();
}catch (NullPointerException e) {
    System.out.println("创建目录失败");
}

//删除文件和文件夹
file1.delete();
file2.delete();

4.获取文件夹下所有文件及文件夹(路径必须为文件夹路径)

  • String[] list(); //获取文件夹下所有文件和文件夹,返回字符串数组
  • File[] listFiles(); //获取文件夹下所有文件和文件夹,返回文件数组
File file = new File("D:/javaTestFile");
String list[] = file.list();
for(String s : list){
	System.out.println(s);
}

File files[] = file.listFiles();
for(File f : files){
	System.out.println(f.getName());
}

遍历多级目录查找目标文件

使用递归遍历目录即可,下面的代码演示了查找javaTestFile目录下的所有txt文件

import java.io.File;

public class FileTest_3 {
    public static void main(String[] args) throws NullPointerException{
        File file = new File("D:/javaTestFile");
        searchFile(file);
    }
    public static void searchFile(File file){
        File lists[] = file.listFiles();
        for(File f : lists) {
            if (f.isDirectory()) {
                searchFile(f);
            }
            if (f.getName().endsWith("txt")) {
                System.out.println(f.getPath());
            }
        }
    }
}

FileFilter——文件过滤器

FileFilter,即文件过滤器,是java库中的一个接口,用于筛选文件,文件过滤器使用原理如下图所示:

使用方法为:
  • 创建子类实现FileFilter,重写accept方法定义过滤规则,然后将子类对象传递进listFile(FileFilterImpl ff)方法的参数中,示例如下:
    1.实现FileFilter,重写accept的规则为查找txt文件
import java.io.FileFilter;
import java.io.File;

public class FileFilterImpl implements FileFilter {

    @Override
    public boolean accept(File f) {
        return f.isDirectory() || f.getName().endsWith("txt");
    }
}

2.创建过滤器过滤文件

import java.io.File;
import java.io.FilenameFilter;

public class FileTest_3 {
    public static void main(String[] args) throws NullPointerException{
        File file = new File("D:/javaTestFile");
        searchFile(file);
    }

    public static void searchFile(File file){
        File lists[] = file.listFiles(new FileFilterImpl());
        for(File f : lists) {
            if (f.isDirectory()) {
                searchFile(f);
            }
            if (f.getName().endsWith("txt")) {
                System.out.println(f.getPath());
            }
        }
    }
}

  • 或者使用匿名内部类,下面以FileNameFilter,另一个文件过滤器(效果同FileFilter)示例:
import java.io.File;
import java.io.FilenameFilter;

public class FileTest_3 {
    public static void main(String[] args) throws NullPointerException{
        File file = new File("D:/javaTestFile");
        searchFile(file);
    }

    public static void searchFile(File file){
       File lists[] = file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir,name).isDirectory() || name.endsWith("txt");
            }
        });
        for(File f : lists) {
            if (f.isDirectory()) {
                searchFile(f);
            }
            if (f.getName().endsWith("txt")) {
                System.out.println(f.getPath());
            }
        }
    }
}

RandomAccessFile——随机读写文件

RandomAccessFile即可以读取文件内容,也可以向文件中写入内容,它包含了一个记录指针,用以标记当前读写处的位置,它的每次操作都是在指针所在处,所以它可以直接跳到文件的任意位置来读写数据。

RandomAccessFile的创建

 RandomAccessFile的构造方法有两个参数,第一个是文件,第二个是权限管理:“r” 只读;“rw” 可读可写;“rws” 可读可写,并要求对文件内容或元数据的每个更新都同步写入到底层设备;“rwd” 可读可写,并要求对文件内容每个更新都同步写入到底层设备。

File file = new File(filePath);
RandomAccessFile raf = new RandomAccessFile(file,"rw");   //可读可写

RandomAccessFile的方法及注意事项

RandomAccessFile常用的方法如下:

  • RandomAccessFile的read()和write()方法,同其他文件操作类
  • long getFilePointer(); //返回文件记录指针的当前位置
  • void seek(long pos); //将文件记录指针定位到pos位置
    注意事项:
  • 在seek方法中指针是从0~n-1的,所以当指针指向length,读取的值是-1
  • 用了RandomAccessFile的read方法后,指针会往后移动一个字符,而readline后会移动到下一行的开头,也就是再read就是下一行的开头第一字符。

RandomAccessFile实现在任意位置写文件和读文件

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RamdomAccessFileTest {
    public static void main(String[] args) {
        //创建readme.txt
        File file = new File("D:/javaTestFile/Readme.txt");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            //创建RamdomAccess对象
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            //写第一行和第二行
            String line1 = "line1";
            String line2 = "line2";
            raf.write(line1.getBytes());
            raf.write("\n".getBytes());
            raf.write(line2.getBytes());
            //将指针移至第二行开始处
            int pos = 0;
            while(pos++ < raf.length()){
                raf.seek(pos);
                if(raf.read() == '\n') break;
                pos++;
            }
            raf.seek(++pos);
            //读第二行内容
            String l2 = raf.readLine().toString();
            System.out.println(l2);
            //指针移至文件末尾
            String line3 = "line3";
            raf.seek(raf.length());
            //追加内容写第三行
            raf.write("\n".getBytes());
            raf.write(line3.getBytes());
            raf.close();
        }catch (IOException e){
            System.out.println("读写异常");
        }
    }
}

IO流

IO流,即输入输出流,表示数据在内存和硬盘之间的传输,Input输入流就是从硬盘读取数据到内存,output输出流就是从内存将数据存储到硬盘中

  • 输入流:即读取源中的数据,输出流:传送数据到目的地
- 字节输入流:InputStream抽象类的子类创建的流对象 InputStream类提供的read方法以字节为单位顺序地读取源中的数据,直到源的末尾或输入流被关闭 - 字节输出流:OutputStream抽象类的子类创建的流对象 OutputStream的write方法以字节为单位顺序地写文件,直到流被关闭 - 字符输入流:Reader抽象类的子类创建的流对象 - 字符输出流:Writer抽象类的子类创建的流对象

OutputStream字节输出流

OutputStream是所有输出流的超类,有以下方法供所有输出流使用:

  • void close(); //关闭流
  • void flush(); //刷新流,写出所有缓冲字节
  • void write(byte b[]); //以字节数组写入
  • void write(byte b[],int offset,int len); //写入b[offset]~b[len]的字节
  • void write(int b) //写入字节b

FileOutputStream——文件字节输出流

FileOutputStream是文件字节输出流,用于把内存数据写入到硬盘中

FileOutputStream的创建

FileOutputStream有构造方法有3种形式,都需要抛出FileNotFoundException:

  1. FileOutputStream(File file); //创建文件输出流以写入由指定的 File对象表示的文件。
  2. FileOutputStream(String name); //创建文件输出流以路径写入文件。
  3. FileOutputStream(File file,boolean append); //同上,第二个参数有true和false两种形式,若为true,则表示将字节将写入文件的末尾而不是开头,为false则表示写入文件开头,即覆盖原内容
package IOlearining;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class FileOutputStreamTest {
    public static void main(String[] args) {
        File file1 = new File("D:/javaTestFile/1.txt");
        try {
            FileOutputStream fos1 = new FileOutputStream(file1);
            FileOutputStream fos2 = new FileOutputStream("D:/javaTestFile/2.txt");
            FileOutputStream fos3 = new FileOutputStream("D:/javaTestFile/3.txt",true);
        }catch (FileNotFoundException e){
            System.out.println("文件未找到");
        }
    }

}

FileOutputStream的使用

  • 写数据,write方法演示:
File file = new File("D:/javaTestFile/1.txt");
    try{
        FileOutputStream fos =new FileOutputStream(file,false);
        fos.write(46);                      //ASCII编码,46对应“."
		fos.write("\n".getBytes());           //换行  
        fos.write("abc".getBytes());           //写入abc
 		fos.write("\n".getBytes());          //换行
        fos.write("defg".getBytes(),1,2);         //写入ef
        fos.close();
    }catch (FileNotFoundException e){
        System.out.println("文件未找到");
    }catch (IOException e){
        System.out.println("写文件异常");
    }
  • 注意FileOutputStream是字节流,将文本按字节写入文件,而一个汉字是两个字节,无法一次写入,直接写入中文就会出现乱码,可以使用OutputStreamWriter将字节流转换为字符流写入:
FileOutputStream fos =new FileOutputStream(file,false);
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
osw.append("中文输入");            //写入成功,没有乱码
osw.close();

ByteArrayOutputStream——字节数组输出流

ByteArrayOutputStream在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中,写入到文件等其他outputStream

ByteArrayOutputStream的创建

ByteArrayOutputStream有2个构造方法:

  • ByteArrayOutputStream bops = new ByteArrayOutputStream(); //无参数默认缓冲大小为32
  • ByteArrayOutputStream bops = new ByteArrayOutputStream(int size); //设置缓冲大小为size

ByteArrayOutputStream的使用

ByteArrayOutputStream的方法如下:

  • 3个继承于OutputStream的write方法,使用相同
  • writeTo(OutputStream os); //将此字节数组输出流的全部内容写入到指定的输出流参数中。
  • toString(); //将缓冲区的内容转换为字符串
  • toByteArray(); //复制输出流的字节数组内容
  • size(); //返回缓冲区大小
  • reset(); //重置字节输出流,清除存储的数据

示例:获取字符串,将除空格以外的数据写入流中并输出:

package Test_02;
import java.io.*;

public class SkipWhiteSpaceOutputStream extends ByteArrayOutputStream{
    void putSkipWhitespaceString(String str){
            byte b[] = str.getBytes();
            ByteArrayOutputStream bops = new ByteArrayOutputStream(100);
            for(int i = 0 ; i < b.length ; i++){
                    if((char)b[i] != ' ') bops.write(b[i]);
            }
            String out = bops.toString();
            System.out.println(out);
    }

	public static void main(String[] args) throws IOException {
        String str;
        Scanner sc = new Scanner(System.in);
        str = sc.nextLine();
        SkipWhiteSpaceOutputStream swops = new SkipWhiteSpaceOutputStream();
        swops.putSkipWhitespaceString(str);
    }
}

测试结果:

BufferedOutputStream——字节缓冲输出流

BufferedOutputStream字节缓冲输出流,使用缓存流将数据写入文件,使用BufferedOutputStream的好处就是能够提高效率:

BufferedOutputStream的构造

BufferedOutputStream有2种构造方法:

  • BufferedOutputStream(OutputStream os); //构造一个字节缓冲输出流对象
  • BufferedOutputStream(OutputStream os,int size); //指定size缓冲区大小构造缓冲输出流对象

BufferedOutputStream的使用

package IOlearining;

import java.io.*;

public class BufferdTest {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        FileOutputStream fos = new FileOutputStream("D:/javaTestFile/1.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write(97);
        bos.close();
    }
}

Inputstream字节输入流

InputStream是所有输入流的超类,有以下方法供所有输入流使用:

  • void close(); //关闭流
  • void read(); //读取数据的下一个字节
  • void read(byte b[]); //读取数据,大小为b的大小

FileInputStream——文件输入流

FileInputStream类是文件输入流,从文件中读取字节。

FileInputStream的构建

类似于FileOutputStream,FileInputStream也有2种构造方法,且需要抛出FileNotFoundException异常:

  • FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的file命名。
  • FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名命名。

FileInputStream的使用

  • 读取字节数据read()方法,需要抛出IOException异常:
package IOlearining;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest {
    public static void main(String[] args) throws IOException,FileNotFoundException {
        File file = new File("D:/javaTestFile/1.txt");
        FileInputStream fis = new FileInputStream(file);
        int i;
        while((i=fis.read())!=-1){
            System.out.print((char)i);
        }
		fis.close();
    }
}
  • read(byte[] b)方法,需要抛出IOException异常,注意需要注意有效位,因为是将数据传入byte数组并覆盖,若数据位数不足,会导致byte数组没有被替换完全,如下所示:
package IOlearining;

import java.io.*;

public class FileInputStreamTest {
    public static void main(String[] args) throws IOException{
        FileInputStream fis = new FileInputStream("D:/javaTestFile/1.txt"); // 文件中为abcde
        int len ;
        byte[] b = new byte[2];
        while ((len= fis.read(b))!=-1) {
			System.out.println(new String(b));   //错误,最后一次会输出de,因为最后一次只有1个数据,所以byte数组中的数据d没有被替换
            System.out.println(new String(b,0,len));   //  正确写法,len 每次读取的有效字节个数
        }
        fis.close();
    }
}

  • 同样的,FileInputStream的read方法只能读取一个字节,不能读取汉字,否则会乱码,可以使用InputStreamWriter将字节流转换为字符流写入:
package IOlearining;

import java.io.*;

public class FileInputStreamTest {
    public static void main(String[] args) throws IOException,FileNotFoundException {
        File file = new File("D:/javaTestFile/1.txt");
        FileInputStream fis = new FileInputStream(file);
        int i;
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        while((i=isr.read())!=-1){
            System.out.print((char)i);
        }
        isr.close();
        fis.close();
    }
}

直接采用文件输入输出流复制文件

package IOlearining;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyTest {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\zycjj\\Pictures\\1.jpg");
        FileOutputStream fos = new FileOutputStream("D:/javaTestFile/1.jpg");
        byte b[] = new byte[1024];
        int len;
        while((len=fis.read())!=-1){
            fos.write(b,0,len);
        }
        fis.close();
        fos.close();
    }
}

字符流

字符流不同于字节流的地方就是,流中的数据是以字符形式传递,所以流数据是中文也不会乱码

Reader——字符输入流

Reader是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法:

  • void close(); ///关闭此流并释放与此流相关联的任何系统资源。
  • int read(); //从输入流读取一个字符。
  • int read(char[] c); //从输入流中读取一些字符,并将它们存储到字符数组中 。
    字符输入流Reader的使用完全类似于字节输入流,如下:
public class ReaderTest {
    public static void main(String[] args) throws IOException {
       	FileReader fr = new FileReader("D:/javaTestFile/1.txt");
        int len ;
        char[] c= new char[2];
        while ((len = fr.read(c))!=-1) {
            System.out.println(new String(c,0,len));
        }
        fr.close();
    }
}

Writer——字符输出流

Writer是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法:

  • void write(int c) // 写入单个字符。
  • void write(char[] c) //写入字符数组。
  • void write(char[] c, int off, int len) //写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
  • void write(String str) //写入字符串。
  • void write(String str, int off, int len) //写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
  • void flush() //刷新该流的缓冲。
  • void close() //关闭此流,但要先刷新它。
package IOlearining;

import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterTest {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        FileWriter fw =new FileWriter("D:/javaTestFile/1.txt");
        fw.write("字符串");       //写字符串
        fw.write("\n");           //写字符串
        fw.write('c');           //写字符
        fw.write('\n');          //写字符
        fw.write(97);            //写字节
		char c[] = "字符数组".toCharArray();
        fw.write(c);                //写字符数组
        fw.close();            
    }
}

采用缓存输入输出流,使用Writer和reader复制文件

package Test_03;

import java.io.*;

public class FileTest {
    public static void main(String[] args) {
        //获取目录下的所有文件
        File file = new File("D:/javaTestFile");
        File files[] = file.listFiles();
        try {
            //创建新文件夹
            File newDir = new File("D:/tmp");
            if (!newDir.exists()) {
            newDir.mkdir();
        }
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile() && files[i].getName().endsWith("txt")) {  //筛选txt文件
                System.out.println(files[i].getName());
                //复制txt文件
                File objFile = new File("D:/tmp",files[i].getName());
                if(!objFile.exists()) {
                    objFile.createNewFile();
                }
                //读取源文件内容
                Reader fr = new FileReader(files[i]);
                BufferedReader br = new BufferedReader(fr);
                String str;

                //复制源文件内容
                FileWriter fw = new FileWriter(objFile);
                BufferedWriter bw = new BufferedWriter(fw);
                while ((str = br.readLine()) != null){
                    try {
                        bw.write(str);
                        bw.newLine();
                    }catch (IOException e){
                        System.out.println("写文件失败");
                    }
                }
                bw.close();
            }
        }
      }catch (FileNotFoundException e) {
            System.out.println("文件未找到");
        }catch (IOException e){
            System.out.println("读写错误");
        }
    }
}

Properties类

Properties类,主要用于配置读取Java的配置文,原理类似于Map,是以键值对的形式进行参数配置的。
它有几个常用方法:

  • getProperty ( String key) //用指定的键在此属性列表中搜索属性
  • list(PrintStream out) //将此属性列表打印到指定的输出流
  • load ( InputStream inStream) //从输入流中读取属性列表(键和元素对)
  • setProperty ( String key, String value) //同put方法
  • store ( OutputStream out, String comments) //将此 Properties 表中的属性列表(键和元素对)写入输出流
  • Set stringPropertyNames() ` :所有键的名称的集合。
  • void clear () // 清除所有装载的 键 - 值对。
package IOlearining;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class ProportyTest {
    public static void main(String[] args) throws IOException {
        File file = new File("D:/javaTestFile/1.proporties");
        //配置
        Properties pro = new Properties();
        pro.setProperty("font-size","15px");
        pro.setProperty("font-color","black");
        System.out.println(pro.getProperty("font-size"));        //15px
        System.out.println(pro.getProperty("font-color"));       //black
        Set<String> setPro = pro.stringPropertyNames();
        for(String key : setPro){
            System.out.println(key + " : " + pro.getProperty(key));
			//依次输出:font-color : black      font-size : 15px
        }
        //将配置存储到文件中
        pro.store(new FileOutputStream(file),"文件注释");
		pro.clear();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值