文件操作

文件属性

// 创建文件对象
File(String filename);
File(String directoryPath, String filename);
File(File dir,String filename);

//获取文件属性
public String getName(); //获取文件名字
public boolean canRead(); //判断文件是否可读
public boolean canWrite(); //判断文件是否可写
public boolean exists(); //文件是否存在
public long length(); //获取文件长度(单位是字节)
public String getAbsolutePath(); //获取文件的绝对路径
public String getParent(); //获取文件的父目录
public boolean isFile(); //判断是否是文件而不是目录
public boolean isDirectory(); //判断是否是目录而不是文件
public boolean isHidden(); //判断文件是否是隐藏文件
public long lastModified(); //获取文件最后修改时间

目录操作

//File对象是一个目录,则有以下方法
public boolean mkdir();//创建一个目录,存在或创建失败返回false,创建成功返回true
public String[] list(); //用字符串的形式返回目录下全部文件
public File[] listFile(); //用File对象返回目录下全部文件
public String[] list(FilenameFilter obj);//返回字符串形式目录下的指定类型的所有文件
public Flie[] listFile(FilenameFilter obj);//返回File类型形式目录下的指定类型的所有文件
public boolean accept (File dir,String name);//是FilenameFilter接口的方法,可通过重写来筛选出上面两个方法的一些特殊文件。

文件的创建和删除

File file = new File(String dir,String Filename);
public boolean creatnewFile();//创建成功返回true
public boolean delet();//删除成功返回true

运行可执行文件

Runtime ec = Runtime.getRuntime();
ec.exec(String command);//可以打开机器上的可执行文件或执行一个操作

文件输入、输出

文件字节输入流

FileInputStream(String name);
FileInputStream(File file);
 int read();
 int read(byte b[]);//把读取的字符存到数组b中
 int read(byte b[],int off,int len);//off表示开始读取的位置,len表示读取len个字节
 close()//关闭流

文件字节输出流

FileInputStream(String name);
FileInputStream(File file);
int read();
int read(byte b[]);//把读取的字符存到数组b中
int read(byte b[],int off,int len);//off表示开始读取的位置,len表示读取len个字节
close()//关闭流

文件字节输入流

FileOutputStream(String name,boolean append);
FileOutputStream(File file,boolean append);
//append 表示是否再文件原有内容的基础上添加,true添加,false删除源文件内容
void write(int n);
void write(byte b[]);
void write(byte b[],int off,int len);
void close();

文件字符输入、输出流

FileReader(同上)
FileWriter(同上)
flush()//用于冲刷缓存区,把内容输出

字符与字节流的区别在于他们的传输单位,一个中文是两个字节所以会有较大区别

缓冲流

BufferedReader(Read in)
BufferedWriter(Writer out)
readLine()//没有内容会返回null
newLine()//可以输入空行
write(String str)//可以输出内容

随机流

该类的实例支持读取和写入随机访问文件。 随机访问文件的行为类似于存储在文件系统中的大量字节。 有一种游标,或索引到隐含的数组,称为文件指针 ; 输入操作读取从文件指针开始的字节,并使文件指针超过读取的字节。 如果在读/写模式下创建随机访问文件,则输出操作也可用; 输出操作从文件指针开始写入字节,并将文件指针提前到写入的字节。 写入隐式数组的当前端的输出操作会导致扩展数组。 文件指针可以通过读取getFilePointer方法和由设置seek方法

  通俗来讲:我们以前讲的 IO 字节流,包装流等都是按照文件内容的顺序来读取和写入的。而这个随机访问文件流我们可以再文件的任意地方写入数据,也可以读取任意地方的字节。

//对文件只读
RandomAccessFile r = new RandomAccessFile(filePath,"r");
//对文件即可读又可写,但是一旦确定了读或者写,那么就不能在变
RandomAccessFile rw = new RandomAccessFile(filePath,"rw");

数组流

ByteArrayInputStream(byte[] buf);
ByteArrayInputStream(byte[] buf,int offset,int length);
ByteArrayOutputStream();
ByteArrayOutputStream(int size);

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;

public class Example10_10 {
    public static void main(String[] args) {
        try {
            ByteArrayOutputStream outByte = new ByteArrayOutputStream();
            byte[] byteContent = "mid-autumn festival ".getBytes();
            outByte.write(byteContent);
            System.out.println(outByte);
            ByteArrayInputStream inByte = new ByteArrayInputStream(outByte.toByteArray());
            byte[] backByte = new byte[outByte.toByteArray().length];
            inByte.read(backByte);
            System.out.println(new String(backByte));
            CharArrayWriter outChar = new CharArrayWriter();
            char[] charContent = "中秋快乐".toCharArray();
            outChar.write(charContent);
            CharArrayReader inChar = new CharArrayReader(outChar.toCharArray());
            char backChar [] = new char[outChar.toCharArray().length];
            inChar.read(backChar);
            System.out.println(backChar);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这部分需要注意的点是string,byte,char数据类型之间的相互转化,以及转化中的编码格式,参考资料:https://blog.csdn.net/JackComeOn/article/details/85381788#bytechar_1

对象流

对象的输入输出流的作用: 用于写入对象 的信息和读取对象的信息。 使得对象持久化。

ObjectInputStream : 对象输入流

ObjectOutPutStream :对象输出流

参考样例

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

//创建要写入磁盘的类,这个类需要实现接口 Serializable(可系列化的)
class Student implements Serializable{
    
    // 在这里保证了serialVersionUID 的唯一性,防止属性变量的临时改变,从而造成写入id与读取id不同
    private static final long serialVersionUID = 1L; 
    int id ; //额外需要添加一个属性
    
    String name ;
    transient String sex; //transient修饰属性,表示暂时的,则这个属性不会被写入磁盘
    transient int age;
    
    public Student(String name,String sex,int age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
}


public class objectIO {

    /**
     * @param args
     * @throws IOException 
     * @throws ClassNotFoundException 
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // TODO Auto-generated method stub

        createObj();
        readObj();
    }
    
    //(一)先写入对象
    public static void createObj() throws IOException {
        //1.创建目标路径
        File file = new File("C:\\Users\\bg\\Desktop\\objTest.txt");
        //2.创建流通道
        FileOutputStream fos = new FileOutputStream(file);
        //3.创建对象输出流
        ObjectOutputStream objOP = new ObjectOutputStream(fos);
        //4.创建类对象,并初始化
        Student stu = new Student("玛丽苏", "男", 18);
        //5.向目标路径文件写入对象
        objOP.writeObject(stu);
        //6.关闭资源
        objOP.close();
    }
    
    //再读取对象
    public static void readObj() throws IOException, ClassNotFoundException {
        File file = new File("C:\\Users\\bg\\Desktop\\objTest.txt");
        FileInputStream fis = new FileInputStream(file);
        ObjectInputStream objIP = new ObjectInputStream(fis);
        //读取对象数据,需要将对象流强制转换为 要写入对象的类型
        Student stu = (Student)objIP.readObject();
        System.out.println("\n name:"+stu.name+"\n sex:"+stu.sex+"\n age:"+stu.age);
        objIP.close();  
    }
}

输出:

 name:玛丽苏
 sex:null       //后面的这连个属性使用了 transient修饰   
 age:0

序列化与对象克隆(其实就是对象流)

序列化与反序列化就是用来操作对象的,可以把对象存入文件中。
其实就是上面的对象流

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Example10_14 {
    public static void main(String[] args) {
        MyWin win = new MyWin();
    }
}

class MyWin extends JFrame implements ActionListener{
    JLabel label = null;
    JButton read=null,write=null;
    int num=0;
    ByteArrayOutputStream out = null;
    MyWin()
    {
        setLayout(new FlowLayout());
        label=new JLabel("HOW ARE YOU");
        read=new JButton("读如对象");
        write=new JButton("写入对象");
        read.addActionListener(this);
        write.addActionListener(this);
        setVisible(true);
        add(label);
        add(read);
        add(write);
        setSize(500,400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        validate();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==write){
            try{
                out=new ByteArrayOutputStream();
                ObjectOutputStream objectOutputStream=new ObjectOutputStream(out);
                objectOutputStream.writeObject(label);
                num++;
                objectOutputStream.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        else if (e.getSource()==read)
        {
            try{
                ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(out.toByteArray());
                ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
                JLabel temp = (JLabel)objectInputStream.readObject();
                temp.setText(String.valueOf(num));
                this.add(temp);
                this.validate();
                objectInputStream.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

使用 Scanner 解析文件

把内容先存入内存后再用常用类来解析所需要的内容,优点在于处理速度快,但如果读入的内容较大将消耗较多的内存,即以空间换取时间。
而使用Scanner类和正则表达式来解析内容的特点在于用时间换空间,即:解析速度慢,占用空间少
a.txt的内容:

123 4 5 6
123
13
456

样例:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Scanner解析文件 {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File("a.txt"));
        while(in.hasNext())
        {
            System.out.println(in.next());
        }
    }
}

输出:

    123
    4
    5
    6
    123
    13
    456

只用Scanner类可以以空格为间隔解析文件,hasnext()判断是(true)否(false)还有内容

配合正则表达式

File file = new File("a.txt");
Scanner sc = new Scanner(file);
sc.useDelimiter(正则表达式);

样例:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Example10_16 {
    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("a.txt");
        Scanner sc = new Scanner(file);
        sc.useDelimiter("[^0123456789.]+");
        try {
            double score=0;
            int n=0;
            while (sc.hasNextDouble())
            {
                score+=sc.nextDouble();
                n++;
            }
            System.out.print("平均分");
            System.out.println(score/n);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

a.txt:

张三37分,李四56分,小明72分,哈哈

输出

平均分55.0

文件对话框

showSaveDialog(Component a);
showOpenDialog(Component a);
JFileChooser.APPROVE_OPTION;
JFileChooser.CANCEL_OPTION;
文章作者: Hao.Jia
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hao.Jia's Blog
Java 学习笔记
喜欢就支持一下吧