1、字符字节流的转换
public static void main(String[] args) throws IOException { InputStream in=System.in; InputStreamReader isr=new InputStreamReader(in); //字符流 BufferedReader br=new BufferedReader(isr); String line=null; while ((line=br.readLine())!=null){ if("over".equals(line)) break; System.out.println(line.toUpperCase()); } }
OutputStreamWriter的子类有FileWriter。FileWriter操作文本文件。
键盘录入的简写
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out)); String line=null; while ((line=bufr.readLine())!=null){ if("over".equals(line)) break; bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush();
System的in和out对象只有一个。如果关闭就无法再打开。而且in和out会随着系统的关闭而关闭,所以不需要手动的去关闭这两个对象。
字符本身来自于字节,而由于字符全都是文本因此转换为字符流比较好操作。
需求:将键盘录入的数据写入到一个文件中。
代码:
public static void main(String[] args) throws IOException { BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d://dem.txt"))); String line=null; while ((line=bufr.readLine())!=null){ if("over".equals(line)) break; bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush(); }
需求2:将文本文件内容输出到控制台
public static void main(String[] args) throws IOException { BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("d://dem.txt"))); BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out)); String line=null; while ((line=bufr.readLine())!=null){ if("over".equals(line)) break; bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush(); } }
以上是为了感受流的规律。
2、流操作的基本规律
InputStreamReader:字节到字符的桥梁。解码
OutputStreamWriter:字符到字节的桥梁。编码
流的操作规律:
之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。
如果想知道开发使用那些对象,需要知道四个明确。
(1)明确源和目的(汇)
源:InputStream Reader
目的:OutputStream Writer
(2)明确数据是否是纯文本数据
源:是纯文本:Reader
否:InputStream
目的:是纯文本Writer
否:OutputStream
到这里,就可以明确需求中具体要使用哪个体系。
(3)明确具体的设备
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
(4)是否需要其他额外功能
1,是否需要高效(缓冲区)
是,加buffer
3、转换流的编码解码
需求:将一个中文字符串数据按照指定的编码表写入到一个文本文件中。
字符串默认使用的是系统的系统语言文本。
一个中文两个字节,任何java识别的字符数据都是UNICODE码表,但是字符串是GBK本地默认码表。
UTF-8国际标准规范的码表。
FileWriter使用系统默认的码表。
OutputStreamWriter可以使用指定的字符集,将要写入流中的字符编码成字节。
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("dem.txt"));
等同于
FileWriter fw=new FileWriter(""); //封装的就是OutputStreamWriter
指定编码表
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("dem1.txt"),"UTF-8");
FileWriter其实就是转换流指定了本机默认码表的体现。而且这个转换流的子类对象,可以方便操作文本文件。
简单说就是 操作文件的字节流+本机默认的编码表。
这是按照默认码表来操作文件的便捷类。
public static void main(String[] args) throws IOException { //如果操作文本文件需要明确具体的编码。FileWriter就不行了,必须使用转换流。 //UTF-8对于中文来讲是使用了三个字节来表示的,GBK是两个字节,当读取一个UTF-8的文本文件就会只去读文字的前两个字节去查码表。 InputStreamReader isr=new InputStreamReader(new FileInputStream("dem.txt"),"utf-8"); char[] buf=new char[10]; int len=isr.read(buf); String str=new String(buf,0,len); System.out.println(str); isr.close(); }
一般出现中文乱码都是其他编码的使用了gbk来解码了。
如果gbk文本文件使用utf-8来解码,就会出现??未知的乱码。
1 /**既然需求中已经明确了指定编码表的动作。 2 * 那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表 3 * 只能使用其父类。outputStreamWriter 4 * outputStreamWriter接收一个字节输出流对象,既然是操作文件,那么该对象应该是FileOutputStream 5 * 什么时候使用转换流呢? 6 * 1、源或者目的对应的设备是字节流,但是操作的是文本数据,可以使用转换作为桥梁 7 * 提高对文本操作的便捷 8 * 2、一旦操作文本设计到具体的指定编码表时,必须使用转换流。 9 */
4、File类构造函数&字段
io流只能操作设备上的数据,不能操作文件夹、文件名和修改文件属性。
操作这些需要一个特殊的对象。File文件对象。
File
(1)将文件或者文件夹封装成对象。
(2)方便对文件与文件夹的属性信息进行操作。
(3)File对象可以作为参数传递给流的构造函数。
File类是用来封装文件或者文件夹的,所以File在new的时候必须给到一个文件或者文件夹的名称。
File的构造函数三种
public static void constructorDemo() { //可以将一个已存在的,或者不存在的文件或者目录封装成File对象 File file=new File("d:\a.txt"); // File file1=new File("d:\","b.txt"); File f=new File("d:\"); File file2=new File(f,"c.txt"); }
系统分割符
File file=new File("d:"+System.getProperty("file.separator")+"cs.txt"); File file1=new File("d:"+File.separator+"a.txt");
pathSeparatorChar与系统路径有关的路径分隔符。在WINDOWS系统上是";"不是冒号噢
File对象常见功能-----获取
常用功能
public static void main(String[] args) { /* * File对象的常见方法 * 1、获取。 * 1.1 获取文件名称 * 1.2 获取文件路径 * 1.3 获取文件大小 * 1.4 获取文件的修改时间 */ getDemo(); } public static void getDemo() { File file = new File("a.txt"); String name = file.getName(); String path = file.getPath(); String realPath=file.getAbsolutePath(); long len=file.length(); long time = file.lastModified(); Date date=new Date(time); DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG); String str_time=dateFormat.format(date); System.out.println(len); System.out.println(str_time); }
File对象常见功能-----创建和删除
/* * 和输出流不一样,如果文件不存在,则创建,如果文件存在,则不创建 */ File file = new File("d:\file1"); /*// boolean b = file.createNewFile(); // // System.out.println("b="+b);*/ //创建文件夹 // boolean b = file.mkdir(); System.out.println("b="+b);
mkdirs创建多级目录。
File常见功能----判断
(1)判断文件是否存在
file.exists();
(2)是否是文件
file.isFile()
(3)是否是文件夹
file.isDirectory()
系统根目录和容量获取
遍历系统根目录
File[] files = File.listRoots(); for (File file : files) { System.out.println(file);
获取磁盘空间
File file=new File("d:\"); //磁盘剩余空间 System.out.println(file.getFreeSpace()); //磁盘总空间 System.out.println(file.getTotalSpace()); //返回此抽象路径名指定的分区上可用于虚拟机的字节数 System.out.println(file.getUsableSpace());
File常见功能----获取目录内容
遍历d盘 当前目录下所有的文件和文件夹名称,并包含着系统隐藏文件名称。调用list方法的file对象中,封装的必须是目录否则会发生空指针异常。
如果访问的 系统级目录也会发生空指针异常。
如果目录存在但是没有内容,会返回一个数组,但是长度为0
File file=new File("d:\"); String[] list = file.list(); for(String name:list){ System.out.println(name); }
File常见功能----过滤器
例如:只需要某个目录下以.txt结尾的文件。
list(FilenameFilter filter)
public class FilterByJava implements FilenameFilter { @Override public boolean accept(File dir, String name) { return name.endsWith(".txt"); }
public static void listDemo2(){ File dir=new File("c:\"); //底层,先list将所有内容都取出来到数组。然后遍历数组看是否符合创建的FilenameFilter.accept(dir,name); dir是目录,name是名称 // 只要返回的是true就存起来到names数组中 String[] names=dir.list(new FilterByJava()); for(String name:names){ System.out.println(name); } }
file的list方法只能获取目录下的文件名称。而listFiles()方法可以拿到当前目录下所有文件对象。
public class FilterByHidden implements FileFilter { @Override public boolean accept(File pathname) { return pathname.isHidden(); } }
public static void listDemo3() { File dir=new File("c:\"); File [] files=dir.listFiles(new FilterByHidden()); for(File file:files ){ System.out.println(file); } }
后缀
public class SuffixFilter implements FilenameFilter { private String suffix; public SuffixFilter(String suffix){ super(); this.suffix=suffix; } @Override public boolean accept(File dir, String name) { return name.endsWith(suffix); } }
public static void listDemo2(){ File dir=new File("c:\"); //底层,先list将所有内容都取出来到数组。然后遍历数组看是否符合创建的FilenameFilter.accept(dir,name); dir是目录,name是名称 // 只要返回的是true就存起来到names数组中 String[] names=dir.list(new SuffixFilter(".txt")); for(String name:names){ System.out.println(name); } }