Java输入输出流和文件操作

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: 操作系统中的文件和目录概念文件与文件系统文件是信息的一种组织形式,是存储在外部存储介质上的具有标志名的一组相关信息集合。 文件系统用文件概念来组织和管理存放在各种介质上的信息。文件系统提供目录机制实现文件的“按名存取”。目录结构与文件检索目录是文件系统组织和管理文件的基本单位,目录中保存它所管理的每个文件的基本属性信息(成为文件目录项或文件控制块)。除

操作系统中的文件和目录概念

文件与文件系统

文件是信息的一种组织形式,是存储在外部存储介质上的具有标志名的一组相关信息集合。
文件系统用文件概念来组织和管理存放在各种介质上的信息。文件系统提供目录机制实现文件的“按名存取”。

目录结构与文件检索

目录是文件系统组织和管理文件的基本单位,目录中保存它所管理的每个文件的基本属性信息(成为文件目录项或文件控制块)。除了文件外,目录中还可以包含子目录和文件,子目录中还可以再有子目录和文件,由此构成目录的多级树状结构。文件是这种树状结构的叶子节点,文件中不能包含另一个文件。

在多级树状目录结构中,一个文件的全名由该文件的路径名和文件名组成。一个文件的路径名由根目录开始沿各级子目录到达该文件的路径上的所有子目录名组成。

文件的逻辑结构

文件是文件系统中最小的数据组织单位,目录机制提供文件之间的分类和组织方式。
文件的组织是指文件中信息的配置和构造方式。文件的组织包含两方面:逻辑结构存储结构。文件的逻辑结构是从用户角度所观察到的文件中信息的组织方式,文件的存储结构是文件在外部存储器上的实际存放方式。
按照文件的逻辑结构,文件可以划分为两大类:流式文件记录式文件
流式文件由字节序列或字符序列组成。流式文件内的信息不再划分结构,只是具有顺序关系的一系列字节或字符集合,字节或字符是信息的最小单位。
记录式文件是一种有结构的文件,包含若干记录。记录是文件中按信息在逻辑上的独立含义划分的一个信息单位,记录在文件中的排列具有顺序关系。记录是文件内独立的最小信息单位,操作系统每次操作至少存储、检索或更新一个记录。记录可以被进一步划分为若干个更小的数据项,数据项是具有标志名的最小的不可分割的数据单位。数据项的集合构成记录,相关记录的集合构成文件。对记录的划分及对数据项的类型描述,均由应用程序完成。

文件的存取方式

存取方式是操作系统为应用程序听的使用文件的技术手段。文件类型、文件的逻辑结构决定文件的存取方式。文件的存取方式主要有顺序存取随机存取索引存取
①顺序存取是指按记录顺序进行读/写操作的存取方式。
②随机存取是指按记录序号进行读/写操作的存取方式。
③索引存取是基于索引文件的存取方法。由于文件中的记录不按它在文件中的位置,而按它的记录键来编址,所以用户提供给操作系统记录键后就可查找到所需记录。

文件的使用方式

针对用户和应用程序两种不同的对象,操作系统通过操作接口应用程序接口两种方式提供其功能和服务,对文件系统亦是如此。
①操作接口:操作系统将其功能和服务以操作命令形式提供给用户,用户以手动方式对文件系统等进行操作,实现人机交互功能。
②应用程序接口:操作系统将其功能和服务以系统调用(system call)形式提供给应用程序。

流的概念

流的定义和作用

流(stream)是指一组有顺序的、有起点和终点的字符集合,是对数据传输的总称和抽象。换言之,数据在两个对象之间的传输称为流。
对流进行读/写操作的最小单位是字节,即一次可以写入一字节或者读取一字节。提高数据传输效率的办法是,将一块内存空间设计成缓冲区(buffer),暂时存放待传送的数据,通过缓冲区可以一次读/写若干字节,缓冲区使数据能够以较大的数据块形式传送,从而能够显著地提供数据传输效率。配备缓冲区的流成为缓冲流(buffered stream)。
设计流的作用是使数据传输操作独立于相关设备。程序需要根据待传输数据的不同特性而使用不同的流,数据传输给指定设备后的操作由系统执行设备驱动程序完成。

流的存在

以下4种情况存在数据流动问题:
控制台应用程序的标准输入/输出操作
文件读写操作
线程通信
网络通信

Java的流类和文件类

按照流中元素的基本单位,流可分为字节流(binary stream)和字符流(character stream)。按照流的方向性,流可分为输入流输出流。每种流类都有输入流和输出流两个类。
①字节流以字节为单位读/写流,用于传输非字符数据,如整数、浮点数,对象等。InputStream和OutputStream是字节输入/输出流的根类。
②字符流以字符为单位读/写流,仅用于传输字符,包括各种字符集。Reader和Write是字符输入/输出流的根类。
File文件类记载文件属性信息,RandomAccessFile随机存取文件类以随机存取方式进行文件读/写操作。

示例

从字节流中读取1字节

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Main {
    public static void main(String[] args) throws Exception{
        String filename = "a.txt";
        FileOutputStream fout = new FileOutputStream(filename);
        fout.write(-1);
        fout.close();

        FileInputStream fin = new FileInputStream(filename);
        int i;
        while ((i = fin.read()) != -1){
            System.out.print(i + " ");
        }
        fin.close();
    }
}

输出结果:

255

FileOutputStream类的write(int i)方法向字节流写入int整型i的低位一字节,FileInputStream类的read()方法从字节流中读取1字节,作为一个int整数的最低1字节,并将该整数的高位3字节补0。

从字节流中读取4字节作为一个int整数

public class Main {
    public static void main(String[] args) throws Exception{
        String filename = "a.txt";
        FileOutputStream fout = new FileOutputStream(filename);
        int value = -128;
        fout.write(value>>>24);
        fout.write(value>>>16);
        fout.write(value>>>8);
        fout.write(value);
        fout.close();

        FileInputStream fin = new FileInputStream(filename);
        while ((value = fin.read()) != -1){
            int temp;
            for (int i = 0; i < 3 && (temp = fin.read()) != -1; i++){
                value = value << 8 | temp;
            }
            System.out.println(value + " ");
        }
        fin.close();
    }
}

数据字节流读取操作:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Main {
    public static void main(String[] args) throws Exception{
        String filename = "a.txt";
        FileOutputStream fout = new FileOutputStream(filename);
        DataOutputStream dout = new DataOutputStream(fout);
        for (int i = 0; i < 10; i++){
            dout.writeInt(i);
        }
        dout.close();
        fout.close();

        FileInputStream fin = new FileInputStream(filename);
        DataInputStream din = new DataInputStream(fin);
        try{
            while (true){
                System.out.print(din.readInt() + " ");
            }
        }catch (EOFException ex){
            //ex.printStackTrace();
        }finally{
            din.close();
            fin.close();
        }
    }
}

把一个对象的表示转换成一个字节流的过程称为序列化(serialization),反之,从字节流中重建对象的过程称为去序列化。对象能够序列化的标记是该类实现java.io.Serializable序列化接口,Serializable是标记接口,其中没有方法。如果要写入的对象没有实现序列化接口,则抛出java.io.NotSerializableException异常。

public class Main {
    public static void main(String[] args) throws Exception{
        String filename = "a.txt";
        FileOutputStream fout = new FileOutputStream(filename);
        ObjectOutputStream objout = new ObjectOutputStream(fout);
        for (int i = 0; i < 10; i++){
            objout.writeObject(new TreeNode((int)(Math.random() * 100)));
        }
        objout.close();
        fout.close();

        FileInputStream fin = new FileInputStream(filename);
        ObjectInputStream objin = new ObjectInputStream(fin);
        try{
            while (true){
                System.out.println(objin.readObject());
            }
        }catch (EOFException ex){

        }finally{
            objin.close();
            fin.close();
        }
    }
}

管道字节流实现发牌程序示例:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.IOException;

public class Main {
    private PipedInputStream pins[];
    private PipedOutputStream pouts[];
    public Main(int cardMax, int number) throws IOException{
        this.pins = new PipedInputStream[number];
        this.pouts = new PipedOutputStream[number];
        for (int i = 0; i < number; i++){
            this.pins[i] = new PipedInputStream();
            this.pouts[i] = new PipedOutputStream(this.pins[i]);
        }

        new SendThread(this.pouts, cardMax).start();;
        for (int i = 0; i < number; i++){
            new ReceiveThread(this.pins[i], "PLAY" + (i + 1)).start();
        }
    }

    public static void main(String[] args) throws Exception{
        new Main(52, 4);
    }
}

class SendThread extends Thread{
    private PipedOutputStream pouts[];
    private int cardMax;
    public SendThread(PipedOutputStream pouts[], int cardMax){
        this.pouts = pouts;
        this.cardMax = cardMax;
        this.setPriority(Thread.MAX_PRIORITY);
    }

    public void run(){
        DataOutputStream douts[] = new DataOutputStream[this.pouts.length];
        for (int i = 0; i < douts.length; i++){
            douts[i] = new DataOutputStream(this.pouts[i]);
        }
        try{
            int value = 1;
            while (value <= this.cardMax){
                for (int i = 0; value <= this.cardMax && i < douts.length; i++){
                    douts[i].writeInt(value++);
                }
            }
            for (int i = 0; i < douts.length; i++){
                douts[i].close();
                this.pouts[i].close();
            }
        }catch(IOException ex){ ex.printStackTrace();}
    }
}

class ReceiveThread extends Thread{
    private PipedInputStream pin;
    private String name;
    public ReceiveThread(PipedInputStream pin, String name){
        this.pin = pin;
        this.name = name;
    }

    public void run(){
        DataInputStream din = new DataInputStream(this.pin);
        while (true){
            try{
                System.out.println(this.name + "取牌" + din.readInt());
                Thread.sleep(100);
            }
            catch(IOException ex) { break; }
            catch(InterruptedException ex) {}
        }
        try{
            din.close();
            this.pin.close();
        }catch(IOException ex) {}
    }
}

使用字符流读写文本文件示例:

public class Main {
    public static void main(String[] args) throws Exception{
        String filename = "b.txt";
        try{
            FileReader fr = new FileReader(filename);
            FileWriter fw = new FileWriter("c.txt");
            BufferedReader br = new BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null){
                fw.write(line);
                fw.write('\n');
            }
            br.close();
            fr.close();
            fw.close();
        }catch(IOException ex){}
    }
}

RandomAccessFile随机存取文件类以随机存取方式进行文件读/写操作,对一个文件可以同时进行既读又写的操作;在文件指定位置读取或者写入基本数据类型。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
6月前
|
Java
揭秘Java文件操作背后的惊天秘密:读写、复制、删除一网打尽!
【6月更文挑战第27天】Java文件操作涵盖读、写、复制和删除。例如,读文件使用`BufferedReader`和`FileReader`;写文件利用`BufferedWriter`和`FileWriter`;复制文件通过读写流实现;删除文件则依赖`Files.delete()`。以上代码示例展示了具体实现。
39 5
|
6月前
|
Java API
Java文件操作,你的电脑“硬盘”竟然可以这样玩?!
【6月更文挑战第27天】Java文件操作涵盖创建、读取、写入、复制、删除等。`java.io`和`java.nio.file`包提供API,如`BufferedReader/FileReader`用于读取,`BufferedWriter/FileWriter`用于写入,`Files.copy()`用于复制,`Files.delete()`用于删除文件。以上代码示例展示了这些功能的简单用法。
39 1
|
6月前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
172 2
|
7月前
|
Java API
Java的文件操作:创建、读写与删除的技术性详解
Java的文件操作:创建、读写与删除的技术性详解
49 1
|
6月前
|
安全 Java 开发者
掌握Java文件操作,让你的代码“飞”起来!读写、复制、删除全攻略!
【6月更文挑战第27天】Java文件操作涵盖读写、复制、删除。使用NIO的`Files`类提升效率:读取文件用`newBufferedReader`实现逐行读,写入文件用`newBufferedWriter`,复制文件用`copy`方法,删除文件用`deleteIfExists`,确保安全。这些最佳实践优化了内存使用,简化了代码。
39 0
|
3月前
|
Java
Java文件操作
本文介绍了Java中`File`类的使用方法,包括构造方法、常见成员方法及其实现功能。`File`对象可以表示文件或文件夹,支持绝对路径和相对路径。构造方法有三种:基于完整路径、父级路径与子路径组合、`File`对象与字符串组合。成员方法涵盖判断类型、获取大小、获取路径、创建与删除文件/文件夹、获取文件列表、重命名等操作。文章通过示例代码详细展示了各个方法的应用场景及注意事项。
42 1
Java文件操作
|
6月前
|
监控 Java API
Java文件操作大揭秘:不只是读写,还有这些逆天技巧!
【6月更文挑战第27天】Java文件操作不仅包括基础的读写,还有NIO的文件过滤、锁定、映射以及压缩解压和文件变化监控。例如,使用Files.walk结合PathMatcher查找特定类型的文件,利用FileChannel进行文件锁定和内存映射以提升效率,借助ZipOutputStream压缩文件,以及用WatchService监听文件系统变化。这些高级技巧能提升开发效率。
35 3
|
6月前
|
Java API
惊呆了!Java文件操作竟能如此简单:一分钟学会读写、复制、删除!
【6月更文挑战第27天】Java编程中的文件操作简单易行。使用`java.io`包中的`FileInputStream`和`FileOutputStream`进行读写,例如写文件将字符串转为字节写入,读文件则循环读取字节。文件复制涉及两个流,从源文件读取后写入目标文件。删除文件只需调用`File`对象的`delete`方法。这些基本操作让Java文件处理变得直观且易于掌握。
35 1
|
6月前
|
存储 网络协议 Java
Java I/O 详解:基础、文件操作与 NIO 实践
Java I/O 详解:基础、文件操作与 NIO 实践
54 1
|
5月前
|
Java 数据库
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
35 0