JAVA中的IO简介2

1 篇文章 0 订阅
1 篇文章 0 订阅

一、File类

File类主要有两个个作用:

1.      用来将文件或者文件夹封装成对象,方便对其属性信息进行操作

2.      File对象可以作为参数传递给IO流的构造函数等。

 

当我们拿到文件或文件夹的对象时,就可以对这个文件或文件夹进行各种操作,比如:我们可以得到它的名字、大小、上次修改时间,它的绝对路径等,可以对它进行创建、删除获取文件夹中的文件列表等等,非常的方便。

 

下面我们通过一些例子来学习File类的使用:

1.      创建和删除

//a.txt封装成对象,a.txt可以是文件或者文件夹

File f= new File("a.txt");

//在指定位置创建文件,若果已经存在,则不创建,返回false,创建成功返回true

boolean b = f.createNewFile();

boolean mkdir():创建文件夹,但是只能创建一级的文件夹

boolean mkdirs():可以创建多级文件夹

boolean delete():删除文件,删除失败返回false

void deleteOnExit():在程序退出时删除指定文件

 

2.      判断

boolean exits():判断文件是否存在

booleanisFile():判断是否是文件

booleanisDirectory():判断是否是文件夹

booleanisHidden():判断文件是否是隐藏文件

booleanisAbsolute():判断文件的路径是否为绝对路径


3.      获取信息

getName():获取信息

getPath():获取路径

getAbsolutePath():获取绝对路径

getParent():获取父目录

long lastModified():获取上次修改时间

long lenth():获取文件的长度

4.      练习:文件列表

/**
	 * 打印出文件列表,包括子文件夹下
	 * @param path
	 * @param i
	 */
	public static void listAll(String path,int i){
		i++;
		File dir = new File(path);
		File[] files = dir.listFiles();
		for(File f:files){
			System.out.println(space(i)+f.getName());
			if(f.isDirectory()){
				listAll(f.getAbsolutePath(),i);
			}
		}
	}

	/**
	 * 提供空格或分割字符,来让文件或文件夹显示层级
	 * @param i
	 * @return
	 */
	public static String space(int i){
		StringBuilder sb = new StringBuilder();
		for(int j=0;j
   
   

5.练习:复制一个文件夹下的内容到另一个文件夹下

/**
	 * 把oldPath目录下的文件和文件夹复制到newPath目录下
	 * @param oldPath
	 * @param newPath
	 * @throws IOException
	 */
	public static void copyDir(String oldPath,String newPath) throws IOException{
		//先判断路径是不是带分隔符,如果没有就加上
		if(!newPath.endsWith(File.separator)){
			newPath = newPath+File.separator;
		}
		//将文件或文件夹封装成File对象
		File oldDir = new File(oldPath);
		File newDir;
		
		//当前文件夹下的列表
		File[] files = oldDir.listFiles();
		for(File f:files){
			if(f.isDirectory()){
				//如果是文件夹,递归
				String dirName = f.getName();
				newDir = new File(newPath+f.getName());
				newDir.mkdirs();
				copyDir(f.getAbsolutePath(),newDir.getAbsolutePath());
			}
			if(f.isFile()){
				//如果是文件,则复制到新的文件夹下
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newPath+f.getName()));
				byte[] buf = new byte[1024];
				int len = 0;
				while((len=bis.read(buf))!=-1){
					bos.write(buf, 0, len);
					bos.flush();
				}
				bos.close();
				bis.close();
			}
		}
	}

二、Properties

Properties是hashtable的子类。

它具备了map集合的特点。它里面存储的是键值对。

它是集合中和IO相结合的集合容器。

该对象的特点:可以用于存取键值对形式的配置文件。

//输入流关联配置文件,配置文件后缀名必须是properties
InputStream is = new FileInputStream("config.properties");
Properties pp = new Properties();
//加载流中的信息
pp.load(is);
//获取配置文件中的属性
String name = (String) pp.get("name");
System.out.println(name);
		
//修改配置文件中的内容
OutputStream os = new FileOutputStream("config.properties");
//如果有sex这个键,则修改,如果没有,就创建sex=man这个键值对
pp.setProperty("sex", "man");
//把内存中修改的内同存到文件里面
pp.store(os, null);

三、打印流

该流提供了打印的方法,可以将各种数据类型的数据都原样打印。

 

字节打印流:PrintStream

构造函数可以接收的参数类型:

1.File对象。File

2.字符串路径。String

3.字节输出流。OutputStream

 

字符打印流:PrintWriter

构造函数可以接收的参数类型

1.File对象。File

2.字符串路径。String

3.字节输出流。OutputStream

4.字符输出流。Writer

 

PrintWriter接收的参数类型更多。所以,我们一般使用PrintWriter

Scanner scanner = new Scanner(System.in);

String line = scanner.next();

     

PrintWriter out = newPrintWriter(System.out,true);

out.println(line);

四、SequenceInputStream

SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

通俗的说就是把多个流对象封装到一个流对象里。

示例代码:三个读取流读取1.txt、2.txt和3.txt中的内容写到4.txt中

public static void main(String[] args) throws IOException {
		//用Vector集合是为了用他的遍历方式,枚举
		Vector
    
    
     
      v = new Vector
     
     
      
      ();
		v.add(new FileInputStream("f:\\1.txt"));
		v.add(new FileInputStream("f:\\2.txt"));
		v.add(new FileInputStream("f:\\3.txt"));
		//获得vector集合中的所有元素,并封装到枚举里
		Enumeration en = v.elements();
		
		SequenceInputStream sis = new SequenceInputStream(en);
		
		FileOutputStream fos = new FileOutputStream("f:\\4.txt");
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=sis.read(buf))!=-1){
			fos.write(buf,0,len);
			fos.flush();
		}
		fos.close();
		sis.close();
	}

     
     
    
    

小练习:将一个mp3文件按1M切割。切割后再将其还原(合并成一个)

/**
	 * 将一个文件按1M切割
	 * @param f
	 * @throws IOException
	 */
	public static void splitFile(File f) throws IOException{
		FileInputStream fis = new FileInputStream(f);
		FileOutputStream fos = null;
		byte[] buf = new byte[1024*1024];
		int len = 0;
		int count = 1;
		while((len = fis.read(buf))!=-1){
			fos = new FileOutputStream("f:\\gj\\"+(count++)+".part");
			fos.write(buf, 0, len);
			fos.close();
		}
		fis.close();
	}

/**
	 * 将刚才切割的文件合并成一个
	 * @throws IOException 
	 */
	public static void megeFile() throws IOException{
		Vector
    
    
     
      v = new Vector
     
     
      
      ();
		for(int i=1;i<=5;i++){
			v.add(new FileInputStream("f:\\gj\\"+i+".part"));
		}
		
		Enumeration en = v.elements();
		SequenceInputStream sis = new SequenceInputStream(en);
		FileOutputStream fos = new FileOutputStream("f:\\gj\\gj.mp3");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len=sis.read(buf))!=-1){
			fos.write(buf,0,len);
			fos.flush();
		}
		fos.close();
		sis.close();
	}

     
     
    
    

五、PipedInputStream和PipedOutputStream

管道输入流和管道输出流,IO中和多线程相结合的流

public class PisPos {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//管道输入流
		PipedInputStream in = new PipedInputStream();
		//管道输出流
		PipedOutputStream out = new PipedOutputStream();
		//将管道输出和输入流连接起来
		in.connect(out);
		//定义两个Runnable接口的实现类才操作流
		Reader r = new Reader(in);
		Write w = new Write(out);
		new Thread(r).start();
		new Thread(w).start();
	}

}
/**
 * 负责操作管道输出流
 * @author snn
 *
 */
class Write implements Runnable{
	private PipedOutputStream out;
	
	public Write(PipedOutputStream out) {
		super();
		this.out = out;
	}

	@Override
	public void run() {
		try {
			out.write("chi le ma ,shi jie ".getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(out!=null)
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	
}
/**
 * 操作管道输入流
 * @author snn
 *
 */
class Reader implements Runnable{
	private PipedInputStream in;
	
	public Reader(PipedInputStream in) {
		super();
		this.in = in;
	}

	@Override
	public void run() {
		try {
			byte[] buf = new byte[1024];
			int len = 0;
			while((len=in.read(buf))!=-1){
				System.out.println(new String(buf,0,len));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(in!=null)
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
}

六、RandomAccessFile

1.简介

该类不是IO体系中的子类,而是直接继承自Object


但是它是IO包中的成员,因为它具备读和写的功能

内部封装了一个数组,而且通过指针对数组的元素进行操作

可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置


其实完成读写的原理就是内部封装了字节输入流和输出流。


通过构造函数可以看出,该类只能操作文件。

而且操作文件还有模式:只读r,读写rw等


如果模式为只读r,不会创建文件,回去读取一个已存在的文件,如果该文件不存在,则会出异常

如果模式为读写rw,操作的文件不存在,会自动创建,如果存在则会被覆盖。

2.写方法

/**
	 * 演示RandomAccessFile写入文件
	 * @throws IOException
	 */
	public static void writeFile() throws IOException{
		RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");
		raf.writeChar(98);
		raf.writeInt(97);
		raf.writeLong(8L);
		raf.writeChars("world");
		raf.close();
	}

3.读方法

public static void readFile() throws IOException{
		RandomAccessFile raf = new RandomAccessFile("ran.txt", "rw");
//		int read = raf.readChar();
//		System.out.println(read);
		raf.seek(2);//可以调整指针的位置
		int i = raf.readInt();
		System.out.println(i);
	}

七、DataInputStream和DataOutputStrea

操作基本数据类型的流对象

1. 写入

/**
	 * 基本的写方法
	 * @throws IOException
	 */
	public static void writeData() throws IOException{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
		dos.writeInt(98);
		dos.writeBoolean(true);
		dos.writeLong(9L);
		dos.close();
	}

2.读出

/**
	 * 基本的读方法
	 * @throws IOException
	 */
	public static void readData() throws IOException{
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
		int i = dis.readInt();
		boolean b = dis.readBoolean();
		long l = dis.readLong();
		System.out.println(i);
		System.out.println(b);
		System.out.println(l);
		dis.close();		
	}

3.writeUTF()和readUTF()

以UTF-8的编码写入,这个方法需要特定的读取方法,因为这个UTF-8不同于普通的UTF-8,以普通的方式读取会出错。

/**
	 * 读取以UTF方式写入的数据
	 * @throws IOException
	 */
	public static void readUTF() throws IOException{
		DataInputStream dis = new DataInputStream(new FileInputStream("utfdata.txt"));
		String str = dis.readUTF();
		System.out.println(str);
		dis.close();
	}
	
	/**
	 * 以UTF的方式写入,必须用UTF的方式读出,不能用普通的方法
	 * @throws IOException
	 */
	public static void writeUTF() throws IOException{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdata.txt"));
		dos.writeUTF("hello world!");
		dos.close();
	}

八、ByteArrayStream

用于操作字节数组的流对象。

ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。

ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经封装了一个可变长度的字节数组,这就是数据目的地。

因为这两个流对象都操作数组,并没有使用系统资源。所以,不用进行close关闭。

public static void byteArrayStreamDemo(){
		ByteArrayInputStream bis = new ByteArrayInputStream("hello".getBytes());
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int len = 0;
		while((len=bis.read())!=-1){
			bos.write(len);
		}
		System.out.println(bos.size());
		System.out.println(bos.toString());
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值