栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java学习】文件操作和IO流

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java学习】文件操作和IO流

目录

一、charset字符集

1.字符的字节数

2.使用的Api

二、File类

1.构造方法

2.常用Api

3.递归 

三、IO流

1.概述

2.IO的分类 

3.字节流 

(1)字节输出流【OutputStream】

 (2)字节输⼊流【InputStream】

4.字符流

(1)字符输⼊流【Reader】 

(2)字符输出流【Writer】 

5.对象流 

(1)作用

(2)用法

6.小结


一、charset字符集

1.字符的字节数

字符集: 支持中文 GBK  UTF-8

   英文和数字, 在所有的字符集中都可以正常显示, 只有一个字节

   中文: UTF-8 1个字符 = 3个字节

        GBK 1个字符 = 2个字节 

java中的字符char: 2个字节   unicode编码

2.使用的Api

解码的api: new String(byte[] bs, String charsetName)

编码的api: byte[] getBytes(String charsetName)

乱码问题:
   使用不同的方式来编码和解码
解决乱码:
   原路返回

例:

public class demo1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str="java自己能大";
        byte[] by=str.getBytes("UTF-8");
        System.out.println(Arrays.toString(by));

        String bystr1=new String(by,"ISO-8859-1");
        System.out.println(bystr1);

        by=bystr1.getBytes("ISO-8859-1");
        System.out.println(Arrays.toString(by));
        bystr1=new String(by,"UTF-8");
        System.out.println(bystr1);
    }
}

二、File类

1.构造方法

public File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File 实例。

public File(String parent, String child) :从⽗路径名字符串和⼦路径名字符串创建新的 File 实例。

public File(File parent, String child) :从⽗抽象路径名和⼦路径名字符串创建新的 File 实例。

2.常用Api

public String getAbsolutePath() :返回此File的绝对路径名字符串。

public String getPath() :将此File转换为路径名字符串。

public String getName() :返回由此File表示的⽂件或⽬录的名称。

public long length() :返回由此File表示的⽂件的⻓度。

public boolean exists() :此File表示的⽂件或⽬录是否实际存在。

public boolean isDirectory() :此File表示的是否为⽬录。

public boolean isFile() :此File表示的是否为⽂件。

File file=new File("file/s.txt");

System.out.println("⽂件绝对路径:" + file.getAbsolutePath());
System.out.println("⽂件构造路径:" + file.getPath());
System.out.println("⽂件名称:" + file.getName());
System.out.println("⽂件⻓度:" + file.length() + "字节");

System.out.println("文件是否存在:"+file.exists());
System.out.println("是否是文件:"+file.isFile());
System.out.println("是否是目录:"+file.isDirectory());

public boolean createNewFile() :当且仅当具有该名称的⽂件尚不存在时,创建⼀个新的空⽂

件。

public boolean mkdir() :创建由此File表示的⽬录。

public boolean mkdirs() :创建由此File表示的⽬录,包括任何必需但不存在的⽗⽬录。

boolean mkdir = m.mkdir();//创建单级目录
boolean mkdir2 = m2.mkdirs();//创建多级目录
System.out.println("创建目录:"+mkdir+mkdir2);
if(!exist){
    Boolean creat=file.createNewFile();
    System.out.println("创建文件:"+creat);
}

public boolean delete() :删除由此File表示的⽂件或⽬录。

public String[] list() :返回⼀个String数组,表示该File⽬录中的所有⼦⽂件或⽬录。

public File[] listFiles() :返回⼀个File数组,表示该File⽬录中的所有的⼦⽂件或⽬录。

File file=new File("day02/file/aa/bb");
File[] files = file.listFiles();
for(File f:files){
    f.delete();
}
file.delete();

筛选指定后缀文件: 

File file=new File("day02/file/aa");
File[] files = file.listFiles(new FileFilter() {
    @Override
    public boolean accept(File file) {
        boolean file1 = file.isFile();
        boolean java = file.getName().endsWith(".txt");
        return file1 && java;
    }
});
for(File f:files){
    System.out.println(f.getName());
}

API中说明:

1.delete⽅法,如果此File表示⽬录,则⽬录必须为空才能删除。

2.调⽤listFiles⽅法的File对象,表示的必须是实际存在的⽬录,否则返回null,⽆法进⾏遍历

3.递归 

递归:指在当前⽅法内调⽤⾃⼰的这种现象。

递归的条件:

        1.递归公式(规律)   求n的阶乘   f(n) = f(n-1) * n
        2.结束/终止的条件        n=1
        3.递归方向: 往结束的条件

注意:递归不终止, 会造成栈溢出  StackOverError

常见的递归案例: 斐波那契数列  汉诺塔  二叉树

例:删除多级目录和文件

public static void main(String[] args) {
    File file=new File("day02/file/aa/bb");
    String[] strings= file.list();
    deleteDir(file);
}
public static void deleteDir(File dir){
    File[] files=dir.listFiles();
    if(files!=null&&files.length>0){
        for(File f:files){
            if(f.isDirectory())
                deleteDir(f);
            else
                f.delete();
        }
    }
    dir.delete();
}

三、IO流

1.概述

Java中I/O操作主要是指使⽤ java.io 包下的内容,进⾏输⼊、输出操作。输⼊也叫做读取数据,输出也 叫做作写出数据。

2.IO的分类 

根据数据的流向分为:输⼊流和输出流。

        输⼊流 :把数据从 其他设备 上读取到 内存 中的流。

        输出流 :把数据从 内存 中写出到 其他设备 上的流。

格局数据的类型分为:字节流和字符流。

        字节流 :以字节为单位,读写数据的流。

                输入: InputStream  ->  FileInputStream
                输出: OutputStream  -> FileOutputStream

        字符流 :以字符为单位,读写数据的流。

                输入: Reader
                输出: Writer

3.字节流 

(1)字节输出流【OutputStream】

构造⽅法

        public FileOutputStream(File file) :创建⽂件输出流以写⼊由指定的 File对象表示的⽂件。

        public FileOutputStream(String name) :创建⽂件输出流以指定的名称写⼊⽂件。

 常用方法

        public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

        public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

        public void write(byte[] b) :将 b.length字节从指定的字节数组写⼊此输出流。

        public void write(byte[] b, int off, int len) :从指定的字节数组写⼊ len 字节,从偏移

        量 off 开始输出到此输出流。

        public abstract void write(int b) :将指定的字节输出流。

File file=new File("day02/file/aa/out.txt");
// append-true, 打开文件, 并写入文件末尾 (追加)
FileOutputStream fos=new FileOutputStream(file,true);

fos.write(-25);
fos.write(-113);
fos.write(-83);

byte[] bs = {-25, -113, -83};
// 将指定字节数组的所有字节一起写入文件中
fos.write(bs);

byte[] bs1 = "天气太热了".getBytes();
// 将bs1字节中, 从off开始, 写len个字节
fos.write(bs1, 3, 9);

byte[] by={-24, -121, -86, -27, -73, -79};
fos.write(by,0,6);

fos.close();

 (2)字节输⼊流【InputStream】

构造⽅法

        FileInputStream(File file) :通过打开与实际⽂件的连接来创建⼀个 FileInputStream ,该⽂件

由⽂件系统中的 File对象 file命名。

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

常用方法 

        public void close() :关闭此输⼊流并释放与此流相关联的任何系统资源。

        public abstract int read() :从输⼊流读取数据的下⼀个字节。

        public int read(byte[] b) :从输⼊流中读取⼀些字节数,并将它们存储到字节数组 b中 。

// 如果文件不存在, 抛出 FileNotFoundException
File file = new File("dd/out.txt");


FileInputStream fis = new FileInputStream(file);
int i;
while ((i=fis.read())!=-1){
    System.out.print(i+",");
}

byte[] bs = new byte[(int)(file.length())];
System.out.println("bs 的长度: " + bs.length);
// 读一些字节, 存入到 bs 数组中, 最多读20个字节
int len = fis.read(bs);
System.out.println(Arrays.toString(bs));
System.out.println("读出来的个数: " + len);

// 解码, 从bs数组的0位置开始, 一共解码 len 个字节
String str = new String(bs, 0, len, "UTF-8");
System.out.println("读出来的字节解码后: " + str);

字节流常用于复制文件

FileOutputStream fos=new FileOutputStream("day02/file/read-copy.png");
FileInputStream fis=new FileInputStream("day02/file/read.png");

byte[] bs=new byte[1024];
int i;
while ((i= fis.read(bs))!=-1){
    fos.write(bs,0,i);
}
fos.close();
fis.close();

 进阶:带缓冲区的复制文件(效率更高) 

FileOutputStream fos=new FileOutputStream("day02/file/read-copy.png");
FileInputStream fis=new FileInputStream("day02/file/read.png");

//添加缓冲区
BufferedOutputStream bos=new BufferedOutputStream(fos);
BufferedInputStream bis=new BufferedInputStream(fis);

long start=System.currentTimeMillis();
byte[] bs=new byte[1024];
int i;
while ((i= bis.read())!=-1){
    bos.write(bs,0,i);
}
long end=System.currentTimeMillis();
bis.close();
bos.close();
fos.close();
fis.close();
System.out.println("时间:"+(end-start));

4.字符流

(1)字符输⼊流【Reader】 

构造方法

        FileReader(File file) :创建⼀个新的 FileReader ,给定要读取的File对象。

        FileReader(String fileName) :创建⼀个新的 FileReader ,给定要读取的⽂件的名称。

常用方法 

        public void close() :关闭此流并释放与此流相关联的任何系统资源。

        public int read() :从输⼊流读取⼀个字符。

        public int read(char[] cbuf) :从输⼊流中读取⼀些字符,并将它们存储到字符数组 cbuf 中。

FileReader reader=new FileReader("day02/file/out.txt");
int i= reader.read();
System.out.println("i:"+i);
System.out.println((char) i);

char[] chars=new char[20];
int len=reader.read(chars);//读出来的字符数

System.out.println("内容是:"+chars);
System.out.println(chars);

String str=new String(chars,0,len);
System.out.println(str);

(2)字符输出流【Writer】 

构造方法

        FileWriter(File file) :创建⼀个新的 FileWriter,给定要读取的File对象。

        FileWriter(String fileName) :创建⼀个新的 FileWriter,给定要读取的⽂件的名称。 

常用方法  

        void write(int c) :写⼊单个字符。

        void write(char[] cbuf) :写⼊字符数组。

       abstract void write(char[] cbuf, int off, int len) :写⼊字符数组的某⼀部分,off数组的开始索引,len写的字符个数。

        void write(String str) :写⼊字符串。

        void write(String str, int off, int len) :写⼊字符串的某⼀部分,off字符串的开始索引,len写的字符个数。

        void flush() :刷新该流的缓冲。

        void close() :关闭此流,但要先刷新它。

FileWriter writer=new FileWriter("day02/file/out.txt");
//自带缓冲区—>内存中
writer.write("好");
writer.write('h');
char[] chars={'h','e','n'};
writer.write(chars);
writer.write(chars,1,2);

String str="真好!";
writer.write(str);
writer.write(str,1,2);

writer.flush();
writer.close();//关闭流,先刷新

字符流常用于读写文件

例:按行读取文件(BufferedReader)

FileReader reader=new FileReader("day02/file/out.txt");
BufferedReader br=new BufferedReader(reader);

String str;
while ((str=br.readLine())!=null){
    System.out.println(str);
}
br.close();

将数据打印到文件中(PrintWriter)

// PrintWriter 8个构造方法
// autoFlush -> true, 只有使用println方法写入的时候, 才会自动刷新缓冲区
public static void main(String[] args) throws IOException {
    // 1.1直接传递一个文件名: 使用默认字符集, 清空原文件, 不会自动刷新缓冲区
    PrintWriter pw1 = new PrintWriter("out.txt");
    // 1.2传递一个文件名 + 字符集: 使用指定字符集, 清空原文件, 不会自动刷新缓冲区
    PrintWriter pw2 = new PrintWriter("out.txt", "GBK");
    // 2传递一个文件对象(或者 + 字符集): 效果同 1
    // 3.1传递一个字节流: 使用默认字符集, 清空原文件, 不会自动刷新
    FileOutputStream fos3 = new FileOutputStream("out.txt");
    PrintWriter pw3 = new PrintWriter(fos3);
    // 3.2传递一个字节流+自动刷新: 使用默认字符集, 清空原文件, 会自动刷新(println)
    FileOutputStream fos4 = new FileOutputStream("out.txt");
    PrintWriter pw4 = new PrintWriter(fos4, true);
    // 3.3传递一个字节流: 使用默认字符集, 在原文件上追加
    FileOutputStream fos5 = new FileOutputStream("out.txt", true);
    PrintWriter pw5 = new PrintWriter(fos5, true);

    // 4.传递一个字符流(或者 + 自动刷新): 效果同3
    // 5.转换流(字符流Writer)  OutputStreamWriter
    FileOutputStream fos = new FileOutputStream("out.txt", true);
    OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
    PrintWriter pw = new PrintWriter(osw, true);

    pw.println("你好, 今天吃了吗? 没吃呢还");

    //pw.flush();
}

一个字符集是GBK的文件,使用 BufferedReader 一行一行读取出来, 并且打印到控制台

File f=new File("day02/file/aa/out.txt");
FileInputStream fis=new FileInputStream(f);
InputStreamReader isr=new InputStreamReader(fis,"GBK");
BufferedReader br=new BufferedReader(isr);

String str;
while ((str=br.readLine())!=null) {
    System.out.println(str);
}
br.close();

5.对象流 

(1)作用

        文件里存放对象(属性 , 值) 

(2)用法

新建一个Person类,接口Serializable表示可序列化的

public class Person implements Serializable {
    public static final long serialVersionUID = 2l;//UID唯一
    public String name;
    public int age;
    private transient char sex;//transient: 临时属性

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

将Person对象存入文件

Person p1=new Person("张三",18);
FileOutputStream fos=new FileOutputStream("day02/file/obj.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);

// 序列化
oos.writeObject(p1);
oos.close();

 从文件中读取对象

FileInputStream fis=new FileInputStream("day02/file/obj.txt");
ObjectInputStream ois=new ObjectInputStream(fis);

// 反序列化
Person p1=(Person) ois.readObject();
System.out.println(p1);
ois.close();

6.小结

     字节流的父类: InputStream / OutputStream
     字符流的父类: Reader / Writer

     字节流的普通子类: FileInputStream / FileOutputStream
     字符流的普通子类: FileReader / FileWriter

     带缓冲区的字节流: BufferedInputStream / BufferedOutputStream
     带缓冲区的字符流: BufferedReader / PrintWriter(打印流)

     转换流: OutputStreamWriter / InputStreamReader

     对象流:  ObjectInputStream  ObjectOutputStream
                          readObject()           writeObject()

     transient: 临时属性, 不会写入到文件中

    出现的异常: 

    NotSerializableException: 不是可序列化的, 需要添加可序列化接口
            Serializable: 接口内容 无
     InvalidClassException: 不兼容的类型, 需要添加版本号来固定版本
            public static final long serialVersionUID=唯一

暑期编程PK赛 得CSDN机械键盘等精美礼品!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016659.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号