BufferedReader br = //高效的用指定的编(解码) new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8")); BufferedWriter bw = //高效的用表写(编码) new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK")); int ch; while((ch = br.read()) != -1) { bw.write(ch); } br.close(); bw.close();
public Writer append(CharSequence csq ) throws IOException { if (csq == null) write( "null" ); else write( csq .toString()); return this ; }
//演示编码 String str=...; ByteBuffer buffer=cset.encode(str); byte[] bytes=buffer.array();//等价于str.getBytes(cset);
解码:Charset对象也需要通过字节缓冲区来实现解码功能,首先调用ByteBuffer的静态方法wrap将字节数组存入缓冲区,然后调用Charset对象的decode方法解码,返回一个字符缓冲区.再利用字符缓冲区的toString方法返回字符串.
- 对于遇到的每一个对象引用都关联一个序列号
- 对于每一个对象,当第一次遇到的时候,保存其对象数据到流中.
- 如果某个对象之前已经保存过,只写出与之前保存的序列号为x的对象相同.
- 对于流中的对象,在第一次遇到其序列号时候,构建它,并使用流中的数据初始化,然后记录这个顺序号与新对象之间的关联.
- 当遇到"与之前保存过的序列号为x的对象相同"标记时获取与这个顺序号相同的对象引用
import java.io.Serializable; class Person implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name ; private int age ; public static Person p = new Person( "xyy",24); private Person(String name, int age ) { super (); this .name = name ; this .age = age ; } public static Person getPerson() { return p ; } } public class Demo { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p=Person. p; ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("C:/obj.dat" )); oos.writeObject( p); oos.close(); ObjectInputStream ois= new ObjectInputStream( new FileInputStream("C:/obj.dat" )); Person p1=(Person) ois.readObject(); System. out .println(p1 ==p ); ois.close(); } }
此时输出为false.破坏了单例模式,解决问题应该在Person类中添加readResolve方法.在Person类添加如下代码,返回true.
protected Object readResolve() { return p ; }
△序列化机制提供了一种用法:提供了一种克隆对象的简便途径,只要对应的类是可序列化的即可,直接将对象序列化到输出流中,然后将其读回,这样产生的对象是原对象的一个深拷贝.可以用ByteArrayOutPutStream保存到字节数组.
△Java7新特性之Path类和Files类.
Java7新增了用于操作文件路径的Path类,它封装了文件的路径,并且提供了一系列有关于文件路径的方法,例如resolve(将两个路径组合起来),equals方法,getParent,getRoot,isAbsolute方法.将以前File类对于文件的操作封装至Files类中,Files类中提供了一系列诸如以前File类中操作文件的方法,例如delete,createFile,createDirectory方法.此外,一些获取文件属性的操作,封装到接口BasicFileAttribute接口中,例如creationTime方法,lastModifiedTime方法等.下面列出了一系列可能会很有用的方法:
//Paths类.用于获取Path对象. static Path get(String first,String... more); /*获取路径对象.将按照默认文件系统分割符组合,然后解析连接起来的结果,如果不是合法路径,抛出异常*/
//Path类.封装了一系列的路径操作 /* 如果other是绝对路径,返回绝对路径,否则返回this和other连接获得的路径 */ Path resolve(Path other); /* 如果other是绝对路径返回other,否则返回连接this父路径和other获得的路径 */ Path resolveSibling(Path other); /* 返回父路径,或者在路径没有父路径的时候,返回null */ Path getParent(); /* 返回该路径的最后一个部件,没有任何部件,返回null */ Path getFileName(); /* 从该路径中创建File对象 */ File toFile();
//File对象提供了转化为path对象的方法 Path toPath();
//Files类封装了一系列对于文件的操作.包括输入输出流缓冲的读取. //把文件的内容转化为字节数组. byte[] bytes=Files.readAllBytes(path); //希望将文件当作行序列读取,那么可以调用: List<String> lines=Files.readAllLines(path,charset); //将字节数组写入文件 Files.write(path,bytes); //将行的集合写入到文件中: Files.write(path,lines); //获取指定文件的输入流和输出流 InputStream in=Files.newInputStream(path); OutputStream out=Files.newOutputStream(path); //获取指定编码的BufferedReader和指定解码的BufferedWriter Reader in=Files.newBufferedReader(path,charset); Writer out=Files.newBufferedWriter(path,charset); //将一个文件复制或移动(复制并删除)到给定位置.可以代替重命名操作. static Path copy(Path from,Path to,CopyOption... options); static Path move(Path from,Path to,CopyOption... options); //删除给定文件或空目录 static void delete(Path path); static void deleteIfExits(Path path); //创建目录(与mkdir,mkdirs一样) static Path createFile(Path path,FileAttribute... attrs); static Path createDirectory(Path path,FileAttribute... attrs); static Path createDirectorys(Path path,FileAttribute... attrs); //获取文件信息(一部分信息封装在BasicAttributes接口) static boolean exits(Path path); //是否存在 static boolean isHidden(Path path); //是否隐藏 static boolean isRegularFile(Path path); //是否是文件 static boolean isDirevtory(Path path); //是否是文件夹 static long size(Path path); //获取文件按字节度量的尺寸. //通过如下操作,获取文件属性对象 PosixFileAttribute attributes=Files.readAttributes(path,BasicFileAttributes.class);
//BasicFileAttributes接口提供一系列属性信息 FileTime creationTime(); //创建时间 FileTime lastModifiedTime(); //最迟修改的时间
Files类提供了一个可以产生Iterable对象,代替list方法.下面代码说明如何使用:
try(DirectoryStream<Path> entries=Files.newDirectoryStream(dir)) { for(Path entry:entries) //Process entries }
可以在方法中指定模式来过滤文件:
try(DirectoryStream<Path> entries=Files.newDirectoryStream(dir,"*.txt"))
模式 | 描述 | 示例 |
* | 匹配路径组成部分的0个或多个字符 | *.java匹配当前目录所有Java文件 |
** | 匹配跨目录边界的0个或多个字符 | **.java 匹配在所有子目录中的Java文件 |
? | 匹配一个字符 | ????.java匹配所有四个字符的Java文件 |
{...} | 匹配由逗号隔开的多个可选项之一 | *.{java,class}匹配所有的Java文件和类class文件 |
\ | 转义上述任意模式的字符 | \*,转义* |
Files提供了一种我认为非常便捷的访问子孙成员的方法,walkFileTree方法,省去了原先需要进行的遍历操作.向其传递一个FileVistor对象.(一般传入便捷类SimpleFileVistor对象,但是其除FileVisited方法之外所有的操作都不做任何处理继续访问,而visitFileFailed方法会抛出异常终止访问,因此一般需要覆盖visitFileFailed方法,防止遇到无法打开的文件暂停访问,其余方法是否覆盖根据需求.下面是遍历一个路径下的所有子孙文件的操作,大大增加了遍历文件的简洁性:
import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; public class Demo { public static void main(String[] args) throws IOException { Path path=Paths.get("C:\\","pictures"); printFile(path); } public static void printFile(Path path) throws IOException { Files.walkFileTree(path,new SimpleFileVisitor<Path>() { //在一个目录被处理前执行的操作 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println(dir+"目录将被处理"); return FileVisitResult.CONTINUE; } //遇见一个文件的时候执行的操作 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println("访问"+file+"文件"); return FileVisitResult.CONTINUE; } //访问文件失败的时候执行的操作 public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } //一个目录被处理后执行的操作 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { System.out.println(dir+"被处理"); return FileVisitResult.CONTINUE; } }); } }