java文件与IO流

一:文件

        什么是文件? 文件对于我们来说并不陌生,文件是保存数据的地方,比如word文档,excel文件....它既可以保存图片,也可以保存视频......

Thompson的文件系统有两个重要的概念,分别是:
所有的程序或系统装置都是文件
不管建构编辑器还是附属文件,所写的程序只有一个目的,且要有效的完成目标。

 文件流

        文件在程序中是通过流的形式来操作的。

流:数据在数据源(文件)与程序(内存)之间的路经。可以拿外卖物流类似包裹类似文件物流类似文件流

常见的文件操作

   创建文件对象相关构造器和方法

        new File(String pathname)//根据路径构建一个File对象
        new File(File parent,String child) //根据父目录文件+子路径构建
        new File(String parent,String child) //根据父目录+子路径构建

       createNewFile 创建新文件   //构造器仅仅创建了对象,并没有在硬盘中创建文件

public class Wen {
	public static void main(String[] args) throws IOException {
		//1、创建文件对象  new File(String pathname)//根据路径构建一个File对象
		File file1 = new File("D:\\test1.txt");
		//2、new File(File parent,String child) //根据父目录文件+子路径构建
		File parentfile = new File("D:/");
		File file2 =new File(parentfile,"test2.txt");
		//3、new File(String parent,String child) //根据父目录路径+子路径构建
		File file3 = new File("D:/","test3.txt");

		//构造器仅仅创建了对象,并没有在硬盘中创建文件
		file1.createNewFile();
		file2.createNewFile();
		file3.createNewFile();

	}
}

获取文件信息操作

	//获取文件信息
		System.out.println("文件名:"+file1.getName());
		System.out.println("文件绝对路径:"+file1.getAbsolutePath());
		System.out.println("文件父级目录:"+file1.getParent());
		System.out.println("文件是否存在:"+file1.exists());
		System.out.println("文件是否可读:"+file1.canRead());
		System.out.println("文件是否可写:"+file1.canWrite());
		System.out.println("文件是否隐藏:"+file1.isHidden());
		System.out.println("文件是否是目录:"+file1.isDirectory());
		System.out.println("文件是否是文件:"+file1.isFile());
		System.out.println("文件长度:"+file1.length());
		System.out.println("文件最后修改时间:"+file1.lastModified());
		System.out.println("=======================================");

运行结果: 

文件名:test1.txt
文件绝对路径:D:\test1.txt
文件父级目录:D:\
文件是否存在:true
文件是否可读:true
文件是否可写:true
文件是否隐藏:false
文件是否是目录:false
文件是否是文件:true
文件长度:0
文件最后修改时间:1715436615002
=======================================

目录的操作和文件删除

        //创建一级目录
		File dir1=new File("D:/dir1");  //创建一级目录对象
		dir1.mkdir();                             //真正在磁盘创建一级目录
		//创建多级目录
		File dir2=new File("D:/dir2/dir3");
		dir2.mkdirs();
		//删除文件
		dir2.delete();  //删除了dir2目录下的所有文件,但不会删除dir2目录本身

二:IO流原理及流的分类

Java IO流原理

        I/O是Input/Output的缩写。I/O技术是非常实用的技术,用于处理数据传输。如读/写文件网络通讯等。
        Java程序中,对于数据的输入/输出操作以"流(stream)" 的方式进行。                          java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过方法输入或输出数据

输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

流的分类

 按操作数据的单位不同分为:字节流(8 bit 0~255),字符流(按字符)                                           按数据流的流向不同可以分为:输入流,输出流                                                                               按流的角色的不同可以分为:节点流,处理流/包装流(对节点流的处理和保证,以加强IO)

       抽象基类                字节流                        字符流
        输入流               InputStream                        Reader
        输出流               OutputStream                         Writer

Java的io流共涉及40多个类,实际上非常规则,都是以4个抽象基类派生的

由这四个类派生出来的子类名称都是以其父类名作为子类名后缀

常见的类

FileInputStream

        FileInputStream是 Java 中用于从文件中读取数据的输入流类。它允许程序以字节为单位从指定文件中读取数据。通过创建FileInputStream对象并调用相关方法,可以逐字节地读取文件内容,进行数据处理等操作。

FileInputStream有以下一些常见的构造方法:
   FileInputStream(File file):通过指定的File对象来创建输入流。
   FileInputStream(String pathname):通过指定文件的路径字符串来创建输入流。

FileInputStream主要有以下一些常用方法:
   int read():从输入流中读取一个字节的数据。
   int  read(byte[] b):从输入流中读取一定数量的字节到字节数组中,返回长度。
   available():返回可以从该输入流中读取的剩余字节数的估计值。
   close():关闭此输入流并释放与该流关联的任何系统资源。

public class FIS {
	public static void main(String[] args) throws IOException {
		FileInputStream fis1 =new FileInputStream(new File("src\\hello.txt"));
		FileInputStream fis2 =new FileInputStream(new File("src\\hello.txt"));

		//读取文件方式一:int read() 返回读取的字节
		int read=0;
		while((read=fis1.read())!=-1){
			System.out.print((char)read);
		}
		fis1.close();
		//读取文件方式二:int read(byte[] b) 返回读取的字节数
		int readLen=0;
		byte[] b=new byte[1024];
		while((readLen=fis2.read(b))!=-1){
			System.out.println(new String(b,0,readLen));
		}
		fis2.close();
	}
}

FileOutStream

        FileOutputStream是 Java 中用于向文件写入数据的类。它可以将数据以字节流的形式写入指定的文件。通过创建FileOutputStream对象,并调用其方法,如write()来将字节数据写入文件。这在需要将数据持久化到文件中时非常有用。

FileOutputStream类提供了多种方法用于向文件写入数据,以下是一些常见的方法:
    write(int b):写入一个字节到文件。
    write(byte[] b):将一个字节数组写入文件。
    write(byte[] b, int off, int len):从字节数组的指定位置开始,写入指定长度的字节到文件。
    close():关闭输出流,释放相关资源。
这些方法帮助字节数据写入文件中。在使用FileOutputStream时,还需要注意以下几点:
    创建FileOutputStream对象时,可以指定文件的路径和模式(如覆盖或追加)。
    在写入数据后,建议使用close()方法关闭输出流,以释放相关资源。
    如果需要写入字符串或其他类型的数据,可以先将其转换为字节数组再进行写入。
    处理文件操作时,需要处理可能出现的异常,如文件不存在、权限问题等。

class Fos{
	File file;
	FileOutputStream fos;

	Fos() throws FileNotFoundException {
		file = new File("C:\\Users\\86186\\IdeaProjects\\u\\Market\\src\\hello.txt");
		try {
			fos = new FileOutputStream(file,true);  // true表示追加写入, false表示覆盖写入
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public void fosTest(){
		try {
			//写入方法一:write(int b):写入一个字节到文件。
			fos.write('h');
			fos.write('e');
			fos.write('l');
			fos.write('l');
			fos.write('o');

			//写入方法二:write(byte[] b):写入一个字节数组到文件。
			//String类中的getBytes()方法可以获取到字符串对应的字节数组。
			byte[] bytes = "hello".getBytes();
			fos.write(bytes);

			//写入方法三:write(byte[] b, int off, int len):写入一个字节数组的一部分到文件。  off:起始位置,len:写入长度
			fos.write(bytes, 0, 3);

		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				fos.close();        // 关闭流, 释放资源,只有关闭流, 才能保证数据全部写入到文件,因为默认情况下,流是缓冲的,缓冲区满了才会写入文件
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public static void main(String[] args) throws FileNotFoundException {
		Fos fos = new Fos();
		fos.fosTest();
	}

}

FileReader

        FileReader类主要用于从文件中读取字符数据。它是一个字符输入流,继承自InputStreamReader(转换流),抽象基类为Reader。可以通过构造方法传入文件路径来创建

FileReader的构造方法主要有以下几种:
      FileReader(File file):创建一个与指定文件对象相关联的FileReader。
      FileReader(String fileName):创建一个与指定文件路径名相关联的FileReader

FileReader类的一些主要方法包括:
   int read():从输入流中读取一个字符,返回该字符的整数表示(到达文件末尾返回 -1)
   int read(char[] cbuf):将字符读入数组。返回读取的长度
   void close():关闭该流并释放与之关联的所有资源。

相关API:
      String(char[]) 将字符数组转换成String

      String(char[],int off,int len) 

public class FR {

	public static void main(String[] args) {
		FR fr = new FR();
		try {
			fr.readFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void readFile() throws IOException {
		FileReader fr = new FileReader("C:\\Users\\86186\\IdeaProjects\\u\\Market\\src\\hello.txt");
		// 读取文件方式一:int read():从输入流中读取一个字符,返回该字符的整数表示(到达文件末尾返回 -1)
		int date = 0;
		while ((date = fr.read())!= -1) {
			System.out.print((char) date);
		}
		fr.close(); // 这里要关闭,否则下面再次读取会出错
		
//		在这个例子中,FileReader对象不能重复使用是因为每次读取文件时,需要重新创建一个新的FileReader对象。
//		当使用FileReader对象读取文件时,它会将文件的指针移动到文件的末尾,导致无法再次读取相同的文件。
//		为了解决这个问题,可以通过创建一个新的FileReader对象来读取相同的文件。
//		代码中,第一次读取文件时创建了一个FileReader对象fr,并在读取完成后关闭了它。
//		然后,在第二次读取文件时,你继续使用已经关闭的fr对象,这就导致了异常。
//		修改后的代码中,在第二次读取文件时,重新创建了一个FileReader对象fr2,
//		并使用它来读取文件,这样就可以避免异常的发生。
		
		// 读取文件方式二:int read(char[] cbuf):从输入流中读取一定数量的字符,并将它们存储到字符数组 cbuf 中
		char[] cbuf = new char[1024];
		while ((date = fr.read(cbuf))!= -1) {
			System.out.print(new String(cbuf, 0, date));
		}
		fr.close(); // 最后还要关闭
	}
}

FileWriter

        FileWriter类用于将字符数据写入文件。它的构造方法可以接受一个文件对象或文件路径作为参数,以便指定要写入的文件。FileWriter提供了一些方法来写入字符数据,如write()方法可以写入单个字符或字符数组。此外,还可以使用flush()方法刷新缓冲区,将数据写入文件,以及使用close()方法关闭文件并释放相关资源。

FileWriter类提供了以下一些常用的方法
        write(int c):写入单个字符到文件中。
        write(char[] cbuf):将字符数组写入文件中。
        write(String str):写入字符串到文件中。
        write(String str, int off, int len):写入字符串的一部分到文件中。
        flush():刷新缓冲区,将数据写入文件。
        close():关闭文件并释放相关资源。

public class FW {
	public static void main(String[] args)
	{
		try {
			new FW().writeFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	public void writeFile() throws IOException {
		FileWriter fw = new FileWriter("C:\\Users\\86186\\IdeaProjects\\u\\Market\\src\\hello.txt");
		// 写入数据方式一:write(int c):写入单个字符到文件中。
		fw.write('h');
		fw.write('e');
		fw.write('l');
		fw.write('l');
		fw.write('o');
		fw.write('\n');


		// 写入数据方式二:write(char[] cbuf):写入字符数组到文件中。
		char[] cbuf =new char[]{'h','e','l','l','o','\n'};
		String str = "你好\n";
		char[] charArray = str.toCharArray();  // 字符串转字符数组
		fw.write(cbuf);
		fw.write(charArray);

		fw.close();  // 关闭流 释放资源 才能写入文件当中
	}
}

运行结果 :

hello
hello
你好

节点流与处理流

在 Java 中,节点流和处理流是输入/输出(I/O)流的两种主要类型。

        节点流(Node Stream):节点流是直接与数据源或目的地进行连接的流。它可以从数据源读取数据或向目的地写入数据。常见的节点流包括文件流(FileInputStream、FileWriter)、字节流(ByteArrayInputStream、ByteArrayOutputStream)等。
        处理流(Processing Stream):处理流是对节点流进行包装或处理的流[修饰器设计模式]。它不直接与数据源或目的地连接,而是在节点流的基础上提供了更高级的功能,如缓冲、过滤、转换等。常见的处理流包括缓冲流(BufferedReader、BufferedWriter)、过滤器流(FilterReader、FilterWriter)等。

 处理流的主要作用包括:

    1.性能优化:通过缓冲数据,可以减少 I/O 操作的次数,提高数据读取和写入的效率。
    2.数据处理:可以对数据进行过滤、转换、加密等处理,使数据符合特定的需求。
    3.增强功能:处理流可以提供一些额外的功能,如换行处理、字符编码转换等,使 I/O 操作更加方便和灵活。

节点流和处理流的关系是:

     节点流处于 I/O 操作的第一线,所有的操作都必须通过节点流进行;处理流则是对节点流的进一步封装和处理,以提供更强大的功能和更好的性能。


    在实际应用中,通常会根据具体的需求选择使用节点流或处理流。如果需要直接与数据源或目的地进行交互,可以使用节点流;如果需要对数据进行处理或优化,可以使用处理流。同时,也可以根据需要将多个处理流组合使用,以实现更复杂的 I/O 操作。


BufferedInputStream

        BufferedInputStream是Java IO库中的一个类,它提供了对输入流的缓冲处理。当从输入流中读取数据时,缓冲区会在后台将数据预先读取到缓冲区中,以便提高读取性能。

BufferedInputStream有以下一些常见构造方法:
1.BufferedInputStream(InputStream in):创建一个带有默认缓冲区大小的缓冲输入流,关联到指定的输入流in。
2.BufferedInputStream(InputStream in, int size):创建一个具有指定缓冲区大小的缓冲输入流,关联到指定输入流in。

对象流

        在 Java 中,对象流用于将对象写入到输出流中,或从输入流中读取对象。                              对象流使用ObjectOutputStream和ObjectInputStream类来实现。
        1.ObjectOutputStream类用于将对象写入到输出流中。它实现了java.io.OutputStream接口,并提供了将对象写入流的方法。ObjectOutputStream类的构造函数接受一个OutputStream对象作为参数,用于指定要写入的输出流。
        2.ObjectInputStream类用于从输入流中读取对象。它实现了java.io.InputStream接口,并提供了从流中读取对象的方法。ObjectInputStream类的构造函数接受一个InputStream对象作为参数,用于指定要读取的输入流。

  • 33
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值