io流--下

File类
File概述:
用来将文件或者文件夹封装成对象
方便对文件与文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数。

File类常见方法:

1,创建。

boolean createNewFile():
创建文件并判断是否创建成功
在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立创建文件。而且如果文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。

2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。

3,判断。
boolean exists() :文件是否存在.
isFile():测试此抽象路径名表示的文件是否是一个标准文件。
isDirectory();测试此抽象路径名表示的文件是否是一个目录。
isHidden();测试此抽象路径名指定的文件是否是一个隐藏文件。
isAbsolute();测试此抽象路径名是否为绝对路径名。

4,获取信息。
getName():返回由此抽象路径名表示的文件或目录的名称。
getPath():获取路径
getParent():返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。

getAbsolutePath()  返回此抽象路径名的绝对路径名字符串。
long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。
long length()  返回由此抽象路径名表示的文件的长度。

代码示例:
/**
File方法演示
*/
import java.io.*;
class CreateFile 
{
	public static void main(String[] args) throws IOException
	{
		File f = new File("f:\\java\\day11\\123.txt");
		//创建文件并判断是否创建成功
		sop("Create:"+f.createNewFile());
		//判断文件是否存在
		sop("cunzai:"+f.exists());
		//判断文件是否是标准文件
		sop("file:"+f.isFile());
		//判断该路径是否为目录路径
		sop("dir:"+f.isDirectory());
		//获取文件名称
		sop("name:"+f.getName());
		//获取路径名称
		sop("路径名称"+f.getPath());
		//获取父目录
		sop("父目录"+f.getParent());
		//获取绝对路径
		sop("绝对路径"+f.getAbsolutePath());
		//获取最后一次修改的时间
		sop("修改时间"+f.lastModified());
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
结果:


文件列表

列表方法:
 String[] list() 
          返回一个字符串数组,获取指定File对象路径中的目录名和文件名 
 String[] list(FilenameFilter filter) 
          返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。 
 File[] listFiles() 
          返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 
 File[] listFiles(FileFilter filter) 
          返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的目录。 
 File[] listFiles(FilenameFilter filter) 
          返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。 
static File[] listRoots() 
          列出可用的文件系统根。 (C盘,D盘)

list()方法和listFiles()方法的区别:
list()方法返回的是目录名和文件名
listFiles()方法返回的是文件对象,文件对象可以调用getName()方法来获取文件名,开发中通常是用此方法

代码示例:
/**
获取目录下的.txt文件
*/
import java.io.*;
class FilenameFilterDemo 
{
	public static void main(String[] args) throws IOException
	{
		File f = new File("f:\\java\\day10");
		//匿名内部类来复写父类中的accept()方法-->过滤器
		File [] files = f.listFiles(new FilenameFilter()
			{
				public boolean accept(File f,String file)
				{
					return file.endsWith(".txt");
				}
			}
		);
		for(File file : files)
		{
			System.out.println(file);
		}
	}
}


递归: 就是函数自身调用自身。
什么时候用递归呢?
当一个功能被重复使用,而每一次使用该功能时的参数不确定,都由上次的功能元素结果来确定。
简单说:功能内部又用到该功能,但是传递的参数值不确定。(每次功能参与运算的未知内容不确定)。

递归的注意事项:
1:一定要定义递归的条件。
2:递归的次数不要过多。容易出现栈内存溢出错误。
其实递归就是在栈内存中不断的加载同一个函数。

代码示例:
/**
列出目录中的所有目录和文件
分析:
判断指定目录下是否有文件和文件夹
如果有文件夹则判断文件夹内是否还有文件夹,如果有重复以上动作,否则遍历文件
步骤:
1,创建File对象,指定要查询的目录
2,遍历目录中的内容
	2.1 如果是文件直接输出
	2.2 如果是文件夹继续遍历目录(递归)
*/
import java.io.*;
class Methord 
{
	public static void main(String[] args) throws IOException
	{
		File f = new File("f:\\java");
		methord(f);
	}
	public static void methord(File f)
	{
		File[] names = f.listFiles();
		for (int a = 0;a <names.length ; a++ )
		{
			if (names[a].isDirectory())
			{
				//递归方法,方法内调用自身方法
				methord(names[a]);
			}else
				System.out.println(names[a]);
		}
	}
}

java.util.Properties

Properties概述
Properties 是HashTable的子类,Properties是hashtable的子类。
它具备map集合的特点。而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载数据时,需要数据有固定格式:键=值。
Properties特点
1:可以持久化存储数据。2:键值都是字符串。3:一般用于配置文件。

Properties常用的方法:
 String getProperty(String key) 
          获取键所对应的值
 String getProperty(String key, String defaultValue) 
          用指定的键在属性列表中搜索属性。 
 void list(PrintStream out) 
          将属性列表输出到指定的输出流。 
 void list(PrintWriter out) 
          将属性列表输出到指定的输出流。 
 void load(InputStream inStream) 
          从输入流中读取属性列表(键和元素对)。 
 void load(Reader reader) 
          按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 
 void store(OutputStream out, String comments) 
          以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 
 void store(Writer writer, String comments) 
          以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。 
 Set<String> stringPropertyNames() 
          返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。 

Properties应用:
常用于配置文件

IO包中的其他类

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

字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream

字符打印流:(常用字符打印流)
PrintWriter
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流,Writer。

打印流应用:
用于简化输出流的书写,增强了输出流的功能

代码示例:
import java.io.*;

class  PrintStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));
		//直接定义一个打印流对象
		PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());
		}
		out.close();
		bufr.close();
	}	
}

合并流
SquenceInputStream
该流用于将多个文件写入流中,并将流存入Vector集合中,组合输出成一个流文件。

构造方法:
SequenceInputStream(Enumeration<? extendsInputStream> e)
          通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的Enumeration 型参数。
SequenceInputStream(InputStream s1,InputStream s2)
          通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。

代码示例:
import java.io.*;
import java.util.*;
class SequenceDemo 
{
	public static void main(String[] args) throws IOException
	{

		Vector<FileInputStream> v = new Vector<FileInputStream>();

		
		v.add(new FileInputStream("c:\\1.txt"));
		v.add(new FileInputStream("c:\\2.txt"));
		v.add(new FileInputStream("c:\\3.txt"));

		Enumeration<FileInputStream> en = v.elements();

		SequenceInputStream sis = new SequenceInputStream(en);

		FileOutputStream fos = new FileOutputStream("c:\\4.txt");

		byte[] buf = new byte[1024];

		int len =0;
		while((len=sis.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
}

切割文件
应用:上传文件时,限定了上传文件的大小,那么要想上传需要将文件进行切割成符合限定的大小文件

代码示例:
import java.io.*;
import java.util.*;

class SplitFile 
{
	public static void main(String[] args) throws IOException
	{
		splitFile();
	}
	public static void splitFile()throws IOException
	{
		FileInputStream fis =  new FileInputStream("c:\\1.bmp");

		FileOutputStream fos = null;


		byte[] buf = new byte[1024*1024];

		int len = 0;
		int count = 1;
		while((len=fis.read(buf))!=-1)
		{
			fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}
		
		fis.close();
		
	}
}

合并原理:多个读取流对应一个输出流。
切割原理:一个读取流对应多个输出流。


对象的序列化

对象的序列化:将一个具体的对象进行持久化,写入到硬盘上。

注意:静态数据不能被序列化,因为静态数据不在堆内存中,是存储在静态方法区中。

如何将非静态的数据不进行序列化?
用transient 关键字修饰此变量即可。


Serializable:用于启动对象的序列化功能,可以强制让指定类具备序列化功能,该接口中没有成员,这是一个标记接口。这个标记接口用于给序列化类提供UID。这个uid是依据类中的成员的数字签名进行运行获取的。如果不需要自动获取一个uid,可以在类中,手动指定一个名称为serialVersionUID id号。依据编译器的不同,或者对信息的高度敏感性。最好每一个序列化的类都进行手动显示的UID的指定。

代码示例:
import java.io.*;
class ObjectStreamDemo {
	public static void main(String[] args) throws Exception{
		writeObj();
		readObj();
	}
	public static void readObj()throws Exception{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
		Object obj = ois.readObject();//读取一个对象。
		System.out.println(obj.toString());
	}
	public static void writeObj()throws IOException{
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
		oos.writeObject(new Person("lisi",25)); //写入一个对象。
		oos.close();
	}
}
class Person implements Serializable{
	private static final long serialVersionUID = 42L;
	private transient String name;//用transient修饰后name将不会进行序列化
	public int age;
	Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	public String toString(){
		return name+"::"+age;
	}
}

管道流
多线程技术和IO流相结合的类
管道读取流和管道写入流可以像管道一样对接上,管道读取流就可以读取管道写入流写入的数据。
将不同的流,连接成一条流
PipedInputStream
PipedOutputStream

PipedReader
PipedWriter

注意:加入多线程技术,是因为在单线程中,先执行read,会发生死锁,read方法是阻塞式的,没有数据的read方法会让线程等待。
public static void main(String[] args) throws IOException{
	PipedInputStream pipin = new PipedInputStream();
	PipedOutputStream pipout = new PipedOutputStream();
	pipin.connect(pipout);
	new Thread(new Input(pipin)).start();
	new Thread(new Output(pipout)).start();
}

RandomAccessFile


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

RandomAccessFile的特点
1:该对象即可读取,又可写入。
2:该对象中的定义了一个大型的byte数组,通过定义指针来操作这个数组。
3:可以通过该对象的getFilePointer()获取指针的位置,通过seek()方法设置指针的位置。
4:该对象操作的源和目的必须是文件。 
5:其实该对象内部封装了字节读取流和字节写入流。


其实完成读写的原理就是内部封装了字节输入流和输出流
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,,读写rw等。


如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

指定位置读取数据的两种方式:
1,调整对象中指针
 void seek(long pos) 
          设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 
2,跳过指定的字节数
int skipBytes(int n) 
          尝试跳过输入的 n 个字节以丢弃跳过的字节。 

DataOutputStream、DataInputStream
DataOutputStream、DataInputStream:专门用于操作基本数据类型数据的对象。
DataOutputStream dos =  new DataOutputStream(new FileOutputStream("data.txt"));
	dos.writeInt(256);
	dos.close();


	DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
	int num = dis.readInt();
	System.out.println(num);
	dis.close();

ByteArrayInputStream ByteArrayOutputStream

用于操作字节数组的流对象。
ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。

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

用流的读写思想来操作数据。

代码示例:
import java.io.*;
class ByteArrayStream 
{
	public static void main(String[] args) 
	{
		//数据源。起始的时候就要有数组
		ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());

		//数据目的,就是内存(数组)
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		int by = 0;

		while((by=bis.read())!=-1)
		{
			bos.write(by);
		}



		System.out.println(bos.size());
		System.out.println(bos.toString());

字符编码

字符流的出现为了方便操作字符。
更重要是的加入了编码转换。
通过子类转换流来完成。
InputStreamReader
OutputStreamWriter
在两个对象进行构造的时候可以加入字符集

Unicode:国际标准码,融合了多种文字。
所有文字都用两个字节来表示,Java语言使用的就是unicode

编码:字符串变成字节数组。String-->byte[];  str.getBytes(charsetName);

解码:字节数组变成字符串。byte[] -->String: new String(byte[],charsetName);

编码解码过程图:



字符编码__联通问题总结:

联通的二进制编码的形式正好符合了utf-8的编码形式,记事本就去utf-8编码表去找对应的字符,于是就出现了这样的情况
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值