黑马程序员-学习日记13(IO流 2 )

-------android培训java培训、期待与您交流! ----------

 

 

.IO流(BufferdeWriter)

 1.字符流的缓冲区

  1)缓冲区是为了提高流的操作效率而出现的。
  所以在创建缓冲区之前,必须要先有流对象。
  缓冲区在流的基础上对流的功能进行了增强。
  2)该缓冲区中提供了一个跨平台的换行符:newLine();
  3)对应类:
   BufferedWriter
   BufferedReader
  4)缓冲区的原理:将数组封装成对象,批量输出数据。

 2.Writer-----> BufferedWriter(java.io包);

   1)将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
   可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
   2)构造函数:
   BufferedWriter(Writer out)
     创建一个使用默认大小输出缓冲区的缓冲字符输出流。
   3)newLine()
     写入一个行分隔符。
 3.代码:
  //创建一个字符写入流对象。
   FileWriter fw = new FileWriter("buf.txt");

   //为了提高字符写入流效率,加入了缓冲技术。
   //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
   BufferedWriter bufw = new BufferedWriter(fw);

   for (int x=1; x<5; x++)
   {
    bufw.write("abcd"+x);
    buw.newLine();
    bufw.flush();//也可以写完再刷,但是要是停电的话,缓冲中的数据就会释放。
   }
   //记住,只要用到缓冲区,就要记得刷新。
   //bufw.flush();

   //其实关闭缓冲区,就是在关闭缓冲区中的流对象。
   bufw.close();


02.IO流(BufferedReader)

 1.字符读取流缓冲区:
   该缓冲区提供了一个一次读一行的方法readLine,方便于对文本数据的获取。
   当返回null时,表示读到文件末尾。
 2.Reader ----> BufferedReader(java.io包)
   1)从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

   可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。

   通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。
   因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader
  (如 FileReader 和 InputStreamReader)。例如,

   BufferedReader in = new BufferedReader(new FileReader("foo.in"));
   将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine()
   都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
   2)构造函数:
  BufferedReader(Reader in)
    创建一个使用默认大小输入缓冲区的缓冲字符输入流。
   3)readLine()方法:
   public String readLine() throws IOException
    读取一个文本行。通过下列字符之一即可认为某行已终止:
    换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。
   返回:
     包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null.
     (只返回回车符之前的数据内容,并不返回回车符)。
 3.代码:
  //创建一个读取流对象和文件相关联。
   FileReader fr = new FileReader("buf.txt");

   //为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲区对象的构造函数。
   BufferedReader bufr = new BufferedReader(fr);

   String line = null;

   while ((line = bufr.readLine()) != null)
   {
    System.out.println(line);
   }

   bufr.close();

03.IO流(MyBufferedReader)

 readLine的原理如图:Day19-04-readLine的原理图例
 用代码演示readLine的原理:


 明白了BufferedReader类中特有方法readLine的原理后,
 可以自定义一个类中包含一个功能和readLine一致的方法。
 来模拟一下BufferedReader

04.IO流(装饰设计模式)


 1.装饰设计模式:
 当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,
 基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。

 装饰类通常会通过构造方法接收被装饰的对象。
 并基于被装饰的对象的功能,提供更强的功能。

05.IO流(装饰和继承的区别)

 MyReader:专门用于读取数据的类。
  |--MyTextReader
   |--MyBufferTextReader
  |--MyMediaReader
   |--MyBufferMediaReader
  |--MyDateReader
   |--MyBufferDateReader

 class MyBufferReader
 {
  MyBufferReader(MyTextReader text)
  {}
  MyBufferReader(MyMediaReader media)
  {}
 }
 上面这个类扩展性很差。
 找到其参数的共同类型,通过多态的形式,可以提高扩展性。

 class MyBufferReader extends MyReader
 {
  MyBufferReader(MyReader r)//组合结构,我中有你。
  {}
 }

 MyReader:专门用于读取数据的类。
  |--MyTextReader
  |--MyMediaReader
  |--MyDateReader
  |--MyBufferReader

 装饰模式比继承要灵活,避免了继承体系臃肿。
 而且降低了类与类之间的关系。

 装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
 所以装饰类和被装饰类通常都是属于一个体系中的。

06.IO流(LineNumberReader)


 LineNumberReader:

 public class LineNumberReader
        extends BufferedReader
 跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),
 它们可分别用于设置和获取当前行号。

 默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,
 并且可以通过调用 setLineNumber(int) 更改行号。但要注意的是,
 setLineNumber(int) 不会实际更改流中的当前位置;它只更改将由 getLineNumber() 返回的值。

 可认为行在遇到以下符号之一时结束:换行符('\n')、回车符('\r')、回车后紧跟换行符。

 1.构造方法:
  LineNumberReader(Reader in)
     使用默认输入缓冲区的大小创建新的行编号 reader。
 2.特有方法:
   1)getLineNumber
   public int getLineNumber()
     获得当前行号。
   2)setLineNumber
   public void setLineNumber(int lineNumber)
      设置当前行号。
 
07.IO流(字节流File读写操作)


 字符流:
 FileReader
 FileWriter

 BufferedReader
 BufferedWriter

 字节流:
 InputStream  OutputStream

 需求:想要操作图片数据,这时就要用到字节流。

 1.InputStream抽象类
   1)此抽象类是表示字节输入流的所有类的超类。
   2)方法:
  <1>abstract  int read()
     从输入流中读取数据的下一个字节。
  <2>int read(byte[] b)
     从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。

  <3>int available()
     返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。
  <4>void close()
     关闭此输入流并释放与该流关联的所有系统资源。
 2.InputStream ---->  FileInputStream
   1)FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。

   FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader
   2)构造函数:
   FileInputStream(File file)
     通过打开一个到实际文件的连接来创建一个 FileInputStream,
     该文件通过文件系统中的 File 对象 file 指定。
 3.OutputStream抽象类
   1)此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。

   需要定义 OutputStream 子类的应用程序必须始终提供至少一种可写入一个输出字节的方法。
   2)方法:
  <1> void close()
     关闭此输出流并释放与此流有关的所有系统资源。
  <2>void flush()
     刷新此输出流并强制写出所有缓冲的输出字节。
  <3>void write(byte[] b)
     将 b.length 个字节从指定的 byte 数组写入此输出流。
  <4>void write(byte[] b, int off, int len)
     将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
  <5>abstract  void write(int b)
     将指定的字节写入此输出流
 4.OutputStream ----> FileOutputStream
   1)文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。
   文件是否可用或能否可以被创建取决于基础平台。特别是某些平台
   一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。
   在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

   FileOutputStream 用于写入诸如图像数据之类的原始字节的流。
   要写入字符流,请考虑使用 FileWriter
   2)构造方法:
  FileOutputStream(File file)
     创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

08.IO流(练习:拷贝图片)


 1.复制一个图片

  思路:
  1.用字节读取流对象和图片关联。
  2.用字节写入流对象创建一个图片文件,用于存储获取到的图片数据。
  3.通过循环读写,完成数据的存储。
  4.关闭资源。


  也可以用字符流进行读写图片数据,但因为字符需要查哈希表,
  所以查不到的字符就会使图片数据发生变化。这样图片就可能打不开。

 2.演示mp3的复制,通过缓冲区。
  BufferedOutputStream
  BufferedInputStream

09.IO流(读取键盘录入)


 1读取键盘录入:
  System.out:对应的是标准输出设备,控制台。
  System.in :对应的是标准输入设备:键盘。
 2.in
  public static final InputStream in
  “标准”输入流。此流已打开并准备提供输入数据。
  通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

 3.需求:
  通过键盘录入数据。
  当录入一行数据后,就将该行数据进行打印。
  如果录入的数据是over,那么停止录入。

 4.注意:
   ctrl+c :可以强行停止程序,其原理是因为它调用封装了回车换行标记。


10.IO流(读取转换流)


 1.通过刚才的键盘录入一行数据并打印其大写,发现其实就是读一行数据的原理。
   也就是readLine方法。

   能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?

   readLine方法是字符流BufferedReader类中的方法。
   而键盘录入的read方法是字节流InputStream的方法。
   那么能不能将字节流转成字符流,再使用字符流缓冲区的readLine方法呢?
 2.转换流
   Reader ---> InputStreamReader(java.io包)
   1)InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。
   它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

   每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。
   要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

   为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

     BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

   2)构造方法:
 
    InputStreamReader(InputStream in)
     创建一个使用默认字符集的 InputStreamReader。

   3)特有方法:
  <1> void close()
     关闭该流并释放与之关联的所有资源。
  <2>String getEncoding()
     返回此流使用的字符编码的名称。
  <3>int read()
     读取单个字符。
  <4>int read(char[] cbuf, int offset, int length)
     将字符读入数组中的某一部分。
  <5>boolean ready()
     判断此流是否已经准备好用于读取。
    
 3.BufferedReader中有readLine()方法,而且BufferedReader可作用于Reader及其子类。
   InputStreamReader是Reader子类,故可以使用BufferedReader对其进行缓冲区技术高效操作.

 4.代码:

  //获取键盘录入对象。
   InputStream in = System.in;

   //将字节流对象转成字符流对象,使用转换流InputStreamReader.
   InputStreamReader isr = new InputStreamReader(in);
   //为了提高效率,将字符串进行。使用BufferedReader.
   BufferedReader bufr = new BufferedReader(isr);
   String line = null;

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

   bufr.close();

11.IO流(写入转换流)

 1.写入转换流:
    Writer ---> OutputStreamWriter(java.io包)
   1)public class OutputStreamWriterextends WriterOutputStreamWriter 是字符流通向字节流的桥梁:
    可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,
    否则将接受平台默认的字符集。

    每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,
    得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。
    注意,传递给 write() 方法的字符没有缓冲。

    为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,
    以避免频繁调用转换器。例如:

  Writer out
    = new BufferedWriter(new OutputStreamWriter(System.out));
  2)构造函数:
  OutputStreamWriter(OutputStream out)
     创建使用默认字符编码的 OutputStreamWriter。
  3)方法摘要
  <1>void close()
     关闭此流,但要先刷新它。
  <2>void flush()
     刷新该流的缓冲。
  <3>String getEncoding()
     返回此流使用的字符编码的名称。
  <4>void write(char[] cbuf, int off, int len)
     写入字符数组的某一部分。
  <5>void write(int c)
     写入单个字符。
  <6>void write(String str, int off, int len)
     写入字符串的某一部分。
 2.注意:
   BufferedWriter中有newLine()方法(用于写入行分隔符,即换行),而且BufferedWriter可作用于Writer及其子类。
   OutputStreamReader是Writer子类,故可以使用BufferedWriter对其进行缓冲区技术高效操作.


12.IO流(流操作规律-1)
 1.
  1)
  源:键盘录入。
  目地:控制台。

  2)需求:想把键盘录入的数据存储到一个文件中。
  源:键盘。
  目的:文件。

  3)需求:想要将一个文件的数据打印在控制台上。
  源:文件。
  目的:控制台。

 2.流操作的基本规律:
   最痛苦的就是流对象有很多。不知道该用哪一个。
 
   通过两个明确来完成。
  1)明确源和目地。
  源:输入流。InputStream  Reader
  目的:输出注。OutputStream  Writer
  2)操作的数据是否是纯文本。
  是:字符流。
  不是:字节流。
  3)当体系明确受制于人,再明确要使用哪个具体的对象。
  通过设备来进行区分:
  源设备:内存,硬盘。键盘
  目的设备:内存,硬盘,控制台。

 3.将一个文本文件中数据存储到另一个文件中。复制文件。
  1)源:因为是源,所以使用读取流。InputStream  Reader
  是不是操作文本文件。
  是?这时就可以选择Reader
  这样体系就明确了。

  接下来明确要使用该体系中的哪个对象。
  明确设备:硬盘。上一个文件。
  Reader体系中可以操作文件的对象是FileReader

  是否需要提高效率:是!加入Reader体系中缓冲区BufferedReader.

  FileReader fw = new FileReader("a.txt");
  BufferedReader bufr = new BufferedReader(fr);

  2)目的:OutputStream Writer
  是否是纯文本。
  是!Writer.
  设备:硬盘,一个文件。
  Writer体系中可以操作文件的对象FileWriter.
  是否需要提高效率:是!加入Writer体系中缓冲区BufferedWriter

  FileWriter fw = new FileWriter("b.txt");
  BufferedWriter bufw = new BufferedWriter(fw);

 4.练习:将一个图片文件中数据存储到另一个文件中。复制文件。要按照以上格式自己完成三个明确。


13.IO流(流操作规律-2)


 1.需求:将键盘录入的数据保存到一个文件中。
  这个需求中有源和目的都存在。
  那么分别分析
  源:InputStream Reader
  是不是纯文本?是!Reader

   1)设备:键盘,对应的对象是System.in.
  不是选择Reader吗?System.in对应的不是字节流吗?
  为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
  所以既然明确了Reader,那么就将System.in转换成Reader.
  用了Reader体系中转换流,InputStreamReader.

  InputStreamReader isr = new InputStreamReader(System.in);

  需要提高效率吗?需要!BufferedReader
  BufferedReader bufr = new BufferedReader(isr);
  
   2)目的:OutputStream Writer
   是否是纯文本?是!Writer.
   设备:硬盘。一个文件。使用FileWriter.
   FileWriter fw = new FileWriter("c.txt");
   需要提高效率吗?需要。
   BufferedWriter bufw = new BufferedWriter(fw);

 2. 扩展:想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。

  1)目的:OutputStream Writer
     是否是纯文本?是!Writer.
     设备:硬盘。一个文件。使用FileWriter.
   但是FileWriter是使用的默认编码表-GBK。

   但是存储时,需要加入指定编码表utf-8.而指定的编码表只有转换流可以指定。
   所以要使用的对象是OutputStreamWriter.
   而该转换流对象要接收一个节输出流。而且还可以操作的文件的字节输出流。FileOutputStream.

   OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");

   需要高效吗?需要。
   BufferedWriter bufw = new BufferedWriter(osw);

   所以,记住。转换流什么时候使用。字符和字节之间的桥梁,通常,涉及到字符编码转换时。
   需要用到转换流。

 3.注意:InputStreamReader ---> FileReader
   1)InputStreamReader的构造方法:
      InputStreamReader(InputStream in, String charsetName)
    创建使用指定字符集的 InputStreamReader。
   2)FileReader是封装了GBK编码表的字符流。是InputStreamReader的子类。

 4.练习:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。


14.IO流(改变标准输入输出设备)

 1.System类(java.lang)的特有方法:

 1)setIn()
  static void setIn(InputStream in)
     重新分配“标准”输入流。
 2)setOut()
  static void setOut(PrintStream out)
     重新分配“标准”输出流。

 2.OutputStream ---> FilterOutputStream ---> PrintStream

 1)PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
  它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;
  而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,
  可以创建一个 PrintStream;这意味着可在写入 byte 数组之后自动调用 flush 方法,
  可调用其中一个 println 方法,或写入一个换行符或字节 ('\n')。

  PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。
  在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类
 2)构造函数:
  PrintStream(String fileName)
     创建具有指定文件名称且不带自动行刷新的新打印流。

15.IO流(异常的日志信息)


 1.Throwable(java.util包)类的方法:
   1)void printStackTrace()
     将此 throwable 及其追踪输出至标准错误流。
    2)void printStackTrace(PrintStream s)
     将此 throwable 及其追踪输出到指定的输出流。
 2.PrintStream类中的方法:
   1)void print(Object obj)
     打印对象。
   2)void print(String s)
     打印字符串

   3)void println(Object x)
     打印 Object,然后终止该行。
   4)void println(String x)
     打印 String,然后终止该行。
   5) void write(byte[] buf, int off, int len)
     将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。


16.IO流(系统信息)

 1.System类(java.util)中的方法:
    static Properties getProperties()
     确定当前的系统属性。
 2.Hashtable<Object,Object>  ----> Properties类(java.util)
  1)Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
   属性列表中每个键及其对应值都是一个字符串。
  2)特有方法:
    void list(PrintStream out)
     将属性列表输出到指定的输出流。
 3.代码:
  Properties prop = System.getProperties();
  //System.out.println(prop);
  prop.list(new PrintStream("sysinfo.txt"));

 

 

 

.File类(java.io包):
  1)用来将文件或者文件夹封装成对象
  2)方便对文件与文件夹的属性信息进行操作。//流只能操作数据。
  3)File对象可以作为参数传递给流的构造函数。
  4)了解File类中的常用方法。
 2.深入介绍File类
  1)<1>文件和目录路径名的抽象表示形式。
     用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录
  <2>文件系统可以对一个对象设置多个访问权限。例如,一个设置可能适用于对象的所有者,
     另一个设置则可能适用于所有其他用户。对象上的访问权限可能导致此类的某些方法执行失败
  <3>File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变。
  2)字段摘要:
  separator-----跨平台的目录分隔符
  public static final String separator与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
  此字符串只包含一个字符,即 separatorChar。
  3)构造函数:
   <1>public File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
  如果给定字符串是空字符串,那么结果是空抽象路径名。

  参数:
  pathname - 路径名字符串
  抛出:
  NullPointerException - 如果 pathname 参数为 null
   <2>public File(String parent,
    String child)根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
  如果 parent 为 null,则创建一个新的 File 实例,
  这与调用以给定 child 路径名字符串作为参数的单参数 File 构造方法效果一样。

  否则,parent 路径名字符串用于表示目录,child 路径名字符串用于表示目录或文件。
  如果 child 路径名字符串是绝对路径名,则用与系统有关的方式将它转换为一个相对路径名。
  如果 parent 是空字符串,则通过将 child 转换为抽象路径名,并根据与系统有关的默认目录解析结果
  来创建新的 File 实例。否则,将每个路径名字符串转换为一个抽象路径名,
  并根据父抽象路径名解析子抽象路径名。


  参数:
  parent - 父路径名字符串
  child - 子路径名字符串
  抛出:
  NullPointerException - 如果 child 为 null
  <3>public File(File parent,String child)
  根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
  如果 parent 为 null,则创建一个新的 File 实例,
  这与调用给定 child 路径名字符串的单参数 File 构造方法的效果一样。

02-IO流(File对象功能)


 File类常见方法:
 1.创建:
   boolean createNewFile()
     throws IOException
   在指定位置创建文件,如果该文件已经存在,则不创建,返回false.
         和输出流不一样,输出流对象一建立创建文件,而且文件已经存在,会覆盖。

   boolean mkdir():创建文件夹。
   boolean mkdirs():创建多级文件夹。

 2.删除:
   <1>boolean delete()
     删除此抽象路径名表示的文件或目录。 删除失败返回false.
   <2>void deleteOnExit()
     在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。在程序退出时删除指定文件。

   注意:若前面的代码发生异常,则此时后面的删除操作就执行不到,此时就会产生垃圾。
      就算是在finally中删除有时也未必有效。因为正在被流操作的文件会报提示无法删除。
      此时用deleteOnExit()退出时删除方法就很容易解决这个问题了。
    
 3.判断:
  <1>boolean canExecute()
     测试应用程序是否可以执行此抽象路径名表示的文件。
  <2>boolean canRead()
     测试应用程序是否可以读取此抽象路径名表示的文件。
  <3>boolean canWrite()
     测试应用程序是否可以修改此抽象路径名表示的文件。
  <4>int compareTo(File pathname)
     按字母顺序比较两个抽象路径名。
  <5>boolean exists()
     测试此抽象路径名表示的文件或目录是否存在。
  <6>boolean isAbsolute()
     测试此抽象路径名是否为绝对路径名。
  <7>boolean isDirectory()
     测试此抽象路径名表示的文件是否是一个目录。
  <8>boolean isFile()
     测试此抽象路径名表示的文件是否是一个标准文件。
  <9>boolean isHidden()
     测试此抽象路径名指定的文件是否是一个隐藏文件。
 注意:文件夹也可能叫a.txt

 4.获取信息:
  <1>String getName()
     返回由此抽象路径名表示的文件或目录的名称。
  <2>String getParent()
     返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
  <3>File getParentFile()
     返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
  <4>String getPath()
     将此抽象路径名转换为一个路径名字符串。
  <5>String getAbsolutePath()
     返回此抽象路径名的绝对路径名字符串。
  <6>long lastModified()
     返回此抽象路径名表示的文件最后一次被修改的时间。
  <7>long length()
     返回由此抽象路径名表示的文件的长度。
  <8>boolean renameTo(File dest)
     重新命名此抽象路径名表示的文件。
 5.文件列表

 文件列表功能:
  1)static File[] listRoots()
     列出可用的文件系统根。
  2)String[] list()
     返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
  3)String[] list(FilenameFilter filter)
     返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
 6.文件列表2:
  1)String[] list(FilenameFilter filter)
     返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
  2)File[] listFiles()
     返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
  3)File[] listFiles(FileFilter filter)
     返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
  4)File[] listFiles(FilenameFilter filter)
     返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。

03.IO流(列出目录下所有内容-递归)


 1.需求:
   列出指定目录下文件或者文件夹,包含子目录中的内容。
   也就是列出指定目录下所有内容。

 2.递归:
   因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可。
   在列出过程中出现的还是目录的话,还可以再次调用本功能。
   也就是函数自身调用自身。
   这种表现形式,或者编程手法,称为递归。

 3.递归要注意:
  1)限定条件。
  2)要注意递归的次数。尽量避免内存溢出。

 4.原理分析:
   如图:
   Day20-07-递归原理分析图
   Day20-07-递归原理2--求和演示

04.IO流(练习:创建java文件列表)


 1.练习:
  将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
  建立一个java文件列表文件。

 2.思路:
  1)对指定的目录进行递归。
  2)获取递归过程所有的java文件的路径。
  3)将这些路径存储到集合中。
  4)将集合中的数据写入到一个文件中。

05.IO流(Properties简述)


 1.Map ---> Hashtable---->Properties类(java.util包)
  1)Properties是Hashtable的子类。
   也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。

   是集合中和IO技术相结合的集合容器。

   该对象的特点:可以用于键值对形式的配置文件。
        但在加载数据时,需要数据有固定格式:键=值。
  2)构造方法:
   Properties()
      创建一个无默认值的空属性列表。
   Properties(Properties defaults)
      创建一个带有指定默认值的空属性列表。
  3)方法:
   <1>String getProperty(String key)
      用指定的键在此属性列表中搜索属性。
   <2>String getProperty(String key, String defaultValue)
      用指定的键在属性列表中搜索属性。
   <3>Object setProperty(String key, String value)
      调用 Hashtable 的方法 put。
   <4>Set<String> stringPropertyNames()
      返回此属性列表中的键集,其中该键及其对应值是字符串,
      如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。


06.IO流(Properties存取配置文件)

 1.Properties的方法:
  1)void list(PrintStream out)
     将属性列表输出到指定的输出流。
  2)void list(PrintWriter out)
     将属性列表输出到指定的输出流。
  3)void load(InputStream inStream)
     从输入流中读取属性列表(键和元素对)。
  4)void load(Reader reader)
     按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
  5)void store(OutputStream out, String comments)//comments为注释
     以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,
     将此 Properties 表中的属性列表(键和元素对)写入输出流。
  6)void store(Writer writer, String comments)
     以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)
     写入输出字符。

 2.演示:
  如何将流中的数据存储到集合中。
  想要将info.txt中键值数据存到集合中进行操作。
  1)用一个流和info.txt文件关联。
  2)读取一行数据,将该行数据用“=”进行切割。
  3)等号左边作为键,右边作为值。存入到Properties集合中即可。

07.IO流(Properties练习)


 1.需求:
  用于记录应用程序运行次数。
  如果使用次数已到,那么给出注册提示。

 2.分析:
  很容易想到的是:计数器。
  可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行自增。
  可是随着该应用程序的退出,该计数器也在内存中消失了。

  下一次再启动该程序,又重新开始从0计数。
  这样不是我们想要的。

  程序即使结束,该计数器的值也存在。
  下次程序启动在会先加载该计数器的值并加1后再重新存储起来。

  所以要建立一个配置文件。用于记录该软件的使用次数。

  该配置文件使用键值对的形式。
  这样便于阅读数据,并操作数据。

  键值对数据是map集合。
  数据是以文件形式存储,使用io技术。
  那么map+io -->properties.

  配置文件可以实现应用程序数据的共享。

 3.补充:
  配置文件有两种:
  1)以“.properties”结尾的。
    如:name=zhangsan
     age=20;

  2)以".xml"结尾的
    如:
 <persons>
  <person id="001">
   <name>zhangsan</name>
   <age>30</age>
   <address>bj</address>
  </person>
  <person>
   <name>lisi</name>
  </person>
 </persons>

 4. 注意:
   所以要想使用某个软件不续费而继续使用的话,可以删除配置文件即可,
   如果配置文件放在了C:\WINDOWS\sytem32中,则删除也无用。


08.IO流(PrintWriter)

 1.IO包中的其他类
  1)打印流
  PrintWriter与PrintStream
    可以直接操作输入流和文件。
  2)序列流
  SequenceInputStream
    对多个流进行合并。
  3)操作对象
  ObjectInputStream与ObjectOutputStream
    被操作的对象需要实现Serializable(标记接口);
 2.打印流:
  该流提供了打印方法,可以将各种数据类型的数据都原样打印。

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

 3.Writer ---> PrintWriter类(java.io)
  1)向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。
  它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。

  与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format
  的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。
  这些方法使用平台自有的行分隔符概念,而不是换行符。

  此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。
  客户端可能会查询调用 checkError() 是否出现错误。
  2)字段摘要
  protected  Writer out
     此 PrintWriter 的底层字符输出流。
  3)构造方法摘要
   <1>PrintWriter(File file)
     使用指定文件创建不具有自动行刷新的新 PrintWriter。
   <2>PrintWriter(OutputStream out)
     根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
   <3>PrintWriter(OutputStream out, boolean autoFlush)
     通过现有的 OutputStream 创建新的 PrintWriter。
   <4>PrintWriter(String fileName)
     创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
   <5>PrintWriter(Writer out)
     创建不带自动行刷新的新 PrintWriter。
   <6>PrintWriter(Writer out, boolean autoFlush)
     创建新 PrintWriter。
  4)特有方法:
  void println(Object x)
     打印 Object,然后终止该行。
 4.注意:
  System.out ---- PrintStream(OutputStream的子类)
  System.in ----- InputStream


09.IO流(合并流)


 InputStream ---> SequenceInputStream类(java.io包)
  1)SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,
  并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,
  直到到达包含的最后一个输入流的文件末尾为止。
  2)构造方法摘要
   <1>SequenceInputStream(Enumeration<? extends InputStream> e)
     通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
   <2>SequenceInputStream(InputStream s1, InputStream s2)
     通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
  3)方法摘要
   <1>int available()
     返回不受阻塞地从当前底层输入流读取(或跳过)的字节数的估计值,方法是通过下一次调用当前底层输入流的方法。
   <2>void close()
     关闭此输入流并释放与此流关联的所有系统资源。
   <3>int read()
     从此输入流中读取下一个数据字节。
   <4>int read(byte[] b, int off, int len)
     将最多 len 个数据字节从此输入流读入 byte 数组。
10.IO流(切割文件)


合并文件的时候,要用到集合,而Vector的效率太低,所以选择用ArrayList.
读取里要用用序列流SequenceInputStream.但该序列流要传入枚举类型的参数。
而枚举是Vector中的方法,ArrayList 中没有枚举方法,只有相似的Iterator迭代器
。故可建立枚举的匿名类,复写类中的方法以返回调用Iterator的方法即可。

注:匿名内部类访问的局部变量要用final修饰。

 

 

 

以下是我的程序代码:

/*
//流只能操作数据,而要操作被数据封装成文件的信息,必须得用File对象。
//File:用来将文件或者文件夹封闭成对象。
//方便对文件与文件夹的属性信息进行操作。
//File对象可以作为参数传递给流的构造函数。
// 
import java.io.*;
class FileDemo{
 public static void main(String args[]){
  consMethod();
 }
 //创建File对象。
 public static void consMethod(){
  //将a.txt封装成file对象,可以将已有的和末出现的文件或者文件来封装成对象。
  File f1 = new File();
  File f2 = new File("c:\\abc","b.txt");
  //File d =  new File("c:\\abc");
  File f3 = new File(d,"c.txt");
  //File f3 = new File("c:\\abc\\zzz\\a.txt");//这样写不平台。跨。
  sop("f1:"+f1);//File类中封装的什么路径打印的就是什么路径。
  sop("f2:"+f2);//封装相对的打印相对的,封装绝对的打印绝对的。
  sop("f3:"+f3);
 }
 public static void sop(Object o){
  System.out.println(o);
 }
}


File 类常见的方法:
 1 ,创建, boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false,
  和输出流不一样,输出流对象一建立文件,而且文件已经存在,会覆盖掉原来的文件。
 
 2 ,删除, boolean delete();删除失败返回false;
       boolean void deleteOnExit()  在程序退出时,删除指定对象。一般用来删除临时文件。

 3 ,判断  boolean exists();判断文件是否存在。
    boolean isDirectory():判断文件是否是目录。
    boolean isFile();判断是否是文件。
    boolean mkdir();创建目录(文件夹);//该方法只能创建一级目录。
    boolean mkdirs();可创建多级目录。
    boolean isHidden();java中有些文件用流是读不了的(因为访问不了), 尽量不要访问
         文件中被隐藏的文件。所以需要用到这个方法判断一下。
         且该文件必须存在。
    boolean isAbsolute():判断文件是不是绝对路径,文件不需要存在,也可判断。
     
  4 ,获取信息
    getName();
    getPath();你封装的什么路径,我获取的就是什么路径。
    getParent();该方法返回的是绝对路径中的文件父目录。如果File中无明确父目录返回null.如果相对路径中有上一层目录那么该目录就是返回如果。
    File getAbsoluteFile();返回绝对路径对象。File对象toString一下变以字符串。
    String getAbsolutePath();返回绝对路径字符串。它New一下变为File对象。
    long lastModified();返回最后修改的时间。
    long length();大小。
    boolean renameTo(File dest)     重新命名此抽象路径名表示的文件。
    static File[] listRoots();//列出机器中有效的盘符。
    String[] list();//指定目录下的所有文件包含隐藏文件
        //调用list方法的对象必须是封装了一个目录,否则空指针异常。不能封装文件。
    File[] listFiles();

 

//java中有些文件用流是读不了的(因为访问不了), 尽量不要访问
//文件中被隐藏的文件。
import java.io.*;
class FileDemo{
 public static void main(String args[])throws IOException{
  //method_1();
  method_6();
 }
 public static void method_1()throws IOException{
  File f = new File("file.txt");
  sop("create:"+f.createNewFile());//返回真。
  //sop("delete:"+f.delete());
 }
 public static void method_2(){
  File f = new File("file.txt");
  sop("exists:"+f.exists());
  //sop("execute:"+f.canExecute());// 测试应用程序是否可以执行此抽象路径名表示的文件
 }
 public static void method_3(){
  File f = new File("abc\\ab\\aaaa");//在当前目录下创建文件夹。
  sop("mkdirs:"+f.mkdirs());//该方法只能创建一级目录。!!!
 }
 public static void method_4()throws IOException{
  File f = new File("file.txt");
  f.createNewFile();//两者不能同时创建。
  //f.mkdir();
  //记住:在判断文件对象是否是文件或者目录时,必须要先判断该文件对象封装的内容是否存在。通过exists()方法。
  sop("dir:"+f.isDirectory());
  sop("dir:"+f.isFile());
 }
 public static void method_5(){
  File f = new File("a.txt");//abc\\a.txt
  sop("path:"+f.getPath());//你封装的什么路径,我获取的就是什么路径。
  sop("abspath:"+f.getAbsolutePath());//两者一样因为给的路径就是绝对的。
  sop("parent:"+f.getParent());//当没有明确父目录时,返回的是null;
 }
 public static void method_6(){
  File f1 = new File("d:\\java\\day20\\aaa.txt");//该功能类似于剪切。
  File f2 = new File("d:\\java\\day20\\bbb.txt");
  sop("renameTo():"+f1.renameTo(f2));
 }
 public static void sop(Object o){
  System.out.println(o);
 }
}

 

import java.io.*;
class FileDemo{
 public static void main(String args[]){
  //listRootsDemo();
  listDemo();
 }
 public static void listRootsDemo(){
  File[] files = File.listRoots();//列出机器上有效盘符。
  for(File f : files){//高级for循环。
   System.out.println(f);
  }
 }
 public static void listDemo(){
  File f = new File("c:\\abc.txt");//指定目录下的所有文件包含隐藏文件
  for(String s: f.list()){//调用list方法的对象必须是封装了一个目录,否则空指针异常,该文件必须存在。
   System.out.println(s);
  }
 }
}


//文件过滤器。
import java.io.*;
class FileDemo{
 public static void main(String args[]){
  listDemo();
 }
 
 public static void listDemo(){

  D d = new D();
  File f = new File("d:\\");
  String[] str = f.list(d);
  for(String s: str){
   System.out.println(s);
  }
 }
 
}
class D implements FilenameFilter{
 public boolean accept(File dir,String name){
  //System.out.println(name);
  return name.endsWith(".txt");
 }
}


import java.io.*;
class FileDemo{
 public static void main(String args[]){
  File f = new File("c:\\");
  File[] file = f.listFiles();
  for(File f1:file)
   System.out.println(f1.getName());
 }
}


列出指定目录下文件或者文件夹,包含子目录中的内容。
也就是列出指定目录下所有内容。
因为目录中还有目录,只要使用同一个列出目录功能的函数
完成即可,在列出过程中出现的还是目录的话,还可以再次
调用本功能。也就是函数自身调用自身,这种表现形式,称递归。
1 ,递归要注意点:
 一,一定要有限定条件。
 二,要注意递归的次数,尽量避免内存举出。

 //java.lang.StackOverflowError 当应用程序递归太深而发生堆栈溢出时,抛出该错误。

import java.io.*;
class FileDemo{
 public static void main(String args[]){
  File dir = new File("d:\\");
  //showDir(dir);
  System.out.println(getSum(10000));
 }
 public static void showDir(File dir){
  System.out.println(dir);
  File[] files = dir.listFiles();
  for(int x=0;x<files.length;x++){
   if(files[x].isDirectory())
    showDir(files[x]);
   else
    System.out.println(files[x]);
  }
 }
 public static void toBin(int num){
  if(num>0){
   System.out.println(num%2);
   toBin(num/2);
  }
 }
 public static int getSum(int n){
  if(n==1)
   return 1;
  return n+getSum(n-1);
 }
}

 

//代层次的目录
import java.io.*;
class FileDemo{
 public static void main(String args[]){
  File dir = new File("d:\\java\\day20");
  showDir(dir,0);
 }
 public static String getLevel(int level){
  StringBuilder sb = new StringBuilder();
  sb.append("|--");
  for(int x=0;x<level;x++){
   //sb.append("  ");
   sb.insert(0,"  ");
  }
  return sb.toString();
 }

 public static void showDir(File dir,int level){
  System.out.println(getLevel(level)+dir.getName());
  level++;
  File[] files = dir.listFiles();
  for(int x=0;x<files.length;x++){
   if(files[x].isDirectory())
    showDir(files[x],level);
   else
    System.out.println(getLevel(level)+files[x]);
  }
 }
}


//删除文件的原理。
//要Window中,删除目录是从里面往外删除的。
//既然是从里面往外删除的,就需要用到递归。
//隐藏的文件是删除不了的。!!!
import java.io.*;
class FileDemo{
 public static void main(String args[]){
  File dir = new File("d:\\day12");
  removeDir(dir);
 }
 public static void removeDir(File dir){
  File[] files = dir.listFiles();
  for(int x=0;x<files.length;x++){
   
   //    false  false
   //    false  true
   //    true  false

//       true  true
   
   if(!files[x].isHidden()&&files[x].isDirectory())//遍历时,判断是否是隐藏的。
    removeDir(files[x]);
   else
    System.out.println(files[x].toString()+"--file--"+files[x].delete());
  }
  System.out.println(dir+":::dir:::"+dir.delete());
 }
}


练习:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个java文件列表文件。
思路:
1 ,对指定的目录进行递归。
2 ,获取递归过程所有java文件的路径。
3 ,将这些路径存储到集合中。
4 ,将集合中的数据写入到一个文件中。


 3 ,将这些路径存储到集合中。
 4 ,将集合中的数据写入到一个文件中。

 import java.io.*;
 import java.util.*;//因为用到了集合。
 class FileDemo {
  public static void main(String args[])throws IOException{
  File dir = new File("d:\\java");
  List<File> list = new ArrayList<File>();
  fileToList(dir,list);

  File file = new File(dir,"javalist.txt");
  writeToFile(list,file.toString());
  }
  public static void fileToList(File dir,List<File> list){
  File[] files = dir.listFiles();
  for(File file : files){
   if(file.isDirectory())
    fileToList(file,list);
   else{
    if(file.getName().endsWith(".java"))
     list.add(file);
   }
  }
  }
  public static void writeToFile(List<File> list ,String javaListFile)throws IOException{
  BufferedWriter bufw = null;
  try
  {
   bufw = new BufferedWriter(new FileWriter(javaListFile));
   for(File f : list){
    String path = f.getAbsolutePath();
    bufw.write(path);
    bufw.newLine();
    bufw.flush();
   }
  }
  catch (IOException e)
  {
   throw e;
  }finally{
   try
   {
    if(bufw!=null)
     bufw.close();
   }
   catch (IOException e)
   {
    throw e;
   }
  }
  }
 }

 
//合并流的使用。
 import java.io.*;
 import java.util.*;
 class FileDemo {
  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[] b = new byte[1024];
  int len = 0;
  while((len=sis.read(b))!=-1){
   fos.write(b,0,len);
  }
  fos.close();
  sis.close();

  }
 }

 */

 import java.io.*;
 import java.util.*;
 class FileDemo {
  public static void main(String args[])throws IOException{
  merge();
  }
  public static void splitFile()throws IOException{
  FileInputStream fis = new FileInputStream("c:\\1.bmp");
  FileOutputStream fos = null;
  byte[] buf = new byte[1024*50];
  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();
  }
  public static void merge()throws IOException{
  ArrayList<FileInputStream> a1 = new ArrayList<FileInputStream>();
  for(int x=1;x<=2;x++){
   a1.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
  }
  final Iterator<FileInputStream> it = a1.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("c:\\splitfiles\\0.bmp");
  byte[] buf = new byte[1024];
  int len = 0;
  while((len=sis.read(buf))!=-1){
   fos.write(buf,0,len);
  }
  fos.close();
  sis.close();
  }
 }

 

 

 

/*
Thinking_in_java(4_).pdf
Properties 是hashtable的子类,也就是说它具备map集合的特点,
而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合窗口。
该对象的特点:可以用于键值对形式的配置文件。
那么在加载时,需要数据有固定格式:键=值。

在加载数据时,需要数据有固定的格式:键=值。

 Set<String> stringPropertyNames()  返回此属性列表中的键集,其中该键及其对应值是字符串

 

import java.io.*;
import java.util.*;
class PropertiesDemo{
 public static void main(String args[]){
  setAndGet();
 }
 public static void setAndGet(){
  Properties prop = new Properties();
  prop.setProperty("lisi","39");
  prop.setProperty("zhangsan","30");
  //System.out.println(prop);//打印全部内容。
  String value = prop.getProperty("lisi");//取特定值。
  //System.out.println(value);
  
  prop.setProperty("lisi",89+"");
  Set<String> names = prop.stringPropertyNames();//JDK1.6中的方法。
  for(String s : names){
   System.out.println(s+":::"+prop.getProperty(s));
  }
 }
}

// void store(OutputStream out, String comments) //将内存中的数据,存储到文件当中。
//想要将info.txt中的键值数据存到集合中进行操作。
//演示:如何将流中的数据存储到集合中。
//  1 ,用一个流和info.txt文件关联。
  2 ,读取一行数据,将该行数据用“=”进行切割。
  3 ,等号左边作为键,右边作为值,存入到Properties集合中。


import java.io.*;
import java.util.*;
class PropertiesDemo{
 public static void main(String args[])throws IOException{
  loadDemo();
 }
 public static void method1()throws IOException{
  BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));  
  String line = null;
  Properties prop = new Properties();

  while((line=bufr.readLine())!=null){
   String[] arr = line.split("=");
   //System.out.println(arr[0]+arr[1]);
   prop.setProperty(arr[0],arr[1]);
  }
  bufr.close();
  System.out.println(prop);//打印集合中有没有数据。
 }
 public static void loadDemo()throws IOException{
  Properties prop = new Properties();
  FileInputStream fis = new FileInputStream("info.txt");
  prop.load(fis);//将流中的数据加载进集合。
  prop.setProperty("wangwu","39");//修改内存中的内容,但文件中的内容不变。
  FileOutputStream fos = new FileOutputStream("info.txt");
  prop.store(fos,"haha");//注释不能用中文。不识别,把内存中的内容写到文件中。

  //System.out.println(prop);第二种方式 。
  prop.list(System.out);//弟一种方式。

  fos.close();
  fis.close();

 }
}

 

 

//用于记录应用程序运行次数,如果使用次数已到,那么给出注册提示。
//很容易想到的是:计数器。可是该计数器定义在程序中,随着程序的运行而在内存中存在,并进行着自增。
//可是随着该应用程序的退出该计数器也在内存中消失了。下一次又启动该程序,又重新开始从0计数
//这样不是我们想要的,当程序即使结束,该计数器的值也存在,下次程序启动会先加载该计数器的值,并加1后,
//会重新存储起来,所以要建立一个配置文件,用于记录该软件的使用次数。
//该配置文件使用键值对的形式,这样便于阅读数据,并操作数据。
//键值对数据是map集合,数据是以文件形式存储,使用IO技术,那么map+io-->properties
//配置文件可以实现应用程序数据的共享。
import java.io.*;
import java.util.*;
class PropertiesDemo{
 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();


 }
}

 

//打印流:能打印基本数据类型,

//最强大的功能就是能原样打印数据,
BufferedWriter中有newLine方法,而PrintStream中在println()方法。
//凡是能和文件相关的流对象都是比较重要的流对象。
PrintStream:字节打印流
 构造函数可以接收的参数类型:
 1 ,file对象
 2 ,字符串路径
 3 ,字节输出流 OutputStream;
PrintWriter:字符打印流。
 1 ,file对象
 2 ,字符串路径
 3 ,字节输出流。
 4 ,字符输出流。
 

//PrintWriter(OutputStream out, boolean autoFlush)  通过现有的 OutputStream 创建新的 PrintWriter。

 


import java.io.*;
class PropertiesDemo{
 public static void main(String args[])throws IOException{
  BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
  //PrintWriter out = new PrintWriter(System.out,true);//自动刷新。
  PrintWriter out = new PrintWriter(new FileoutputStream("a.txt),true);//自动刷新。
  PrintWriter out = new PrintWriter(new FileWriter("a.txt),true);//自动刷新。
  String line = null;
  while((line=bufr.readLine())!=null){
   if("over".equals(line)) {
    break;
   }
   //out.write(line.toUpperCase());
   out.println(line.toUpperCase());
   //out.flush();
  }
  out.close();
  bufr.close();
 }
}

 

import java.io.*;
class PropertiesDemo{
 public static void main(String args[])throws IOException{
  BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
  //PrintWriter out = new PrintWriter(System.out,true);//自动刷新。
  //PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("a.txt")));//自动刷新。
  PrintWriter out = new PrintWriter(new FileOutputStream("a.txt"),true);//自动刷新。
  String line = null;
  while((line=bufr.readLine())!=null){
   if("over".equals(line)) {
    break;
   }
   //out.write(line.toUpperCase());
   out.println(line.toUpperCase());
   //out.flush();
  }
  out.close();
  bufr.close();
 }
}

 

 


import java.io.*;
class PropertiesDemo{
 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.flush();
  }
  out.close();
  bufr.close();
 }
}


//SequenceInputStream 对多个流进行合并。
1 ,该对象没有对应的OutputStream
2 ,可将多个流对象拼成一个流对象。


import java.io.*;
import java.util.*;
class PropertiesDemo{
 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",true);
  byte[] buf = new byte[1024];
  int len = 0;
  while((len = sis.read(buf))!=-1){
   fos.write(buf,0,len);
  }
  fos.close();
  sis.close();
 }
}

*/

 

class PropertiesDemo{
 public static void main(String args[]){
  
 }
 public static void method1(){
  
 }
}

 

 

 

 

//分割电影。
class FygExercise6{
 public static void main(String args[])throws Exception{
  split();
  //System.out.println(0%100);
 }
 public static void split()throws Exception{
  FileInputStream fis = new FileInputStream("d:"+File.separator+"111.flv");
  FileOutputStream fos = null;
  byte[] buf = new byte[1024*1024];
  int len = 0,j=0;
  int count =0;
  while((len = fis.read(buf))!=-1){
   if(count%200==0){
    //fos = new FileOutputStream("d:\\"+(count/100)+".flv");
    fos = new FileOutputStream("d:\\"+(++j)+".flv");
   }
   fos.write(buf,0,len);
   if((count+1)%200==0){
    System.out.println("第"+j+"个文件 大小"+count+"M");
    fos.close();
   }
   count++;
  } 
  System.out.println("最后一个文件"+" 大小 "+(--count)+"M");
  fos.close();
 }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值