JAVA中级二 输入输出流,常见文件操作

这篇博客详细介绍了JAVA中的输入输出流,包括文件对象的创建与操作,流的概念及其分类,如字节流、字符流。讲解了ASCII码、文件读写、缓存流的使用,以及如何处理中文字符。还涵盖了对象流、System.in的使用,以及文件复制、文件夹复制等综合练习。
摘要由CSDN通过智能技术生成

输入输出流,常见文件操作

01 文件对象

文件和文件夹都是用File代表。

1.1 创建一个文件对象

使用绝对路径或者相对路径创建File对象。实际上,没有创建文件。
基本语法:File f=new File("路径");

 	// 绝对路径
    File f1 = new File("d:/LOLFolder");
    System.out.println("f1的绝对路径:" + f1.getAbsolutePath());
    // 相对路径,相对于工作目录,如果在eclipse中,就是项目目录
    File f2 = new File("LOL.exe");
    System.out.println("f2的绝对路径:" + f2.getAbsolutePath());
    // 把f1作为父目录创建文件对象
    File f3 = new File(f1, "LOL.exe");
    System.out.println("f3的绝对路径:" + f3.getAbsolutePath());

1.2 文件的常用方法1

  1. 创建文件对象

    File f=new File("d:/LOLFolder/LOL.exe");
    
  2. 判断文件是否存在,返回boolean值

    f.exists();
    
  3. 判断文件是否是文件夹,返回boolean值

    f.isDirectory();
    
  4. 判断文件是否是文件(非文件夹),返回boolean值

    f.isFile();
    
  5. 获取文件的长度

    f.length();
    
  6. 获取文件最后修改时间

    long time = f.lastModified();
    Date d = new Date(time);
    
  7. 设置文件最后修改时间

    f.setLastModified(0);
    //设为1970.1.1 08:00:00
    
  8. 文件重命名(renameTo方法用于对物理文件名称进行修改,但是并不会修改File对象的name属性。)

	File f2 =new File("d:/LOLFolder/DOTA.exe");
	f.renameTo(f2);
	//由LOL.exe改为DOTA.exe

1.3 文件的常用方法2

  1. 创建文件对象
    File f=new File("d:/LOLFolder/skin/garen.ski");
    
  2. 获取当前文件夹下的文件
    f.list();
    //以字符串数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
    
    File[] fs=f.listFiles;
    //以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
    
  3. 获取所在文件夹
	f.getParent();
	//以字符串形式返回获取所在文件夹
	
	f.getParentFile();
	//以文件形式获取所在文件夹
  1. 创建文件夹
	f.mkdir();
	//创建文件夹,如果父文件夹skin不存在,就创建无效
	
	f.mkdirs();
	//创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
	
	f.creatNewFile();
	//创建一个空文件夹,如果父文件夹skin不存在,就会抛出异常
	//所以创建一个空文件夹之前,通常都会创建父文件夹
	f.getParentFile.mkdirs();
  1. 列出所有盘符
	f.listRoots();
	//列出所有的盘符c: d: e: 等等
  1. 删除文件
	f.delete();
	//删除文件

	f.deleteOnExit();
	//JVM结束时,删除文件,常用于临时文件的删除

1.4 练习

  1. 遍历一个文件夹,并找出最大的和最小(非0)的那个文件;
  2. 遍历一个文件夹下所有文件,并找出最大的和最小(非0)的那个文件;

02 什么是流

什么是流(Stream),流就是一系列的数据。

2.1 流的理解

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序。
比如:读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream;
输出流:OutputStream。
在这里插入图片描述

2.2 文件输入流

如下代码,就建立了一个文件输入流,这个流可以用来把数据从硬盘的文件,读取到JVM(内存)。
目前代码只是建立了流,还没有开始读取。

package stream;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
public class TestStream {
   
 
    public static void main(String[] args) {
   
        try {
   
            File f = new File("d:/lol.txt");
            // 创建基于文件的输入流
            FileInputStream fis = new FileInputStream(f);
            // 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中
 
        } catch (IOException e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
    }
}

2.3 文件输出流

	try {
   
		File f=new File("d:/lol.txt");
		FileOutputStream fos=new FileOutputStream(f);
	}catch(IOException ioe) {
   
		ioe.getStackTrace();
	}

03 字节流

InputStream字节输入流;
OutputStream字节输出流;
用于以字节的形式读取和写入数据。

3.1 ASCII码

所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
在这里插入图片描述

3.2 以字节流的形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取.

package stream;
  
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
  
public class TestStream {
   
  
    public static void main(String[] args) {
   
        try {
   
            //准备文件lol.txt其中的内容是AB,对应的ASCII分别是65 66
            File f =new File("d:/lol.txt");
            //创建基于文件的输入流
            FileInputStream fis =new FileInputStream(f);
            //创建字节数组,其长度就是文件的长度
            byte[] all =new byte[(int) f.length()];
            //以字节流的形式读取文件所有内容
            fis.read(all);
            for (byte b : all) {
   
                //打印出来是65 66
                System.out.println(b);
            }
             
            //每次使用完流,都应该进行关闭
            fis.close();
              
        } catch (IOException e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
    }
}

3.3 以字节流的形式向文件写入数据

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据。

注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。
但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常

package stream;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class TestStream {
   
 
    public static void main(String[] args) {
   
        try {
   
            // 准备文件lol2.txt其中的内容是空的
            File f = new File("d:/lol2.txt");
            // 准备长度是2的字节数组,用88,89初始化,其对应的字符分别是X,Y
            byte data[] = {
    88, 89 };
 
            // 创建基于文件的输出流
            FileOutputStream fos = new FileOutputStream(f);
            // 把数据写入到输出流
            fos.write(data);
            // 关闭输出流
            fos.close();
             
        } catch (IOException e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
    }
}

练习之文件和目录不存在时,如何写入文件

package stream;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class TestStream {
   
 
    public static void main(String[] args) {
   
        try {
   
            File f = new File("d:/xyz/abc/def/lol2.txt");
             
            //因为默认情况下,文件系统中不存在 d:\xyz\abc\def,所以输出会失败
             
            //首先获取文件所在的目录
            File dir = f.getParentFile();
            //如果该目录不存在,则创建该目录
            if(!dir.exists()){
   
//              dir.mkdir(); //使用mkdir会抛出异常,因为该目录的父目录也不存在
                dir.mkdirs(); //使用mkdirs则会把不存在的目录都创建好
            }
 
            byte data[] = {
    88, 89 };
 
            FileOutputStream fos = new FileOutputStream(f);
 
            fos.write(data);
 
            fos.close();
 
        } catch (IOException e) {
   
            e.printStackTrace();
        }
 
    }
}

练习之拆分文件

package file;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
/*
*@Author hmg
*@Description 
*@Time 2019年11月24日下午3:53:52
*@Version1.0
*/
public class TestFile {
   

	public static void main(String[] args) {
   
		// TODO Auto-generated method stub
		try {
   
			File inf =new File("e:/eclipse.exe");
			FileInputStream fis=new FileInputStream(inf);
			byte[] all=new byte[(int)inf.length()];
			fis.read(all);
			
			int part=all.length/(100*1024);
			File[] ouf=new File[part+1];
			for(int i=0;i<ouf.length;i++) {
   
				String str="e:/eclipse.exe"+"-"+i;
				ouf[i]=new File(str);
			}
			for(int i=0;i<=part;i++) {
   
				FileOutputStream fos=new FileOutputStream(ouf[i]);
				if(i==part) {
   
					int rest=all.length%(100*1024);
					fos.write(all, i*100*1024,rest );
					System.out.printf("输出子文件%s,大小是%d字节%n",ouf[i].getAbsoluteFile(),rest);
					fos.close();
				}
				else {
   
					fos.write(all, i*100*1024, 100*1024);
					System.out.printf("输出子文件%s,大小是%d字节%n",ouf[i].getAbsoluteFile(),100*1024);
					fos.close();
					
				}
			}
			fis.close();
		}catch(IOException e) {
   
			e.printStackTrace();
		}
	}
}

在这里插入图片描述
答案:

package file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
  
public class TestFile {
   
  
    public static void main(String[] args) {
   
        int eachSize = 100 * 1024; // 100k
        File srcFile = new File("e:/eclipse.exe");
        splitFile(srcFile, eachSize);
    }
  
    /**
     * 拆分的思路,先把源文件的所有内容读取到内存中,然后从内存中挨个分到子文件里
     * @param srcFile 要拆分的源文件
     * @param eachSize 按照这个大小,拆分
     */
    private static void splitFile(File srcFile, int eachSize) {
   
  
        if (0 == srcFile.length())
            throw new RuntimeException("文件长度为0,不可拆分");
  
        byte[] fileContent = new byte[(int) srcFile.length()];
        // 先把文件读取到数组中
        try {
   
            FileInputStream fis = new FileInputStream(srcFile);
            fis.read(fileContent);
            fis.close();
        } catch (IOException e) {
   
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 计算需要被划分成多少份子文件
        int fileNumber;
        // 文件是否能被整除得到的子文件个数是不一样的
        // (假设文件长度是25,每份的大小是5,那么就应该是5个)
        // (假设文件长度是26,每份的大小是5,那么就应该是6个)
        if (0 == fileContent.length % eachSize)
            fileNumber = (int) (fileContent.length / eachSize);
        else
            fileNumber = (int) (fileContent.length / eachSize) + 1;
  
        for (int i = 0; i < fileNumber; i++) {
   
            String eachFileName = srcFile.getName() + "-" + i;
            File eachFile = new File(srcFile.getParent(), eachFileName);
            byte[] eachContent;
  
            // 从源文件的内容里,复制部分数据到子文件
            // 除开最后一个文件,其他文件大小都是100k
            // 最后一个文件的大小是剩余的
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值