黑马程序员——Java基础—IO流(File)


Java基础之IO流



File类

文件和目录路径名的抽象表示形式。用来将文件或者文件夹封装成对象。方便对文件或文件夹的属性信息进行操作。

File对象可以作为参数传递给流的构造函数。流只能操作数据,而File对象可以操作文件或文件夹的属性信息。

示例:File f = new File("a.txt");将a.txt封装成File对象,可以将已存在的和未存在的文件或文件夹封装成对象。

String separator:该字段是一个跨平台的分割符,返回一个字符串类型。示例:String s = File.separator;

File类常见方法:

1.创建: 

boolean createNewFile():在指定位置创建文件,如果该文件已经存在则不创建,返回创建false。该方法和输出流不

同,输出流对象一建立就创建文件,并且文件已存在会被覆盖。

boolean mkdir():创建一级文件夹。 boolean mkdirs():创建多级文件夹。

2.删除:

boolean delete():删除指定的文件或目录。如果删除失败则返回false。 

void deleteOnExit():在程序退出时删除指定的文件,在虚拟机终止时删除指定的文件或目录。

3.判断:

boolean canExecute():判断该文件对象是否可以执行。

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

boolean isFile():判断指定的文件对象是否是文件。 

boolean isDirectory():判断指定的文件对象是否是目录。

boolean isHidden():判断指定的文件对象是否是隐藏文件。

boolean isAbsolute():判断指定的文件对象是否是绝对路径 ,该方法可以判断不存在的文件。

注意:在判断文件对象是否为文件或者目录时,要先通过exists方法判断该文件对象封装的内容是否存在。

4.获取信息:

String getName():获取名称。

String getPath():获取路径名称,如果该文件对象是绝对路径就返回绝对路径,如果不是绝对路径就返回非绝对路径。

String getParent():获取该文件对象的父路径名称,如果此文件对象没有指定父目录,则返回null 。

String getAbsolutePath():获取该文件对象的绝对路径名称。 

long lastModified():返回该文件对象最后一次被修改的时间的long值,以毫秒为单位。

long length():获取该文件对象的大小(长度),以字节为单位。 

boolean renameTo(File dest):重新命名此抽象路径名表示的文件。

示例:f1.renameTo(f2):将f1的文件名改成f2的文件名。代码演示:

import java.io.*;
class  FileDemo1
{
	public static void main(String[] args) throws IOException
	{
		File f = new File("FileDemo1.java");
		sop(f.createNewFile()); //在指定位置创建文件
		sop(f.delete());  //删除指定的文件或目录。
		f.deleteOnExit();  //在程序退出时删除指定的文件,在虚拟机终止时删除指定的文件或目录

		sop(f.mkdirs());  //创建多级文件夹
		sop(f.canExecute());  //判断该文件对象是否可以执行
		sop(f.exists());  //判断文件是否存在。
		sop(f.isFile());  //判断指定的文件对象是否是文件
		sop(f.isDirectory());  //判断指定的文件对象是否是目录
		sop(f.isHidden());  //判断指定的文件对象是否是隐藏文件
		sop(f.isAbsolute());  //判断指定的文件对象是否是绝对的

		sop(f.getPath());  //获取路径名称
		sop(f.getParent());  //获取该文件对象的父路径名称
		sop(f.getAbsolutePath());  //获取该文件对象的绝对路径名称
		sop(f.lastModified());  //返回该文件对象最后一次被修改的时间
		sop(f.length());  //获取该文件对象的大小(长度)
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

File[] listRoots():列出可用的文件系统根目录,也就是说列出电脑中有效的盘符。返回的是一个File[],File[] 

files = File.listRoots(); 代码示例:

import java.io.*;
class  FileDemo2
{
	public static void main(String[] args) 
	{
		File[] files = File.listRoots();
		for(File f : files) //列出电脑中有效的盘符
		{
			System.out.println(f);
		}

		File f = new File("D:\\java2014");
		String[] names = f.list();
		for(String s : names)
		{
			System.out.println(s);
		}
	}
}

String[] list():返回的是指定的目录下的文件和文件夹的名称,包括隐藏的文件。 

示例:File f = new File("D:\\java2014"); String[] names = f.list() 。

需要注意:调用list方法的File对象必须封装了一个存在的目录。

File[] listFiles():返回的是指定的目录下的文件和文件夹的对象数组 ,包含隐藏的文件。

示例:File f = new File("D:\\java2014");File[] file = f.listFiles()。

该方法返回的是File[],File[]中存放的是File对象,方便于对File对象的操作,因此建议开发用此方法。

/*
需求:列出指定目录下的文件或者文件夹,包含子目录中的内容。也就是该目录中的所有的文件。
*/
import java.io.*;
class  FileDemo3
{
	public static void main(String[] args) 
	{
		
		File dir = new File("d:\\java2014");
		showDir(dir);
		
		//System.out.println(getSum(1000));
	}
	public static void showDir(File dir)
	{
		System.out.println(dir);

		File[] files = dir.listFiles();

		for(int x =0; x<files.length; x++)
		{
			if(files[x].isDirectory())  //判断是否是文件夹,如果是,那么继续递归
				showDir(files[x]);
			else
				System.out.println(files[x]);
		}
	}
}

String[] list(FilenameFilter filter):传入一个FilenameFilter对象,该对象要实现FilenameFilter接口,并且要覆

盖boolean accept(File dir,String name) 方法,该方法测试指定的文件名是否包含在指定的目录中。

如果包含在目录中则返回true,否则返回false。方法中的内容可以定义为return name.endsWith(".java") 。

可以不传FilenameFilter对象,最好是传入一个匿名内部类。

递归:函数自己调用自己。应用场景:当某一功能要重复使用时。

注意:递归时一定要明确结束条件。要注意递归的次数,尽量避免内存溢出。代码示例:

/*
练习:将一个指定目录下的java文件的绝对路径存储到一个文本文件中。
思路:
1.对指定的目录进行递归。
2.获取递归过程中所有的java文件的绝对路径。
3.将java文件存储到集合中。
4.将集合中的数据写入到一个文本文件中。
*/
import java.io.*;
import java.util.*;
class  JavaFileList
{
	public static void main(String[] args) 
	{
		File dir = new File("d:\\java2014");

		List<File> list = new ArrayList<File>();

		fileToList(dir,list);
		//System.out.println(list.size());

		File file = new File("d:\\java2014\\JavaFileList.txt");
		writeToFile(list,file);
	}
	public static void fileToList(File dir,List<File> list)
	{
		File[] files = dir.listFiles();

		for(File f : files)
		{
			if(f.isDirectory())
				fileToList(f,list);
			else
			{
				if(f.getName().endsWith(".java"))
					list.add(f);
			}
		}
	}
	public static void writeToFile(List<File> list,File file)
	{
		BufferedWriter bufw = null;
		try
		{
			bufw = new BufferedWriter(new FileWriter(file));

			for(File f : list)
			{
				String path = f.getAbsolutePath();
				
				bufw.write(path);
				bufw.newLine();
				bufw.flush();
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("数据写入失败");
		}
		finally
		{
			try
			{
				if(bufw!=null)
					bufw.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("流资源关闭失败");
			}
		}
	}
}

Properties:

Properties是Hashtable的子类,也就是Map集合的一个子类对象,所以可以通过Map集合的方法取出该集合中的元素。

迭代Properties集合获取键和值,获取所有的属性信息。该集合中存储的都是字符串,没有泛型定义。

是集合与IO技术相结合的集合容器。可以用于键值对形式的配置文件,并且可以将属性信息存储到硬盘上。

数据的固定格式是:键=值 。

setProperty(key,value):设置属性信息。

String getProperty(key):通过键获取值。 

Set<String>  stringPropertyNames():获取此属性列表中的键集,其中该键及其对应值是字符串。

代码示例:

class Demo
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = new Properties();
		
		prop.setProperty("zhangsan","22");
		prop.setProperty("lisi","25");

		String value = prop.getProperty("lisi");

		//prop.list(System.out);
		Set<String> set = prop.stringPropertyNames();

		for(String key : set)
		{
			System.out.println(key+":"+prop.getProperty(key));
		}
	}
}

load(InputStream inStream):从输入流中读取属性列表(键和元素对)。

示例:prop.load(new FileInputStream("Info.txt")),将流中的数据加载进Properties集合。

load(Reader reader):示例:prop.load(new FileInputStream("Info.txt")),将流中的数据加载进Properties集合。

list(PrintStream out)和list(PrintWriter out) :将属性列表输出到指定的输出流。示例:prop.list(System.out),

打印集合中元素。

store(OutputStream out, String comments):将此Properties集合中的属性列表(键和元素对)写入输出流。

示例:FileOutputStream fos = new FileOutputStream("Info.txt");  prop.store(fos,"注释信息"); 

代码示例:

import java.io.*;
import java.util.*;
/*
需求:将流中的数据存储到集合中,将info.txt中的数据存入到Properties集合中。
思路:1.用一个流和文件相关联。2.读取一行数据,用"="进行切割。3.将"="左边作为键,右边作为值,
存储到集合中即可。
*/
class Test
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
		
		Properties prop = new Properties();
		
		prop.load(bufr);  //将流中的数据加载进集合。

		prop.setProperty("lisi","30");

		BufferedWriter bufw = new BufferedWriter(new FileWriter("info.txt"));

		prop.store(bufw,"amen");  //将集合中的数据加载到流中。

		/*
		for(String line=null; (line=bufr.readLine())!=null;  )
		{
			String[] arr = line.split("=");
			
			prop.setProperty(arr[0],arr[1]);
		}
		*/

		prop.list(System.out);  //打印属性列表。

		bufr.close();
		bufw.close();
	}
}

打印流(PrintStream、PrintWriter):提供了打印方法,可以将各种数据类型的数据都原样的打印。

字节打印流:PrintStream

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

1.file对象:File 。2.字符串路径:String 。3.字节输出流:OutputStream 。

字符打印流:PrintWriter

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

1.file对象:File 。2.字符串路径:String 。 3.字节输出流:OutputStream 。4.字符输出流:Writer 

PrintWriter(OutputStream out, boolean autoFlush):如果为 true,则 println、printf或format方法将刷新输出缓冲

区。自动刷新。

序列流:SequenceInputStream ,将多个读取流合并成一个读取流。

Vector<FileInputStream> v = new Vector<FileInputStream>();v.add(new FileInputStream("f:\\1.txt"));

v.add(new FileInputStream("f:\\2.txt"));Enumeration<FileInputStream> en = v.elements();SequenceInputStream

 sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("f:\\4.txt"); 代码示例:

class Test
{
	public static void main(String[] args) throws IOException
	{
		//创建一个Vector集合
		Vector<FileInputStream> v = new Vector<FileInputStream>();

		v.add(new FileInputStream("1.txt")); //将流对象存储到Vector集合中。
		v.add(new FileInputStream("2.txt"));
		v.add(new FileInputStream("3.txt"));
		v.add(new FileInputStream("4.txt"));

		Enumeration<FileInputStream> en = v.elements(); //获取集合的迭代器
		
		//创建合并流对象,接收一个枚举。
		SequenceInputStream sis = new SequenceInputStream(en);

		PrintWriter out = new PrintWriter(System.out);

		for(int by=0; (by=sis.read())!=-1;  )
		{
			out.print((char)by);
		}
		sis.close();
		out.close();
	}
}

切割文件:day16\SplitFile.java 。第20天-17。

对象的序列化:操作对象。ObjectInputStream与ObjectOutputStream 。被操作的对象需要实现Serializable (标记接口)。
管道流:PipedInputStream和PipedOutputStream 。输入输出可以直接进行连接,通过结合线程使用。


RandomAccessFile 类:随机访问文件,自身具备读写的方法。通过skipBytes(int x),seek(int x)来达到随机访问。随机存取文件的行为类似存储在文件系统中的一个大型字节数组。该类直接继承Object类,但它是IO包中成员,因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer方法获取指针位置,同时可以通过seek方法改变指针的位置。该类完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出该类只能操作文件,而且操作文件还有模式:只读r ,读写rw 等模式。如果为只读模式r,不会创建文件,会去读取一个已经存在的文件,如果该文件不存在,则会出现异常。如果模式为rw,若操作的文件不存在,会自动创建文件,如果存在则不会覆盖。该类要掌握的特点:1.有模式r、rw,2.可以直接读取或写入基本数据类型:readInt()、writeInt() 。3.可以通过seek方法改变指针的位置,来进行指定的数据读取和写入。


DataInputStream与DataOutputStream:用于操作基本数据类型的流对象。凡是操作基本数据类型就用它。
DataOutputStream:构造函数:DataOutputStream(OutputStream out)。写的方法:writeBoolean(boolean v)、writeDouble(double v)、writeInt(int v) 。示例:DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); dos.writeBoolean(true); dos.writeDouble(35.45);dos.writeInt(99); 
DataInputStream:构造函数:DataInputStream(InputStream in)。读的方法:readBoolean() 、readDouble()、readInt()。怎么写入的就怎么读取出来顺序不能错误,否则会出现乱码情况。


ByteArrayInputStream与ByteArrayOutputStream :用于操作字节数组的流对象。
ByteArrayInputStream :在构造的时候需要接收数据源,并且数据源是一个字节数组。ByteArrayOutputStream :在构造的时候不用定义数据目的,因为该对象内部已封装了可变长度的字节数组,这就是数据目的地。
这两个流对象操作的都是数组,并没有使用系统资源,所以不用关闭流资源操作。 源设备:内存 ArrayStream、硬盘 FileStream、键盘 System.in。 目的设备:内存 ArrayStream、硬盘 FileStream、控制台 System.out 。
用流的读写思想来操作数组:设置(set)数组是写-->>OutputStream,获取(遍历)数组是读-->>InputStream 。


CharArrayReader与CharArrayWriter :操作字符数组的流对象。 StringReader与StringWriter :操作字符串的流对象。


字符编码
字符流的出现不但为了方便操作字符,更重要的是加入了编码转换。通过转换流:InputStreamReader和OutputStreamWriter来完成编码转换,这两个对象进行构造的时候可以加入字符集。
编码表的由来:计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表。
转换流的编码应用:可以将字符以指定编码格式存储。可以对文本数据指定编码格式来解读。指定编码表的动作由构造函数完成。
编码:字符串-->>字节数组:通过String类的byte[] getBytes()方法,该方法里面可以传递一个字符集,表示按着什么编码表进行编码,
byte[] getBytes(String charsetName)。示例:byte[] by = str.getBytes(); byte[] by = str.getBytes("UTF-8");
解码:字节数组-->>字符串:通过String的构造函数:new String(byte[] buf),构造函数里面也可以传递一个字符集,表示按着什么编码表进行解码,new String(byte[] by,String charsetName)。示例:String st = new String(byte[],"GBK")   。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值