【大数据开发】Java语言基础——字节流、转换流、File、打印流、序列流day18

本文深入讲解Java中的IO流概念,包括字符流与字节流的区别、缓冲流的使用、转换流的功能,以及如何利用File类进行文件和目录的操作。通过实例演示了文件复制、图片复制、键盘输入处理等常见场景,同时介绍了打印流和序列流的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、回顾

字符流
	Reader
	Writer
字符缓冲流
	BufferedReader
	BufferedWriter
字节流:可以操作任何类型的数据
	InputStream:字节输入流
		-----FileInoutStream:int read() 一次读一个字节    int read(byte[] arr)
	OutputStream:字节输出流,不需要刷新
		-----FileOutputStream:write(byte[] b);

下面来看看字节流

二、字节流

下面列出的是下面代码示例要用的几个方法
在这里插入图片描述

得到文件中字节的总数,也就是文件的大小(直接使用这个方法可能会造成数组内存溢出,因此适合于小文件)
在这里插入图片描述

(1)使用FileInputStream实现从文件中读取数据-----read()和read(byte[] arr)两种方式
使用FileOutputStream向文件中写入数据-----write()

import java.io.*;
class Demo1 
{
	public static void main(String[] args)throws IOException 
	{
		//write();
		//read();
		//read2();
		fun();
	}
	

	//获取文件的大小
	public static void fun()throws IOException 
	{
		FileInputStream fis = new FileInputStream("tmp.txt");
		//int num = fis.available();//得到的是文件中字节的总数,也就是文件的大小

		byte[] arr=new byte[fis.available()];

		int num = fis.read(arr);
        sop(new String(arr,0,num));
	}
     //从文件中读取数据
	public static void read2()throws IOException 
	{
		FileInputStream fis = new FileInputStream("tmp.txt");

		byte[] arr=new byte[1024];
		int num=0;
		while((num = fis.read(arr))!=-1)
		{
			System.out.print(new String(arr,0,num));
		}
        
		fis.close();


      /*
		int num = fis.read(arr);//返回的是读取的字节的个数
		System.out.print(new String(arr,0,num));

		num = fis.read(arr);//返回的是读取的字节的个数
		System.out.print(new String(arr,0,num));
        
		num = fis.read(arr);//返回的是读取的字节的个数
		System.out.print(num);//-1
      */
	}




    //从文件中读取数据
	public static void read()throws IOException 
	{
		FileInputStream fis = new FileInputStream("tmp.txt");//文件需要事先存在

		//int read()  一次读一个字节
		int num =0;
		while((num=fis.read())!=-1)
		{
			//System.out.println(Integer.toBinaryString(num));
			System.out.print((char)num);
		}

		fis.close();
		/*
		int num = fis.read();
		System.out.print((char)num);

		num = fis.read();
		System.out.print((char)num);

		num = fis.read();
		System.out.print((char)num);

		num = fis.read();
		System.out.print(num); -1
		*/
		
	}

    //向文件中写入数据--字节流
	public static void write()throws IOException
	{
		//创建字节输出流对象和文件相关联
		FileOutputStream fos=new FileOutputStream("tmp.txt");

        //void write(byte[] b)
		fos.write("abc".getBytes());//编码  直接写入文件
		fos.close();
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

总结:字节流和字符流的区别:直接写入文件,不需要刷新

(2)字节流实现复制一个文件

import java.io.*;
class Demo2 
{
	public static void main(String[] args)throws IOException  
	{
		//字节流实现复制一个文件
        FileInputStream fis = new FileInputStream("Home2.java");

        FileOutputStream fos = new FileOutputStream("Home2_copy.java");

        int num=0;
		while((num=fis.read())!=-1)
		{
			fos.write(num);
		}

		fis.close();
		fos.close();

		
	}
}

(3)字节流复制一张图片

class Demo3 
{
	public static void main(String[] args) 
	{
		//复制一个图片 --只能用字节流
        BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try
		{
			bis=new BufferedInputStream(new FileInputStream("33.jpg"));
			bos=new BufferedOutputStream(new FileOutputStream("33_copy.jpg"));

			byte[] arr=new byte[1024];
			int num=0;
			while((num=bis.read(arr))!=-1)
			{
				bos.write(arr,0,num);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();

		}finally{
			if(bis!=null)
				try
				{
					bis.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("字节缓冲读取流关闭失败");
				}
			if(bos!=null)
				try
				{
					bos.close();
				}
				catch (IOException ee)
				{
					throw new RuntimeException("字节缓冲输出流关闭失败");
				}
		}	
	}
}

字节缓冲流
	BufferedInputStream对比BufferedReader:
		  BufferedReader----String readLine()
		  BufferedInputStream----没有自己特有的方法
	BufferedOutputStream对比BufferedWriter:
	      BufferedWriter----newLine()
		  BufferedOutputStream----没有自己的特有的方法

三、转换流InputStreamReader、OutputStreamWriter

InputStream子类对象in
在这里插入图片描述
(1)下面先用in实现循环读取键盘输入的小写字母,够一行时,输出其大写形式

import java.io.*;
class Demo4 
{
	public static void main(String[] args)throws IOException 
	{
		//FileInputStream fis = new FileInputStream("tmp.txt");

		//InputStream stream = System.in;//in是一个InputStream的子类对象,是一个已经和键盘绑定好的输入流对象

		
		//int num = stream.read();//阻塞式方法

		//System.out.println((char)num);

		//循环读取键盘输入的小写字母,够一行时,输出其大写形式
        int num=0;
        StringBuilder sb = new StringBuilder();
        while(true)
		{
		    num = System.in.read();

			if(num=='\r')
				continue;
			else if(num=='\n'){
                if("over".equals(sb.toString()))
					break;
				System.out.println(sb.toString().toUpperCase());
				sb.delete(0,sb.length());
			}else
				sb.append((char)num);
		}
	}
}

(2)上面的in属于InputStream,是字节流。下面将字节流转换为字符流——转换流
字节输入流转成字符输入流:InputStreamReader-----从字节输入流到字符输入流的桥
字节输出流转成字符输出流:OutputStreamWriter-----从字符输出流转成字符输出流的桥

class Demo5 
{
	public static void main(String[] args) throws IOException
	{
		//1.定义标准的键盘输入流
		InputStream in = System.in;

		//2.把字节输入流转成字符输入流
		InputStreamReader isr=new InputStreamReader(in);//转换流

		//3.把字符输入流对象传给BufferedReader的构造方法
		BufferedReader br=new BufferedReader(isr);


        //4.定义标准的输出流(输出到控制台)
		PrintStream ps=System.out;//已经和控制台绑定的字节输出流对象

		//5.把字节输出流转成字符输出流
		OutputStreamWriter osw=new OutputStreamWriter(ps);

		//6.把字符输出流对象传给BufferedWriter的构造方法
		BufferedWriter bw=new BufferedWriter(osw);

		String line=null;

		while((line=br.readLine())!=null)
		{
		//当输入over的时候结束输入
			if("over".equals(line))
				break;
			bw.write(line);
			bw.newLine();	//每次要加换行
			bw.flush();		//每次要刷新
            //System.out.println(line);
		}
        
		br.close();
		bw.close();
	}
}

(3)经过上面的知识点学习,下来总结一下

字符流
Reader  int read()  int read(char[] arr)
  FileReaer

Writer  write(String str) flush()
  FileWriter


字节流
InputStream  int read()   int read(byte[] arr)
  FileInputStream

OutputStream  write(byte[] arr)写入多个字节   write(int a)一次写入一个字节
  FileOutputStream


缓冲流:提高效率,不具备读写功能的

  字符缓冲流
      BufferedReader(Reader r)  父类是Reader,自己特有的功能:String  readLine()

	  BufferedWriter(Writer w)  父类是Writer,自己特有的功能: void newLine()

  字节缓冲流
     BufferedInputStream(InputStream in)  父类是InputStream,没有自己特有的功能

	 BufferedOutputStream(OutputStream out) 父类是OutputStream,没有自己特有的功能

标准输入流:System.in   in是InputStream的子类对象
标准输出流:System.out  out 是PrintStream类型的对象

转换流

InputStreamReader(InputStream i)
   new BufferedReader(new InputStreamReader(System.in));

OutputStreamWriter(OutputStream s)
   new BufferedWriter(new OutputStreamWriter(System.out))

1.
确定从哪儿读
确定往哪儿写

2.确定字符流还是字节流

3.确定设备

读取键盘数据,写入到控制台

(4)练习
分别从键盘读或从文件读,写入到控制台或写入到文件,

import java.io.*;
class Demo6 
{
	public static void main(String[] args) throws IOException
	{
		//键盘读
		//BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		//从文件读
        BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("tt.txt")));
		//控制台写
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        //写入到文件
        //BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("tt.txt")));

		String line=null;
		while((line=br.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		br.close();
		bw.close();
	}
}

四、File

把文件和文件夹面向对象
(1)构造函数和常用方法
File(String pathname)
在这里插入图片描述

import java.io.*;
import java.util.*;
import java.text.*;
class Demo7 
{
	public static void main(String[] args)throws IOException 
	{
		//File:把文件和文件夹面向对象

		//File(String pathname) 
        File f1=new File("F:\\bg2002\\day18\\Demo1.java");//绝对路径
        File f11=new File("Demo1.java");//相对路径

		//File(String parent, String child) 
        File f2=new File("F:\\bg2002\\day18","Demo1.java");

		//File(File parent, String child) 
        File f3=new File("F:\\bg2002\\day18");
		File f4=new File(f3,"Demo1.java");


		//System.out.println("Hello World!");

		//fun1();
		fun2();
	}

	public static void fun2()throws IOException
	{
		File file=new File("Home2_copy.java");

		if(!file.exists())
			file.createNewFile();
        
		System.out.println(file.getName());
		System.out.println(file.getPath());//如果是相对路径,显示相对路径
		System.out.println(file.getParent());//如果是相对路径,显示null
		System.out.println(file.getAbsolutePath());

		String riqi = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified()));
        System.out.println(riqi);

		System.out.println(file.delete());
	}

	public static void fun1()throws IOException
	{
		File file=new File("bg2002.txt");

		if(!file.exists())
			file.createNewFile();//创建文件
		    //file.mkdirs();//创建文件夹
		
		System.out.println(file.isFile());//判断是不是文件
		System.out.println(file.isDirectory());//判断是不是文件夹
		System.out.println(file.isHidden());//判断是不是隐藏的
	}
}

(2)listRoots()、list()、listFiles()

package day17;
import java.io.*;

class Demo6 {
    public static void main(String[] args)
    {
        File[] roots = File.listRoots();

        for(File file:roots)
            System.out.println("listRoots():\t"+file);

        //String[] list()
        File dir=new File("F:\\QMDownload");
        String[] arr = dir.list();//只得到目录下所有的文件和文件夹
        for(String ss:arr)
        {
            System.out.println("dir.list():\t"+ss);
        }


        //File[] listFiles()   得到目录下所有的文件和文件夹,包括完整的路径
        File[] array = dir.listFiles();
        for(File f:array)
        {
            System.out.println("listFiles():\t"+f.getAbsolutePath());
        }
    }
}

(3)File[] listFiles(FileFilter filter) 方法-----lambda表达式

import java.io.*;
class Demo9
{
	public static void main(String[] args)  throws IOException 
	{
		//File[] listFiles(FilenameFilter filter) 
		
        File dir=new File("f:\\bg2002\\day18");
		//File[] files = dir.listFiles(new MyFilter());
       /*
		File[] files=dir.listFiles(new FilenameFilter(){
			 public boolean accept(File dir,String name)
				{
					if(name.endsWith(".mp4"))
						return true;
					else
						return false;
				}
		});
      */

	  File[] files=dir.listFiles((dirs,name) ->name.endsWith(".txt"));

      for(File ff:files)
		    System.out.println(ff);
	}
}
class MyFilter implements FilenameFilter
{
	public boolean accept(File dir,String name)
	{
		if(name.endsWith(".java"))
			return true;
		else
			return false;
	}
}

(4)练习

删除指定目录下的所有的内容,包括子文件夹下的所有内容

import java.io.*;
class Demo11  
{
	public static void main(String[] args) throws IOException 
	{
		//删除指定目录下的所有的内容,包括子文件夹下的所有内容  
		File dir=new File("f:\\bg2002\\day17");

		del(dir);
	}

	public static void del(File dir)throws IOException 
	{
		  File[] files = dir.listFiles();
		  for(File file:files)
		  {
			   if(file.isDirectory())
				    del(file);
			   else
				   System.out.println(file+"..."+file.delete());
		  }

		 System.out.println(dir+"..."+dir.delete());
	}
}

五、打印流

	 PrintStream:字节输出流,继承了OutputStream,具备了字节输出流的基本功能,特有的功能是打印功能,有如下方法:
	 PrintStream(File file)
	 PrintStream(String file)
	 PrintStream(OutputStream stream)

具体用法如下:

import java.io.*;
class Demo12 
{
	public static void main(String[] args)throws IOException  
	{
		PrintStream ps=new PrintStream(new FileOutputStream("t.txt"));

		//ps.write(353); // write(int a)  00000000 00000000 00000001 01100001-->款掉前三个字节01100001
        //ps.write("abc".getBytes());
        //ps.println(353);//按照数据的原样显示
        ps.write(String.valueOf(353).getBytes());// "353".getBytes()
		ps.close();
	}
}

PrintWriter :继承了Writer,具备了Writer的基本功能,自己特有的功能是打印功能

	    PrintWriter(String file)
		PrintWriter(File file)
		PrintWriter(OutputStream out)
		PrintWriter(Writer write)

下面用PrintWriter实现从控制台边输入边打印

import java.io.*;
class Demo13
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));  //这是用BufferedWrite实现边输入边打印
        PrintWriter pw = new PrintWriter(System.out,true);//指定第二个参数,可以自动刷新

        String line=null;
        while((line=br.readLine())!=null)
        {
            if("end".equals(line))
                break;
            pw.println(line);
            //bw.write(line);
            //bw.newLine();
            //bw.flush();
        }
        br.close();
        pw.close();
    }
}

六:序列流-----SequenceInputStream (了解)

import java.io.*;
import java.util.*;
class Demo14 
{
	public static void main(String[] args) throws IOException
	{
		/*
        FileInputStream f1=new FileInputStream("Demo1.java");
		FileInputStream f2=new FileInputStream("Demo2.java");
		FileInputStream f3=new FileInputStream("Demo3.java");

		Vector<FileInputStream> v=new Vector<>();
		v.add(f1);
		v.add(f2);
		v.add(f3);

		Enumeration<FileInputStream> en = v.elements();
		*/
        FileInputStream f1=new FileInputStream("Demo1.java");
		FileInputStream f2=new FileInputStream("Demo2.java");
		FileInputStream f3=new FileInputStream("Demo3.java");

		List<FileInputStream> list=new ArrayList<>();
        list.add(f1);
		list.add(f2);
		list.add(f3);

		Enumeration<FileInputStream> en = Collections.enumeration(list);

		SequenceInputStream se=new SequenceInputStream(en);
        
		FileOutputStream fos = new FileOutputStream("hebing.java");

		byte[] arr=new byte[1024];
		int num=0;
		while((num=se.read(arr))!=-1){
			fos.write(arr,0,num);
		}
        
        se.close();
		fos.close();		
	}
}

练习:下面使用序列流把一个文件拆分成多个文件,再把多个文件合并成一个文件

import java.io.*;
import java.util.*;
class Demo15 
{
	public static void main(String[] args)throws IOException 
	{
		//把一个文件拆成多个文件
         File file=new File("ok.jpg");
		 splits(file);
	}

	//把一个文件拆成多个文件
	public static void splits(File file)throws IOException 
	{
		if(!file.isFile())
			return;

		//把拆出来的文件放到同一个文件夹下
		String name=file.getName().substring(0,file.getName().indexOf("."));
		File dir=new File(name);
		if(!dir.exists())
			dir.mkdir();

		FileInputStream fis=new FileInputStream(file);

		FileOutputStream fos = null;

		byte[] arr=new byte[1024*1024*2];
		int num=0;
		int n=1;
		while((num=fis.read(arr))!=-1){
			fos=new FileOutputStream(new File(dir,(n++)+".jpg"));
            fos.write(arr,0,num);
		}
         
		 //附加一个说明信息
		 Properties pro=new Properties();
		 pro.setProperty("fileType",file.getName());
		 pro.setProperty("fileNumber",Integer.toString(--n));

		 //把map集合中的信息写入到文件
		 fos=new FileOutputStream(new File(dir,"readme.txt"));

		 pro.store(fos,"haha");

         fis.close();
		 fos.close();

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值