java基础-IO-File类、Properties类、打印流、序列流、字符编码
2015-08-28 11:23
766 查看
一、File类
1、概述
File类:文件和目录路径名的抽象表现形式
特点:
a、用来将文件或文件夹封装成对象
b、方便于对文件与文件夹的属性信息进行操作
c、File对象可以作为参数传递给流的构造函数
File对象创建:
方式一:File f =new File("a.txt");
将a.txt封装成File对象。可以将已有的和不存在的文件或者文件夹封装成对象。
方式二:File f2=newFile("c:\\abc","b.txt");
将文件所在目录路径和文件一起传入,指定文件路径。
方式三:File d=new File("c:\\abc");
File f3=new File(d,"c.txt");
将文件目录路径封装成对象。再创建文件对象。降低了文件与父目录的关联性。
File.separator表示目录分隔符,可以跨平台使用。
2、常见方法。
a、创建
boolean createNewFile(); //在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立就创建文件。而且文件已经存在,会覆盖。
boolean mkdir();//创建文件夹,只能创建一级文件夹
boolean mkdirs();//创建多级文件夹
b、删除
boolean delete(); //删除文件或目录。文件存在,返回true;文件不存在或者正在被执行,返回false。
void deleteOnExit();//在程序退出时删除指定文件
c、判断
boolean canExecute();//是否是可执行文件
boolean exists();//文件是否存在
boolean isFile();//是否是文件
boolean isDirectory();//是否是文件夹
boolean isHidden();//是否是隐藏文件
boolean isAbsolute();//文件是否是绝对路径
记住:在判断文件对象是否是文件或者目录时,必须要判断该文件对象封装的内容是否存在。通过exists判断。
d、获取信息
String getName();//获取文件名
String getPath(); //获取文件的相对路径(即创建的对象传入的参数是什么就获取到什么)
String getParent(); //获取文件父目录。返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。如果相对路径中有上一层目录,那么该目录就是返回结果。
String getAbsolutePath();//获取文件的绝对路径
long lastModified();//返回文件最后一次被修改的时间
long length();//返回文件长度
boolean renameTo(File dest):重命名
e、列出文件及文件过滤
static File[] listRoots();//列出可用的文件系统根目录,即系统盘符
String[] list();
//列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
String[]list(FilenameFilter filter);
//返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。
FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(Filedir,String name),返回的是boolean型,对不符合条件的文件过滤掉。
File[] listFiles();//返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹
File[] ListFiles(FilenameFilterfilter);//返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。
代码示例:
3、递归
递归:
1,限定条件
2,要注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法,所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。
例:列出指定目录下文件或文件夹,包含子目录中的内容。
例:删除一个带内容的目录。
例:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。建立一个java文件列表清单。
二、Properties类
1、概述
Properties是Hashtable的子类,它具备Map集合的特点。而且它里面 存储的键值对都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。
特点:
1)可用于键值对形式的配置文件
2)在加载时,需要数据有固定的格式,常用的是:键=值
2、特有方法
1、设置
Object setProperty(String key,String value);//设置键和值
2、获取
String getProperty(String key); //指定key获取value
Set<String> stringPropertyName();//返回属性列表的键集,存入Set集合
3、加载流和存入流
void load(InputStream instream); //将字节流中的数据加载进集合。
void store(OutputStreamout,String comments);//对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。
void load(Reader reader);//将字符流中的数据加载进集合。
void store(Writerwriter, String comments);//对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。
void list(PrintStream out);//将属性列表输出到指定的输出流
代码示例:
例:用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。
三、打印流
1、概述
打印流包括:PrintStream和PrintWriter
该流提供了打印方法,可将各种类型的数据都原样打印。
2、字节打印流:PrintStream
构造方法中可接收的参数类型:
a、File对象。File
b、字符串路径:String
c、字符输出流:OutputStream
3、字符串打印流:PrintWriter
构造方法中可接受的参数类型
a、File对象:File
b、字符串路径:String
c、字节输出流:OutputStream
d、字符输出流:Writer
代码示例:
四、序列流
1、概述
SequenceInputStream对多个流进行合并。也被称为合并流。
常用构造函数
SequenceInputStream(Enumeration<?extends FileInputStream> e)
2、常见合并多个流文件步骤
1、创建集合,并将流对象添加进集合
2、创建Enumeration对象,将集合元素加入。
3、创建SequenceInputStream对象,合并流对象
4、创建写入流对象,FileOutputStream关联写入文件
5、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。
代码示例:
例:切割并合并文件
五、对象的序列化(持久化)
ObjectInputStream& ObjectOutputStrea
将对象数据从堆内存存入到硬盘中,将对象序列化。
代码示例:
六、管道流
PipedInputStream&PipedOutputStream
输入输出可以直接进行连接,通常结合线程使用。
代码示例:
七、RandomAccessFile
RandomAccessFile
该类不算是IO体系中的子类。而是直接继承自Object。
但它是IO包中的成员,因为它具备读和写的功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针的位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和字节输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw.
如果模式为只读 r :不会创建文件。会去读一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式为读写 rw :操作的文件不存在,会自动创建。如果存在则不会覆盖。
代码示例:
八、操作基本数据类型的流对象DataInputStream& DataOutputStream
代码示例:
九、操作数组的流对象
ByteArrayInputStream&ByteArrayOutputStream
CharArrayReader&CharArrayWriter
StringReader&StringWriter
代码示例:
十、字符编码
1、常见编码表
ASCII:美国标准信息交换码。用一个字节的7位表示。
ISO8859-1:拉丁码表。欧洲码表。用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级。
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节表示。
UTF-8:最多用三个字节表示一个字符。
例:转换流的字符编码
例:编解码
例:从键盘输入学生信息,计算学生总成绩,并把学生信息和计算出的总分数高低顺序存放在磁盘文件“stuinfo.txt”中。
1、概述
File类:文件和目录路径名的抽象表现形式
特点:
a、用来将文件或文件夹封装成对象
b、方便于对文件与文件夹的属性信息进行操作
c、File对象可以作为参数传递给流的构造函数
File对象创建:
方式一:File f =new File("a.txt");
将a.txt封装成File对象。可以将已有的和不存在的文件或者文件夹封装成对象。
方式二:File f2=newFile("c:\\abc","b.txt");
将文件所在目录路径和文件一起传入,指定文件路径。
方式三:File d=new File("c:\\abc");
File f3=new File(d,"c.txt");
将文件目录路径封装成对象。再创建文件对象。降低了文件与父目录的关联性。
File.separator表示目录分隔符,可以跨平台使用。
2、常见方法。
a、创建
boolean createNewFile(); //在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立就创建文件。而且文件已经存在,会覆盖。
boolean mkdir();//创建文件夹,只能创建一级文件夹
boolean mkdirs();//创建多级文件夹
b、删除
boolean delete(); //删除文件或目录。文件存在,返回true;文件不存在或者正在被执行,返回false。
void deleteOnExit();//在程序退出时删除指定文件
c、判断
boolean canExecute();//是否是可执行文件
boolean exists();//文件是否存在
boolean isFile();//是否是文件
boolean isDirectory();//是否是文件夹
boolean isHidden();//是否是隐藏文件
boolean isAbsolute();//文件是否是绝对路径
记住:在判断文件对象是否是文件或者目录时,必须要判断该文件对象封装的内容是否存在。通过exists判断。
d、获取信息
String getName();//获取文件名
String getPath(); //获取文件的相对路径(即创建的对象传入的参数是什么就获取到什么)
String getParent(); //获取文件父目录。返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。如果相对路径中有上一层目录,那么该目录就是返回结果。
String getAbsolutePath();//获取文件的绝对路径
long lastModified();//返回文件最后一次被修改的时间
long length();//返回文件长度
boolean renameTo(File dest):重命名
e、列出文件及文件过滤
static File[] listRoots();//列出可用的文件系统根目录,即系统盘符
String[] list();
//列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。
String[]list(FilenameFilter filter);
//返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。
FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,accept(Filedir,String name),返回的是boolean型,对不符合条件的文件过滤掉。
File[] listFiles();//返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹
File[] ListFiles(FilenameFilterfilter);//返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。
代码示例:
import java.io.*; /* File类常见方法: 1,创建。 boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。 和输出流不一样,输出流对象一建立就创建文件。而且文件已经存在,会覆盖。 boolean mkdir():在已存在的文件夹下创建文件夹。 boolean mkdirs():创建多级文件夹。 2,删除。 boolean delete():删除文件或目录。文件存在,返回true;文件不存在或者正在被执行,返回false。 void deleteOnExit();//在程序退出时删除指定文件 3,判断。 boolean exists():文件是否存在。 boolean canExecute():文件是否能执行。 boolean isFile():是否是文件。 boolean isDirectory():是否是目录。 boolean isHidden():是否是隐藏文件。 boolean isAbsolute():路径是否是绝对路径。即使文件不存在,也会判断是不是绝对路径。 4,获取信息。 String getName():返回文件名。 String getPath():返回文件路径。 String getParent():返回父目录。该方法返回的是绝对路径中的父目录;如果相对路径中有上一层目录则返回该目录;如果获取的是相对路径则返回null。 例:文件路径为绝对路径c:\\abc\\file.txt,返回c: \abc; 文件路径为相对路径abc\\file.txt,返回\abc; 文件路径为相对路径file.txt,返回null; String getAbsolutePath():返回文件的绝对路径。 long lastModified():最后一次被修改的时间。 long length():文件的长度。 boolean renameTo(File dest):重命名 5,列出文件及文件过滤 static File[] listRoots();//列出可用的文件系统根目录,即系统盘符 String[] list();//列出当前目录下所有文件,包括隐藏。调用list方法的file对象必须是封装了一个目录。该目录还必须存在。 String[]list(FilenameFilter filter);//返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。 FilenameFilter:文件名过滤器,是一个接口,其中包含一个方法,boolean accept(File dir,String name):对不符合条件的文件过滤掉。 File[] listFiles();//返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹 File[] ListFiles(FilenameFilter filter);//返回抽象路径名数组,获取目录中满足指定过滤器的文件或目录。 */ import java.io.*; class FileDemo { public static void main(String[] args) throws IOException { list(); } public static void list() { File dir = new File("d:");//调用list方法的file对象必须是封装了一个目录。该目录还必须存在。 //列出当前目录下所有文件,包括隐藏。 String[] names = dir.list(); for(String name : names) { sop(name); } sop("---------------------------------------"); //返回一个字符串数组,获取目录中满足指定过滤器的文件或目录。 String[] jpg = dir.list(new FilenameFilter()//FilenameFilter 接口只有一个accept方法,可以使用匿名内部类。 { public boolean accept(File dir,String name) { return name.endsWith(".JPG"); } }); for(String name : jpg) { sop(name); } sop("---------------------------------------"); //返回一个抽象路径名数组,获取当前文件夹下的所有文件和文件夹 File[] files = dir.listFiles(); for(File f : files) { sop(f.getName()+"--"+f.length()); } } public static void listRoots() { File[] files = File.listRoots(); for(File file : files) { sop(file); } } public static void method()throws IOException { //创建File对象 File f = new File("file.txt"); //在指定位置创建文件,如果该文件已经存在,则不创建,返回false。 f.createNewFile(); //删除文件或目录。文件存在,返回true;文件不存在或者正在被执行,返回false。 //f.delete(); //在程序退出时删除指定文件 //f.deleteOnExit(); //创建文件夹 File dir = new File("abc"); dir.mkdirs(); //创建多级文件夹。 File dir1 = new File("abc\\kkk\\ddd\\fd\\dd"); dir.mkdirs(); //在判断文件对象是否是文件或目录时,必须要先判断该文件对象封装的内容是否存在 //通过exists判断。 f.exists();//文件是否存在。 f.canExecute();//文件是否能执行。 f.isFile();//是否是文件 f.isDirectory();//是否是目录。 f.isAbsolute();//路径是否是绝对路径。 f.getPath();//返回文件路径。 f.getAbsolutePath();//返回文件的绝对路径。 f.getParent();//该方法返回的是绝对路径中的父目录。如果获取的是相对路径则返回null。 f.renameTo(new File("d:\\haha.txt")); } //创建File对象 public static void consMethod()throws IOException { //将a.txt封装成对象。可以将已有的或未出现的文件或文件夹封装成对象。 File f1 = new File("a.txt"); File f2 = new File("c:\\abc","b.txt"); File d = new File("c:\\abc"); File f3 = new File(d,"c.txt"); //File f4 = new File("c:\\abd\\c.txt"); //File.separator表示目录分隔符,可以跨平台使用。 File f4 = new File("c:"+File.separator+"abd"+File.separator+"c.txt"); } public static void sop(Object obj) { System.out.println(obj); } }
3、递归
递归:
1,限定条件
2,要注意递归的次数,尽量避免内存溢出。因为每次调用自身的时候都会先执行下一次调用自己的方法,所以会不断在栈内存中开辟新空间,次数过多,会导致内存溢出。
例:列出指定目录下文件或文件夹,包含子目录中的内容。
import java.io.*; /* 列出指定目录下文件或文件夹,包含子目录中的内容。 递归: 1,限定条件 2,要注意递归的次数,尽量避免内存溢出。 */ class Filelist { public static void main(String[] args) { File dir = new File("g:\\myjava"); showDir(dir); } public static void showDir(File dir) { sop(dir+"---------"); File[] files = dir.listFiles(); for(File f : files) { if(f.isDirectory()) showDir(f); else sop(f); } } public static void sop(Object obj) { System.out.println(obj); } }
例:删除一个带内容的目录。
import java.io.*; /* 删除一个带内容的目录。 删除原理: 在windows中,删除目录是从里往外删的。 既然是从里往外删除,就要用到递归。 */ class RemoveDir { public static void main(String[] args) { File dir = new File("d:\\a"); removeDir(dir); } public static void removeDir(File dir) { File[] files = dir.listFiles(); for(File f : files) { if(!f.isHidden()&&f.isDirectory()) removeDir(f); else f.delete(); } dir.delete(); } }
例:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。建立一个java文件列表清单。
import java.io.*; import java.util.*; /* 将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。 建立一个java文件列表清单。 思路: 1、对指定的目录进行递归。 2、获取递归过程所有的java文件的路径。 3、将这些路径存储到集合中。 4、将集合中的数据写入到一个文件中。 */ class JavaFileList { public static void main(String[] args) { File dir = new File("g:\\myjavacode"); List<File> list = new ArrayList<File>(); fileToList(dir,list); System.out.println(list.size()); writeToFile(list,"g:\\myjavacode\\javalist.txt"); } 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,String javaListFile) { BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter(javaListFile)); for(File f : list) { String path = f.getAbsolutePath(); bw.write(path); bw.newLine(); bw.flush(); } } catch (IOException e) { System.out.println(e.toString()); } finally { try { if(bw!=null) bw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
二、Properties类
1、概述
Properties是Hashtable的子类,它具备Map集合的特点。而且它里面 存储的键值对都是字符串,无泛型定义。是集合中和IO技术想结合的集合容器。
特点:
1)可用于键值对形式的配置文件
2)在加载时,需要数据有固定的格式,常用的是:键=值
2、特有方法
1、设置
Object setProperty(String key,String value);//设置键和值
2、获取
String getProperty(String key); //指定key获取value
Set<String> stringPropertyName();//返回属性列表的键集,存入Set集合
3、加载流和存入流
void load(InputStream instream); //将字节流中的数据加载进集合。
void store(OutputStreamout,String comments);//对应load(InputStream )将属性列表(键值对)写入输出流。comments属性列表的描述。
void load(Reader reader);//将字符流中的数据加载进集合。
void store(Writerwriter, String comments);//对应load(Reader)将属性列表(键值对)写入输出流。comments属性列表的描述。
void list(PrintStream out);//将属性列表输出到指定的输出流
代码示例:
import java.io.*; import java.util.*; class PropertiesDemo { public static void main(String[] args) throws IOException { load(); } public static void load()throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream("info.txt"); //将流中数据加载进集合。 prop.load(fis); prop.setProperty("lisi","99");//只能修改内存中的数据,文件中数据不会改变。 FileOutputStream fos = new FileOutputStream("info.txt"); prop.store(fos,"correct lisi age"); System.out.println(prop); } /* 想要将info.txt中的键值数据存到集合中进行操作。 思路: 1,用一个流和文件相关联。 2,读取一行数据,将该行数据用“=”进行切割。 3,等号左边作为键,右边作为值。存入到Properties集合中即可。 */ public static void method()throws IOException { BufferedReader br = new BufferedReader(new FileReader("info.txt")); String line = null; Properties prop = new Properties(); while((line=br.readLine())!=null) { String[] arr = line.split("="); prop.setProperty(arr[0],arr[1]); } br.close(); System.out.println(prop); } public static void setAndGet() { Properties prop = new Properties(); prop.setProperty("zhangsan","30"); prop.setProperty("lisi","39"); System.out.println(prop); String value = prop.getProperty("lisi"); System.out.println(value); prop.setProperty("lisi","99"); Set<String> names = prop.stringPropertyNames(); for(String name : names) { System.out.println(name+":"+prop.getProperty(name)); } } }
例:用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。
import java.io.*; import java.util.*; /* 需求:用于记录应用程序运行次数。如果使用次数已到,那么给出注册提示。 分析: 很容易想到的是:计数器。可是该计数器定义在程序中,随着该应用程序的退出,该计数器也在内存中消失了。 所以要建立一个配置文件,用于记录该软件的使用次数。 该配置文件使用键值对的形式。键值对数据是map集合。 数据是以文件形式存储。使用io技术。那么map+io——>Properties。 思路:1、用读取流关联文本信息文件。如果存在则读取,如果不存在,则创建 2、每次运行,将文件数据存入集合中,读取值,判断次数,如果小于等于5次,则次数增加1次,如果大于则输出提示信息。 3、将值小于等于5次的信息数据存入文件中 */ class RunCount { public static void main(String[] args) throws IOException { Properties prop = new Properties(); File file = new File("count.ini"); if(!file.exists()) file.createNewFile(); FileInputStream fis = new FileInputStream(file); prop.load(fis); int count = 0; String value = prop.getProperty("time"); if(value!=null) count = Integer.parseInt(value); if (count>=5) { System.out.println("您好,使用次数已到,请注册!"); return ; } count++; prop.setProperty("time",count+""); FileOutputStream fos = new FileOutputStream(file); prop.store(fos,""); fos.close(); fis.close(); } }
三、打印流
1、概述
打印流包括:PrintStream和PrintWriter
该流提供了打印方法,可将各种类型的数据都原样打印。
2、字节打印流:PrintStream
构造方法中可接收的参数类型:
a、File对象。File
b、字符串路径:String
c、字符输出流:OutputStream
3、字符串打印流:PrintWriter
构造方法中可接受的参数类型
a、File对象:File
b、字符串路径:String
c、字节输出流:OutputStream
d、字符输出流:Writer
代码示例:
import java.io.*; class PrintStreamDemo { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(System.out,true);//true 代表自动刷新。 String line = null; while ((line=br.readLine())!=null) { if("over".equals(line)) break; out.println(line.toUpperCase()); //out.flush();//刷新是针对流的 } out.close(); br.close(); } }
四、序列流
1、概述
SequenceInputStream对多个流进行合并。也被称为合并流。
常用构造函数
SequenceInputStream(Enumeration<?extends FileInputStream> e)
2、常见合并多个流文件步骤
1、创建集合,并将流对象添加进集合
2、创建Enumeration对象,将集合元素加入。
3、创建SequenceInputStream对象,合并流对象
4、创建写入流对象,FileOutputStream关联写入文件
5、利用SequenceInputStream对象和FileOutputStream对象读数据进行反复读写操作。
代码示例:
import java.io.*; import java.util.*; class SequenceInputStreamDemo { public static void main(String[] args) throws IOException { Vector<FileInputStream> v = new Vector<FileInputStream>(); v.add(new FileInputStream("d:\\1.txt")); v.add(new FileInputStream("d:\\2.txt")); v.add(new FileInputStream("d:\\3.txt")); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("d:\\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(); mergeFile(); } public static void splitFile()throws IOException { FileInputStream fis = new FileInputStream("d:\\1.JPG"); FileOutputStream fos = null; byte[] buf = new byte[1024*1024]; int len = 0; int count = 1; while((len=fis.read(buf))!=-1) { fos = new FileOutputStream("d:\\splitfiles\\"+(count++)+".part"); fos.write(buf,0,len); fos.close(); } fis.close(); } public static void mergeFile()throws IOException { ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); al.add(new FileInputStream("d:\\splitfiles\\1.part")); al.add(new FileInputStream("d:\\splitfiles\\2.part")); al.add(new FileInputStream("d:\\splitfiles\\3.part")); al.add(new FileInputStream("d:\\splitfiles\\4.part")); al.add(new FileInputStream("d:\\splitfiles\\5.part")); final Iterator<FileInputStream> it = al.iterator(); Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() { public boolean hasMoreElements() { return it.hasNext(); } public FileInputStream nextElement() { return it.next(); } }; SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("d:\\0.JPG"); byte[] buf = new byte[1024]; int len = 0; while((len=sis.read(buf))!=-1) { fos.write(buf,0,len); } fos.close(); sis.close(); } }
五、对象的序列化(持久化)
ObjectInputStream& ObjectOutputStrea
将对象数据从堆内存存入到硬盘中,将对象序列化。
代码示例:
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")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } public static void writeobj()throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); oos.writeObject(new Person("lisi",30)); oos.close(); } } class Person implements Serializable { static final long serialVersionUID = 42L;// 保证序列号唯一 String name; transient int age;//transient修饰 非静态也不会被序列化。 static String country = "cn";//静态是不能被序列化的。 Person(String name,int age) { this.name = name; this.age = age; } public String toString() { return name+":"+age+" "+country; } }
六、管道流
PipedInputStream&PipedOutputStream
输入输出可以直接进行连接,通常结合线程使用。
代码示例:
import java.io.*; class Read implements Runnable { private PipedInputStream in; Read(PipedInputStream in) { this.in = in; } public void run() { try { byte[] buf = new byte[1024]; int len = in.read(buf); String s = new String(buf,0,len); System.out.println(s); in.close(); } catch (IOException e) { throw new RuntimeException("管道读取流失败"); } } } class Write implements Runnable { private PipedOutputStream out; Write(PipedOutputStream out) { this.out = out; } public void run() { try { out.write("piped lai la".getBytes()); out.close(); } catch (IOException e) { throw new RuntimeException("管道输出流失败"); } } } class PipedStreamDemo { public static void main(String[] args) throws IOException { PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); in.connect(out); Read r = new Read(in); Write w = new Write(out); new Thread(r).start(); new Thread(w).start(); } }
七、RandomAccessFile
RandomAccessFile
该类不算是IO体系中的子类。而是直接继承自Object。
但它是IO包中的成员,因为它具备读和写的功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针的位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和字节输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw.
如果模式为只读 r :不会创建文件。会去读一个已存在的文件,如果该文件不存在,则会出现异常。
如果模式为读写 rw :操作的文件不存在,会自动创建。如果存在则不会覆盖。
代码示例:
import java.io.*; /* RandomAccessFile 该类不算是IO体系中的子类。而是直接继承自Object。 但它是IO包中的成员,因为它具备读和写的功能。 内部封装了一个数组,而且通过指针对数组的元素进行操作。 可以通过getFilePointer获取指针的位置, 同时可以通过seek改变指针的位置。 其实完成读写的原理就是内部封装了字节输入流和字节输出流。 通过构造函数可以看出,该类只能操作文件。 而且操作文件还有模式:只读r,读写rw. 如果模式为只读 r :不会创建文件。会去读一个已存在的文件,如果该文件不存在,则会出现异常。 如果模式为读写 rw :操作的文件不存在,会自动创建。如果存在则不会覆盖。 */ class RandomAccessFileDemo { public static void main(String[] args) throws IOException { writeFile(); System.out.println("Hello World!"); readFile(); } public static void readFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.txt","r"); //调整对象指针。 raf.seek(8*0); //跳过指定的字节数 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); System.out.println("name="+name); int age = raf.readInt(); System.out.println("age="+age); raf.close(); } public static void writeFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("raf.txt","rw"); raf.write("李四".getBytes()); raf.writeInt(97);//4个字节 raf.write("王五".getBytes()); raf.writeInt(99); raf.seek(8*3); raf.write("周七".getBytes()); raf.writeInt(103); raf.close(); } }
八、操作基本数据类型的流对象DataInputStream& DataOutputStream
代码示例:
import java.io.*; class DataStreamDemo { public static void main(String[] args) throws IOException { writeData(); System.out.println("Hello World!"); readData(); } public static void readData()throws IOException { DataInputStream dis = new DataInputStream(new FileInputStream("data.txt")); int n = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println("n="+n); System.out.println("b="+b); System.out.println("d="+d); dis.close(); } public static void writeData()throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(9888.756); dos.close(); } }
九、操作数组的流对象
ByteArrayInputStream&ByteArrayOutputStream
CharArrayReader&CharArrayWriter
StringReader&StringWriter
代码示例:
import java.io.*; /* 用于操作字节数组的流对象。 ByteArrayInputStream:在构造的时候,需要接收数据源。而且数据源是一个字节数组。 ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象内部已经封装了可变长度的字节数组。这就是数据目的地。 因为这两个流对象都操作数组,并没有使用系统资源,所以不用close关闭。 源设备: 键盘 System.in 硬盘 FileStream 内存 ArrayStream 目的设备: 控制台: System.out 硬盘 FileStream 内存 ArrayStream 用流的读写思想来操作数据。 */ class ByteArrayStreamDemo { public static void main(String[] args) throws IOException { //数据源 ByteArrayInputStream bis = new ByteArrayInputStream("abcdefg".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()); } }
十、字符编码
1、常见编码表
ASCII:美国标准信息交换码。用一个字节的7位表示。
ISO8859-1:拉丁码表。欧洲码表。用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级。
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节表示。
UTF-8:最多用三个字节表示一个字符。
例:转换流的字符编码
import java.io.*; class EncodeStream { public static void main(String[] args) { System.out.println("Hello World!"); } public static void readText()throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt","UTF-8")); char[] buf = new char[10]; int len = isr.read(buf); String s = new String(buf,0,len); System.out.println(s); isr.close(); } public static void writeText()throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt","UTF-8")); osw.write("你好"); osw.close(); } }
例:编解码
import java.util.*; /* 编码:字符串变成字符数组。 解码:字符数组变成字符串。 String-->byte[]; str.getBytes(charsetName); byte[]-->String; new String(byte[],charsetName); */ class EncodeDemo { public static void main(String[] args) throws Exception { String s = "你好"; byte[] b1 = s.getBytes("GBK"); System.out.println(Arrays.toString(b1)); String s1 = new String(b1,"ISO8859-1"); System.out.println(s1); byte[] b2 = s1.getBytes("ISO8859-1"); System.out.println(Arrays.toString(b2)); String s2 = new String(b2,"GBK"); System.out.println(s2); } }
例:从键盘输入学生信息,计算学生总成绩,并把学生信息和计算出的总分数高低顺序存放在磁盘文件“stuinfo.txt”中。
/* 有五个学生,每个学生有三门课的成绩。 从键盘输入以上数据(包括姓名,三门课成绩)。 输入格式:zhangsan,30,40,50。 计算出总成绩,并把学生信息和计算出的总分数高低顺序存放在磁盘文件“stuinfo.txt”中。 1,描述学生类。 2,定义一个可操作学生对象的工具类。 思路; 1,通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。 2,因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。所以可以使用TreeSet集合。 3,将集合信息写入文件中。 */ import java.io.*; import java.util.*; class Student implements Comparable<Student> { private String name; private int math,chinese,english; private int sum; Student(String name,int math,int chinese,int english) { this.name = name; this.math = math; this.chinese = chinese; this.english = english; sum = math + chinese + english; } public int compareTo(Student s) { int num = new Integer(this.sum).compareTo(new Integer(s.sum)); if(num==0) return this.name.compareTo(s.name); return num; } public String getName() { return name; } public int getSum() { return sum; } public int hashCode() { return name.hashCode()+sum*78; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.sum == s.sum; } public String toString() { return "studet["+name+", "+math+", "+chinese+", "+english+"]"; } } class StudentInfoTool { public static Set<Student> getStudents()throws IOException { return getStudents(null); } public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; Set<Student> stus = null; if(cmp==null) stus = new TreeSet<Student>(); else stus = new TreeSet<Student>(cmp); while((line=br.readLine())!=null) { if("over".equals(line)) break; String[] info = line.split(","); Student stu = new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3])); stus.add(stu); } br.close(); return stus; } public static void write2File(Set<Student> stus)throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter("stuinfo.txt")); for(Student stu : stus) { bw.write(stu.toString()+"\t"); bw.write(stu.getSum()+""); bw.newLine(); bw.flush(); } bw.close(); } } class StudentInfoTest { public static void main(String[] args) throws IOException { Comparator<Student> cmp = Collections.reverseOrder(); Set<Student> stus = StudentInfoTool.getStudents(cmp); StudentInfoTool.write2File(stus); System.out.println("Hello World!"); } }
相关文章推荐
- java学习之继承、重载、重写(覆盖)
- java中的包
- JAVA多线程和并发性知识点总结
- springMVC Spring MVC 异常处理
- Struts2中的配置问题
- Spring4新特性:泛型限定式依赖注入
- Jdk用native2ascii命令做unicode编码转换
- Could not initialize JavaVM
- java基础-IO-字符流、字节流
- springmvc常用注解以及参数传递
- spring mvc json乱码问题
- myeclipse开发jar包not find总结(更新中)
- java+Struts2生成验证码
- 转 Java内存管理原理及内存区域详解
- JAVA非空条件三元运算符
- eclipse配置jetty运行环境二
- [leetcode-213]House Robber II(java)
- 修改Struts2的struts.xml配置文件位置
- JAVA float double数据类型保留2位小数点5种方法
- Quartz核心类