一、File类
二、递归
三、Properties类
四、打印流
五、切割流
六、队列流
七、其他功能的流1、内存流
2、数据流
3、管道流
4、随机存取流
5、对象流
八、编码九、流的操作规律
十、思考与总结
一、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():
getAbsolutePath()
long lastModified()
long length()
206class FileDemo 207{ 208 public static void main(String[] args) throws IOException 209 { 210 method_5(); 211 } 212 213 public static void method_5() 214 { 215 File f1 = new File("c:\\Test.java"); 216 File f2 = new File("d:\\hahah.java"); 217 218 sop("rename:"+f2.renameTo(f1)); 219 220 } 221 222 public static void method_4() 223 { 224 File f = new File("file.txt"); 225 226 sop("path:"+f.getPath()); 227 sop("abspath:"+f.getAbsolutePath()); 228 sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。 229 //如果相对路径中有上一层目录那么该目录就是返回结果。 230 231 232 233 } 234 235 public static void method_3()throws IOException 236 { 237 File f = new File("d:\\java1223\\day20\\file2.txt"); 238 239 //f.createNewFile(); 240 241 //f.mkdir(); 242 243 244 //记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。 245 //通过exists判断。 246 sop("dir:"+f.isDirectory()); 247 sop("file:"+f.isFile()); 248 249 sop(f.isAbsolute()); 250 } 251 252 253 public static void method_2() 254 { 255 File f = new File("file.txt"); 256 257 //sop("exists:"+f.exists()); 258 259 //sop("execute:"+f.canExecute()); 260 261 //创建文件夹 262 File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa"); 263 264 sop("mkdir:"+dir.mkdirs()); 265 } 266 267 268 public static void method_1()throws IOException 269 { 270 File f = new File("file.txt"); 271// sop("create:"+f.createNewFile()); 272 //sop("delete:"+f.delete()); 273 274 275 276 277 }
二、递归函数自身调用自身。这种表现形式,或者编程手法,称为递归。
递归要注意:
1,限定条件。
2,要注意递归的次数。尽量避免内存溢出。
278/* 279需求:列出指定目录下文件或者文件夹,包含子目录中的内容。 280 281因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。 282在列出过程中出现的还是目录的话,还可以再次调用本功能。也就是 283需要使用到递归。 284 285*/ 286import java.io.*; 287 288class FileDemo3 289{ 290 public static void main(String[] args) 291 { 292 File dir = new File("d:\\testdir"); 293 //showDir(dir,0); 294 295 //toBin(6); 296 //int n = getSum(8000); 297 //System.out.println("n="+n); 298 299 System.out.println(dir.delete()); 300 } 301 public static String getLevel(int level) 302 { 303 StringBuilder sb = new StringBuilder(); 304 sb.append("|--"); 305 for(int x=0; x<level; x++) 306 { 307 //sb.append("|--"); 308 sb.insert(0,"| "); 309 310 } 311 return sb.toString(); 312 } 313 public static void showDir(File dir,int level) 314 { 315 316 System.out.println(getLevel(level)+dir.getName()); 317 318 level++; 319 File[] files = dir.listFiles(); 320 for(int x=0; x<files.length; x++) 321 { 322 if(files[x].isDirectory()) 323 showDir(files[x],level); 324 else 325 System.out.println(getLevel(level)+files[x]); 326 } 327 }
三、Properties类
1、Properties是hashtable的子类。也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。是集合中和IO技术相结合的集合容器。
2、该对象的特点:可以用于键值对形式的配置文件。
3、那么在加载数据时,需要数据有固定格式:键=值。
328/* 329练习:限制程序运行次数。当运行次数到达5次时,给出,请您注册的提示。并不再让该程序执行。 330*/ 331import java.io.*; 332import java.util.*; 333 334class PropertiesDemo 335{ 336 public static void main(String[] args) throws IOException 337 { 338 //method_1(); 339 loadDemo(); 340 } 341 342 public static void loadDemo()throws IOException 343 { 344 Properties prop = new Properties(); 345 FileInputStream fis = new FileInputStream("info.txt"); 346 347 //将流中的数据加载进集合。 348 prop.load(fis); 349 350 prop.setProperty("wangwu","39"); 351 352 FileOutputStream fos = new FileOutputStream("info.txt"); 353 354 prop.store(fos,"haha"); 355 356 // System.out.println(prop); 357 prop.list(System.out); 358 359 fos.close(); 360 fis.close(); 361 362 } 363 364 //演示,如何将流中的数据存储到集合中。 365 //想要将info.txt中键值数据存到集合中进行操作。 366 /* 367 1,用一个流和info.txt文件关联。 368 2,读取一行数据,将该行数据用"="进行切割。 369 3,等号左边作为键,右边作为值。存入到Properties集合中即可。 370 371 */ 372 public static void method_1()throws IOException 373 { 374 BufferedReader bufr = new BufferedReader(new FileReader("info.txt")); 375 376 String line = null; 377 Properties prop = new Properties(); 378 379 380 while((line=bufr.readLine())!=null) 381 { 382 String[] arr = line.split("="); 383 ///System.out.println(arr[0]+"...."+arr[1]); 384 prop.setProperty(arr[0],arr[1]); 385 } 386 387 bufr.close(); 388 389 System.out.println(prop); 390 } 391 392 393 394// 设置和获取元素。 395 public static void setAndGet() 396 { 397 Properties prop = new Properties(); 398 399 prop.setProperty("zhangsan","30"); 400 prop.setProperty("lisi","39"); 401 402// System.out.println(prop); 403 String value = prop.getProperty("lisi"); 404 //System.out.println(value); 405 406 prop.setProperty("lisi",89+""); 407 408 Set<String> names = prop.stringPropertyNames(); 409 for(String s : names) 410 { 411 System.out.println(s+":"+prop.getProperty(s)); 412 } 413 } 414 415 416}
四、打印流
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
1、字节打印流:
PrintStream
构造函数可以接收的参数类型:
a,file对象。File
b,字符串路径。String
c,字节输出流。OutputStream
2、字符打印流:
PrintWriter
构造函数可以接收的参数类型:
a,file对象。File
b,字符串路径。String
c,字节输出流。OutputStream
d,字符输出流,Writer。
1 import java.io.*;
2
3 class PrintStreamDemo
4 {
5 public static void main(String[] args) throws IOException
6 {
7 BufferedReader bufr =
8 new BufferedReader(new InputStreamReader(System.in));
9
10 PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);
11
12 String line = null;
13
14 while((line=bufr.readLine())!=null)
15 {
16 if("over".equals(line))
17 break;
18 out.println(line.toUpperCase());
19 //out.flush();
20 }
21
22 out.close();
23 bufr.close();
24
25 }
26 }
五、切割流
将完整的流切割成若干碎片进行保存。在需要的时候可以重新组合。
443import java.io.*; 444import java.util.*; 445 446class SplitFile 447{ 448 public static void main(String[] args) throws IOException 449 { 450 //splitFile(); 451 merge(); 452 } 453 454 455 public static void merge()throws IOException 456 { 457 ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); 458 459 for(int x=1; x<=3; x++) 460 { 461 al.add(new FileInputStream("c:\\splitfiles\\"+x+".part")); 462 } 463 464 final Iterator<FileInputStream> it = al.iterator(); 465 466 Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() 467 { 468 public boolean hasMoreElements() 469 { 470 return it.hasNext(); 471 } 472 public FileInputStream nextElement() 473 { 474 return it.next(); 475 } 476 }; 477 478 SequenceInputStream sis = new SequenceInputStream(en); 479 480 481 FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp"); 482 483 byte[] buf = new byte[1024]; 484 485 int len = 0; 486 487 while((len=sis.read(buf))!=-1) 488 { 489 fos.write(buf,0,len); 490 } 491 492 fos.close(); 493 sis.close(); 494 } 495 496 public static void splitFile()throws IOException 497 { 498 FileInputStream fis = new FileInputStream("c:\\1.bmp"); 499 500 FileOutputStream fos = null; 501 502 503 byte[] buf = new byte[1024*1024]; 504 505 int len = 0; 506 int count = 1; 507 while((len=fis.read(buf))!=-1) 508 { 509 fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part"); 510 fos.write(buf,0,len); 511 fos.close(); 512 } 513 514 fis.close(); 515 516 } 517}
六、序列流
SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
构造函数:
518public SequenceInputStream(Enumeration<? extends InputStream> e) 519public SequenceInputStream(InputStream s1,InputStream s2)
从其构造函数可知,通过它可以将碎片文件整合起来。
520import java.io.*; 521import java.util.*; 522class SequenceDemo 523{ 524 public static void main(String[] args) throws IOException 525 { 526 527 Vector<FileInputStream> v = new Vector<FileInputStream>(); 528 529 530 v.add(new FileInputStream("c:\\1.txt")); 531 v.add(new FileInputStream("c:\\2.txt")); 532 v.add(new FileInputStream("c:\\3.txt")); 533 534 Enumeration<FileInputStream> en = v.elements(); 535 536 SequenceInputStream sis = new SequenceInputStream(en); 537 538 FileOutputStream fos = new FileOutputStream("c:\\4.txt"); 539 540 byte[] buf = new byte[1024]; 541 542 int len =0; 543 while((len=sis.read(buf))!=-1) 544 { 545 fos.write(buf,0,len); 546 } 547 548 fos.close(); 549 sis.close();
七、其他功能的流
1、内存流ArrayStream
用于操作字节数组的流对象。
ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
在流操作规律讲解时:
源设备:
键盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
1 import java.io.*;
2 class ByteArrayStream
3 { //用流的读写思想来操作数据。
4 public static void main(String[] args)
5 {
6 //数据源。
7 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());
8
9 //数据目的
10 ByteArrayOutputStream bos = new ByteArrayOutputStream();
11
12 int by = 0;
13
14 while((by=bis.read())!=-1)
15 {
16 bos.write(by);
17 }
18
19
20
21 System.out.println(bos.size());
22 System.out.println(bos.toString());
23
24 // bos.writeTo(new FileOutputStream("a.txt"));
25
26 }
27 }
2、数据流
可以用于操作基本数据类型的数据的流对象。
3、管道流
输入与输出需要接到一块,操作的是线程,read是阻塞是方法。
4、随机存取流
该类不是算是IO体系中子类。而是直接继承自Object。但是它是IO包中成员。因为它具备读和写功能。内部封装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。其实完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,,读写rw等。如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
5、对象流
a,成对出现的,其读写方法需要对象提供序列号;
b,序列号:类实现Serlizeble接口后,会为对象生成特有的序列号,这个序列号与对象特有的成员有关;
c,静态成员:与序列号无关;
d,特有成员:加上transient后,与序列号无关。
e,序列化可以判断:内存中对象与文件中是否为同一个。
九、流的操作规律
流对象很多,用哪个是个问题。
通过三个明确来确定。
1.明确源和目的。
a,源是输入流;
b,目的是输出流。
2.明确操作数据是否是纯文本。
纯文本是字符流,其他用字节流
3,体系明确后,再确定要使用那个对象。
a,源:内存、硬盘、键盘;
b,目的:内存、硬盘、控制台。
4,是否需要提高效率?
十、思考与总结
1、Writer
基类是抽象的,所以用子类来创建对象;在创建子类对象时,要指定目的地;有了目的地,然后开始写的的动作,写是写到流中,想要将写的数据转入目的地(内存流除外),需要刷新的动作;刷新之后,要关闭资源;为什么关闭资源?因为读写并不是java的功能,而是java调用了系统的功能,所以要关闭(系统)资源。
2、IOException
原则上一块处理;但关闭资源的动作是要放到finally中,并且为了避免空指针异常,应该加上判断;创建引用变量写在try之外。
3、源与流的设置
System.setOut()
System.setIn()