IO流
IO流
一.字符流
- 1.FileReader
- 2.FileWriter
- 3.BufferedReader
- 4.BufferedWriter
二.字节流
- 1.FileInputStream
- 2.FileOutputStream
- 3.BufferedInputStream
- 4.BufferedOutputStream
- IO流
- 一.字符流
- 二.字节流
- 三.装饰设计模式
- 四.流操作的基本规律
- 五.异常日志信息和错误信息
- 四.IO流_Flie类
- 五.util包中Properties类
- 六.io_字节打印流和字符打印流
- 七.io_序列流SequenceInputStream类:将多个输出流串联
- 八.范例:文件的切割与合并
- 九.io_ObjectInputStream和ObjectOutputStream,对象的序列化
- 十.PipedInputStream和PipedOutputStream:管道流
- 十一.RandomAccessFile:该类实例支持对随机访问文件的读取和写入
- 十二.DataInputStream与DataOutputStream:用于操作基本数据类型的流对象
- 十三.ByteArrayInputStream和ByteArrayOutputStream:用于操作字节数组的流对象
一.字符流
- 1.FileReader
- 2.FileWriter
- 3.BufferedReader
- 4.BufferedWriter
1.FileWriter
Writer中子类OutputSteamWriter中已实现子类FileWriter可以对文件进行操作
1.import java.io.*;
2.class FileWriterDemo
3.{
4. public static void main(String[] args) throws Exception
5. {
6. //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件,
7. //而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将会被覆盖,
8. //其实该步就是在明确数据要存放的目的地.
9. FileWriter fw = new FileWriter("e:\\test.txt");
10.
11. //write()方法是将字符串写入流中
12. fw.write("小咩咩是笨蛋");
13.
14. //刷新流对象中的缓冲区的数据,将数据刷到目的地
15. fw.flush();
16.
17. fw.write(",小咩咩喜欢我");
18. //关闭流资源,但是关闭之前会刷新一次内部的缓冲区的数据,刷到目的地,
19. //和flush的区别:flush刷新后,流可以继续使用,close刷新后,会关闭流
20. fw.close();
21. }
22.}
2.FileReader
1.import java.io.*;
2.class FileReaderDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. readMethod();
7. readMethod2();
8.
9. }
10. //方式1:read()
11. public static void readMethod() throws IOException
12. {
13. //创建一个文件读取流对象,和指定名称的文件相关联,
14. //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException
15. FileReader fr = new FileReader("e:\\test1.txt");
16.
17. //read()方法一次读一个字符,而且自动往下读,当文件读完,会返回-1
18. int ch = 0;
19. while ((ch = fr.read()) !=-1)
20. {
21. System.out.println((char)ch);
22. }
23. fr.close();
24. }
25.
26. //方式2:read(char[] buf):将字符读入数组buf,返回读取的字符数,如果已到达流的末尾,则返回 -1
27. public static void readMethod2() throws IOException
28. {
29. FileReader fr = new FileReader("e:\\test1.txt");
30. //一般在实际应用中,在这里定义数组时,定义成1024的整数倍
31. char[] buf = new char[1024];
32. //ch为read(char[] buf)
33. int ch = 0;
34. while ((ch = fr.read(buf)) !=-1)
35. {
36. System.out.print2(new String(buf,0,ch));//这里用到了Stirng中打印数组的一部分的构造方法:String(char[] value, int offset, int count)
37. }
38. fr.close();
39.
40.
41. }
42.}
43.
3.Writer和Reader中的异常
1.import java.io.*;
2.class FileWriterExceptionDemo
3.{
4. public static void main(String[] args) throws Exception
5. {
6. //因为在finally里面有用到变量fw,所以应该将fw定义在try-catch外面
7. FileWriter fw = null;
8.
9. try
10. {
11. //传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写
12. fw = new FileWriter("e:\\test1.txt",true);
13. //\r\n为在Windows里面的换行字符,而在其他里面就直接为\n
14. fw.write("\r\n小咩咩是笨蛋");
15.
16. fw.flush();
17. }
18. catch (IOException e )
19. {
20. System.out.println(e.toString());
21. }
22. //因为关闭流的动作是最后必须执行的动作,所以放在finally里面
23. finally
24. {
25. //close()同样会抛出异常,所以也需要try-catch
26. try
27. {
28. //如果上面的try里面没有创建成功流对象,这里就不能关闭,所以就得判断
29. if (fw !=null)
30. {
31. fw.close();
32. }
33.
34. }
35. catch (IOException e)
36. {
37. System.out.println(e.toString());
38. }
39.
40. }
41.
42.
43.
44. }
45.}
4.利用FileWriter和FileReader来复制文件
文件的拷贝复制:
- 1.创建一个写入流,并创建一个文件用于存储;
- 2.创建一个读取流和要拷贝的文件相关联;
- 3.FileReader流把读取的内容存放在一个容器里面,然后把容器里面的内容写入FileWrite流中,然后通过flush()完成数据储存;
- 4.关闭流
1.import java.io.*;
2.class CopyDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. copy_1();
7. copy_2();
8. }
9. public static void copy_1() throws IOException
10. {
11. FileWriter fw = new FileWriter("e:\\haha.txt");
12. FileReader fr = new FileReader("e:\\test2.htlm");
13. int ch = 0;
14. while ((ch=fr.read())!=-1)
15. {
16. fw.write(ch);
17. }
18. fw.close();
19. fr.close();
20.
21. }
22. public static void copy_2()
23. {
24. FileWriter fw = null;
25. FileReader fr = null;
26. try
27. {
28. fw = new FileWriter("e:\\test3.htlm");
29. fr = new FileReader("FileWriterDemo.java");
30. char[] buf = new char[1024];
31. int length = 0;
32. while ((length=fr.read(buf))!=-1)
33. {
34. fw.write(buf,0,length);
35. }
36. }
37. catch (IOException e)
38. {
39. throw new RuntimeException("读写失败");
40. }
41. finally
42. {
43. if (fw !=null)
44. try
45. {
46. fw.close();
47. }
48. catch (IOException e)
49. {
50. System.out.println(e.toString());
51. }
52. if (fr !=null)
53. try
54. {
55. fr.close();
56. }
57. catch (IOException e)
58. {
59. System.out.println(e.toString());
60. }
61. }
62. }
63.}
64.
5.BufferedWriter
- 1.缓冲区的出现是为了提高流的操作效率的
- 2.在缓冲区创建之前,必须要先有流对象
- 3.缓冲区中提供了一个跨平台的换行符newLine(),类似于Windows里面的\r\n
1.import java.io.*;
2.class BufferedWriterDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. //创建一个字符写入流
7. FileWriter fw = new FileWriter("e:\\test4.txt");
8.
9. //创建一个缓冲区,在缓冲区创建之前,必须要先有流对象
10. BufferedWriter bw = new BufferedWriter(fw);
11. bw.write("test,test,test,test");
12.
13. //缓冲区中换行符
14. bw.newLine();
15.
16. //只要用到缓冲区,都得记得刷新
17. bw.flush();
18.
19. //关闭缓冲区就相当于关闭了缓冲区对应的流,所以不用再关闭流了
20. bw.close();
21. }
22.}
6.BufferedReader
字符读取流缓冲区:BufferedReader
里面有一个重要的方法:readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null.
1.import java.io.*;
2.class BufferedReaderDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. FileReader fr = new FileReader("CopyDemo.java");
7. BufferedReader br = new BufferedReader(fr);
8. String s = null;
9. while ((s = br.readLine()) != null)
10. {
11. System.out.println(s);
12. }
13. }
14.}
7.利用BufferedWriter和BufferedReader复制文件
1./*
2.通过缓冲区复制文件
3.*/
4.import java.io.*;
5.class CopyDemo2
6.{
7. public static void main(String[] args)
8. {
9. BufferedReader br = null;
10. BufferedWriter bw = null;
11. try
12. {
13. br = new BufferedReader(new FileReader("DateDemo.java"));
14. bw = new BufferedWriter(new FileWriter("e:\\test5.txt"));
15. String line = null;
16. while ((line=br.readLine()) !=null)
17. {
18. bw.write(line);
19. //这里必须加入newLine(),因为在readLine()只会读取一行,而不包括行终止符
20. bw.newLine();
21. bw.flush();
22. }
23. }
24. catch (IOException e)
25. {
26. throw new RuntimeException("读写失败");
27. }
28. finally
29. {
30. if (bw != null)
31. {
32. try
33. {
34. bw.close();
35. }
36. catch (IOException e)
37. {
38. throw new RuntimeException("关闭失败");
39. }
40. }
41. if (br != null)
42. {
43. try
44. {
45. br.close();
46. }
47. catch (IOException e)
48. {
49. throw new RuntimeException("关闭失败");
50. }
51. }
52. }
53. }
54.}
55.
8.根据readLine()的原理自定义BufferedReader
1./*
2.明白了readLine()方法的原理后,下面自定义一个类中的功能和readLine()一致的方法,来模拟一下BufferedReader
3.*/
4.import java.io.*;
5.class MyBufferedReaderDemo
6.{
7. public static void main(String[] args) throws IOException
8. {
9. FileReader fr = new FileReader("CollectionDemo.java");
10. MyBufferedReader mybr = new MyBufferedReader(fr);
11. String myline = null;
12. while ((myline=mybr.myReadLine()) !=null)
13. {
14. System.out.println(myline);
15. }
16. mybr.myClose();
17. }
18.}
19.class MyBufferedReader
20.{
21. private FileReader fr;
22. MyBufferedReader(FileReader fr)
23. {
24. this.fr = fr;
25. }
26. public String myReadLine() throws IOException
27. {
28. StringBuilder sb = new StringBuilder();
29. int ch = 0;
30. while ((ch=fr.read()) !=-1)
31. {
32. if (ch=='\r')
33. {
34. continue;
35. }
36. if (ch=='\n')
37. {
38. return sb.toString();
39. }
40. else
41. {
42. sb.append((char)ch);
43. }
44. }
45. //因为在文本文件中可能遇到最后结尾处没有换行符"\n",那么这是的最后一行将不会被return出来
46. //所以这里判断如果StringBuilder里面还有内容,就继续返出来
47. if (sb.length() !=0)
48. {
49. return sb.toString();
50. }
51. return null;
52. }
53. public void myClose() throws IOException
54. {
55. fr.close();
56. }
57.
58.}
9.LineNumberReader
1.LineNumberReader:跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号.默认情况下,行编号从 0 开始
2.继承至BufferedReader
1.import java.io.*;
2.class LineNumberReaderDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. FileReader fr = new FileReader("PersonDemo.java");
7. LineNumberReader lnr = new LineNumberReader(fr);
8. String line = null;
9. lnr.setLineNumber(100);
10. while ((line=lnr.readLine()) !=null)
11. {
12. System.out.println(lnr.getLineNumber()+"::"+line);
13. }
14. }
15.}
10.自定义读取行号的的功能MyLineNumberReader
1.import java.io.*;
2.class MyLineNumberReaderDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. FileReader fr = new FileReader("CollectionDemo.java");
7. MyLineNumberReader mylnr = new MyLineNumberReader(fr);
8. mylnr.setLineNumber(100);
9. String myline = null;
10. while ((myline=mylnr.myReadLine()) !=null)
11. {
12. System.out.println(mylnr.getLineNumber()+"::"+myline);
13. }
14. mylnr.myClose();
15. }
16.}
17.class MyLineNumberReader
18.{
19. private Reader r;
20. private int linenumber;
21. MyLineNumberReader(Reader r)
22. {
23. this.r = r;
24. }
25. public String myReadLine() throws IOException
26. {
27. linenumber++;
28. StringBuilder sb = new StringBuilder();
29. int ch = 0;
30. while ((ch=r.read()) !=-1)
31. {
32. if (ch=='\r')
33. {
34. continue;
35. }
36. if (ch=='\n')
37. {
38. return sb.toString();
39. }
40. else
41. {
42. sb.append((char)ch);
43. }
44. }
45. if (sb.length() !=0)
46. {
47. return sb.toString();
48. }
49. return null;
50. }
51. public void setLineNumber(int linenumber)
52. {
53. this.linenumber = linenumber;
54. }
55. public int getLineNumber()
56. {
57. return linenumber;
58. }
59. public void myClose() throws IOException
60. {
61. r.close();
62. }
63.
64.}
二.字节流
- 1.FileInputStream
- 2.FileOutputStream
- 3.BufferedInputStream
- 4.BufferedOutputStream
1.FileOutputStream和FileInputStream
1.import java.io.*;
2.class FileStreanDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. writeFile();
7. //字符流读取文件的三种方式,最常用的是第二种
8. readFile_3();
9. readFile_2();
10. readFile_1();
11. }
12. public static void writeFile() throws IOException
13. {
14. FileOutputStream fos = new FileOutputStream("e:\\fos.txt");
15. fos.write("abcdefg".getBytes());//这里操作字节流不用flush就直接可以将内容存入文件
16. fos.close();
17. }
18. public static void readFile_3() throws IOException
19. {
20. FileInputStream fis = new FileInputStream("e:\\fos.txt");
21. byte[] bs = new byte[fis.available()];//该方法慎用,因为如果文件过大,造成数组的长度很大,可能内存溢出
22. fis.read(bs);
23. System.out.println(new String(bs));
24. fis.close();
25. }
26. public static void readFile_2() throws IOException
27. {
28. FileInputStream fis = new FileInputStream("DateDemo.java");
29. byte[] bs = new byte[1024];
30. int len = 0;
31. while ((len=fis.read(bs)) !=-1)
32. {
33. System.out.print(new String(bs,0,len));
34. }
35. fis.close();
36. }
37. public static void readFile_1() throws IOException
38. {
39. FileInputStream fis = new FileInputStream("e:\\fos.txt");
40. int ch = 0;
41. while ((ch=fis.read()) !=-1)
42. {
43. System.out.println((char)ch);
44. }
45. fis.close();
46.
47. }
48.}
49.
50.
2.用FileOutputStream和FileInputStream复制图片
复制一个图片
思路:
1.用字节读取流对象和图片关联
2.用字节写入流对象创建一个图片文件,用于存储获取到的图片数据
3.通过循环读写,完成数据的存储
4.关闭资源
1.import java.io.*;
2.class CopyPicDemo
3.{
4. public static void main(String[] args)
5. {
6. FileOutputStream fos = null;
7. FileInputStream fis = null;
8. try
9. {
10. fos = new FileOutputStream("e:\\2.jpg");
11. fis = new FileInputStream("e:\\1.jpg");
12. byte[] by =new byte[1024];
13. int len = 0;
14. while ((len=fis.read(by)) !=-1)
15. {
16. fos.write(by,0,len);
17. }
18. }
19. catch (IOException e)
20. {
21. throw new RuntimeException("读存失败");
22. }
23. finally
24. {
25. if (fos !=null)
26. {
27. try
28. {
29. fos.close();
30. }
31. catch (IOException e)
32. {
33. throw new RuntimeException("关闭失败");
34. }
35. }
36. if (fis !=null)
37. {
38. try
39. {
40. fis.close();
41. }
42. catch (IOException e)
43. {
44. throw new RuntimeException("关闭失败");
45. }
46. }
47. }
48.
49. }
50.}
51.
3.BufferedOutputStream和BufferedInputStream
1.import java.io.*;
2.class BufferedOutputStreamDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. copy_1();
7. }
8. public static void copy_1() throws IOException
9. {
10. BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("e:\\1.jpg"));
11. BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("e:\\3.jpg"));
12. int by = 0;
13. while ((by=bufis.read()) !=-1)
14. {
15. bufos.write(by);
16. }
17. bufis.close();
18. bufos.close();
19. }
20.}
21.
4.自定义字节流缓冲区以及read()和write()方法的特点
Tips
read()和write()方法的特点:read()方法在前面补0,将类型从byte型提升成int型,而write()方法是强制转换为字节,从而保证数据的不变化
程序源码
1.import java.io.*;
2.class CopyPicDemo2
3.{
4. public static void main(String[] args) throws IOException
5. {
6. MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("e:\\1.jpg"));
7. BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("e:\\3.jpg"));
8. int by = 0;
9. while ((by=bufis.myRead()) !=-1)
10. {
11. bufos.write(by);
12. }
13. bufis.myClose();
14. bufos.close();
15. }
16.}
17.class MyBufferedInputStream
18.{
19. private byte[] buf = new byte[1024];
20. private int pos = 0,count = 0;
21. private InputStream in;
22. MyBufferedInputStream(InputStream in)
23. {
24. this.in = in;
25. }
26.
27. //定义myRead()方法,一次读一个字节,从缓冲区(字节数组)中获取
28. public int myRead() throws IOException
29. {
30. if (count==0)
31. {
32. count = in.read(buf);
33. pos = 0;
34. byte b =buf[pos];
35. count--;
36. pos++;
37. return b & 255;
38. //因为如果数据的字节码中可能出现连续的8个1,这样就是-1,read()强转为int型后还是四个8位的1,还是-1,所以将其和255与,这样既保证了数据的原样性,也避免了出现-1
39. }
40. else if (count>0)
41. {
42. byte b = buf[pos];
43. count--;
44. pos++;
45. return b & 255;
46. }
47. else
48. return -1;
49. }
50. public void myClose() throws IOException
51. {
52. in.close();
53. }
54.
55.
56.
57.}
5.System.in
读取键盘录入
System.out:标准输出设备:控制台
System.in:标准输入设备:键盘
public static final InputStream in:“标准”输入流。
1./*
2.需求:
3.通过键盘录入数据,录入一行就打印一行,如果录入的数据是over时就停止录入
4.*/
5.import java.io.*;
6.class ReadIn
7.{
8. public static void main(String[] args) throws IOException
9. {
10. test2();
11.
12.
13. }
14. public static void test2() throws IOException
15. {
16. InputStream in = System.in;
17. StringBuilder sb = new StringBuilder();
18. int ch = 0;
19. /*
20. read()方法是如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
21. 在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
22. 在此处,read()会一直等待键盘录入,一直到出现over
23. */
24. while (true)
25. {
26. ch = in.read();
27. if (ch=='\r')
28. {
29. continue;
30. }
31. if (ch=='\n')
32. {
33. String str = sb.toString();
34. System.out.println(str);
35. if ("over".equals(str))
36. {
37. break;
38. }
39. sb.delete(0,sb.length());
40. }
41. else
42. {
43. sb.append((char)ch);
44. }
45. }
46. }
47. public static void test() throws IOException
48. {
49. InputStream in = System.in;
50. int by = in.read();
51. int by2 = in.read();
52. int by3 = in.read();
53. System.out.println(by);
54. System.out.println(by2);
55. System.out.println(by3);//运行程序录入a,结果为97,13,10.因为\r的ASC码为13,\n的ASC码为10
56. }
57.}
58.
6.InputStreamReader和OutputStreamWriter
- 1.读取转换流:InputStreamReader:是字节流通向字符流的桥梁
- 2.写入转化流:OutputStreamWriter:是字符流通向字节流的桥梁
- 3.System.setIn(new FileInputStream(“haha.txt”)):重新分配“标准”输入流
- 4.System.setOut(new PrintStream(“xiix.txt”)):重新分配“标准”输出流
1.//下面的程序:源:键盘录入;目的:控制台
2.import java.io.*;
3.class TransStreamDemo
4.{
5. public static void main(String[] args) throws IOException
6. {
7. /*
8. //获取键盘录入对象
9. InputStream in = System.in;
10. //将字节流对象转成字符流对象,使用转换流
11. InputStreamReader isr = new InputStreamReader(in);
12. //为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader
13. BufferedReader bufr = new BufferedReader(isr);
14. */
15.
16. //键盘录入最常见写法
17. BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
18.
19. //同样
20. BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
21.
22. String line =null;
23. while ((line=bufr.readLine()) !=null)
24. {
25. bufw.write(line);
26. //要使用newLine()方法就必须使用BufferedWriter对其字符写入流进行装饰
27. bufw.newLine();
28. bufw.flush();//字符输出流必须刷出来
29. //如果不进行停止标识,那么程序会一直等待键盘录入
30. if ("over".equals(line))
31. {
32. break;
33. }
34. }
35. bufr.close();
36. bufw.close();
37. }
38.}
39.
三.装饰设计模式
装饰设计模式:
- 1.当想要对已有的对象进行功能增强时,可以定义类将已有对象传入,基于已有的功能,并提供加强功能,那么自定义的该类称为装饰类.
- 2.装饰类通常会通过构造方法接收被装饰的功能,并基于被装饰的对象的功能,提供更强的功能.
如一个简单的demo 人吃饭,刚开始人穷只是普通的吃饭后来人生活好了吃饭就不一样了增强了吃饭的功能 虽然例子不是恰当 能说明问题就行
1.class PersonDemo
2.{
3. public static void main(String[] args)
4. {
5. Person p = new Person();
6. SuperPerson sp = new SuperPerson(p);
7. sp.superChifan();
8. }
9.}
10.class Person
11.{
12. public void chifan()
13. {
14. System.out.println("吃饭");
15. }
16.}
17.class SuperPerson
18.{
19. private Person p;
20. SuperPerson(Person p)
21. {
22. this.p = p;
23. }
24. public void superChifan()
25. {
26. System.out.println("开胃酒");
27. p.chifan();
28. System.out.println("甜点");
29.
30. }
31.}
Notice
- 1.以上只是简单说明一下,在JAVA IO中用了很多增强 如:FileRead中read()方法 只是一个一个字节去读,为了读得更快在BufferedReader就增强了read()方法而产生了reandLine()一行一行的去读
- 2.有人说没必要那么麻烦:你只要拿superPerson继承person 在覆写person的chiFan()方法不就行了?装饰是构造函数参数传递进行增强,如果为了某个功能而产生子类(继承)那么那个体系是非常臃肿的
- 3.例如:你有个对象有个功能 是在N年前建立的,如今你觉得功能不够用了 写个类把对象传进来就可以解决问题了 如果这个功能写错了 我就把自己写的功能去掉又不影响以前的功能灵活性相当强的。
- 4.装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
- 5.装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。
*/
四.流操作的基本规律
-
1.明确源和目的
源:输入流.InputStream Reader
目的:输出流.OutputStream Writer -
2.操作的数据是否是纯文本
是:字符流
不是:字节流 -
3.当体系明确后,再明确是要使用哪个具体的对象
通过设备来进行区分
源设备:内存,硬盘(File),键盘(System.in)
目的设备:内存,硬盘(File),控制台(System.out)
需求:将键盘录入的数据按照指定的编码表(UTF-8)存入文件
1.源:操作的为纯文本,所以选择reader
设备:键盘.对象为System.in,因为System.in对应的字节流,所有选择转换流InputStreamReader(System.in)
需要高效和功能增强:BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in))
2.目的:操作的数据为出文本,所以选择Writer
设备:硬盘.一个文件,使用FileWriter,但是FileWriter里面是默认的编码表,所以只能选择转换流OutputStreamWriter(new FileOutputStream("xx.txt"),"UTF-8"))
高效和功能增强:BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("xx.txt"),"UTF-8"))
转换流的应用:是字节流和字符流的桥梁,当需要指定编码表时,需要用到转换流
五.异常日志信息和错误信息
1.异常信息
1.import java.io.*;
2.import java.util.*;
3.import java.text.*;
4.class ExceptionInfo
5.{
6. public static void main(String[] args)
7. {
8. try
9. {
10. int[] arr = new int[2];
11. System.out.println(arr[4]);
12. }
13. catch (Exception e)
14. {
15.
16. PrintStream ps = null;
17. try
18. {
19. Date d = new Date();
20. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
21. String s =sdf.format(d);
22. ps = new PrintStream("e:\\haha.txt");
23. ps.println(s);
24. //ps.write(d.toString().getBytes());//因为PrintStream继承于OutputStream,字节流的write()方法不能写入字符串,所以变成字节数组
25. }
26. catch (Exception ex)
27. {
28. throw new RuntimeException("出错");
29. }
30. e.printStackTrace(ps);
31. /*
32. System.setOut(new PrintStream("e:\\exeception.log"));//同样需要try-catch
33. e.printStackTrace(System.out)
34. */
35. }
36. }
37.}
38.
39.
2.系统信息
1.import java.io.*;
2.import java.util.*;
3.class SystemInfo3
4.{
5. public static void main(String[] args) throws IOException
6. {
7. Properties prop = System.getProperties();
8. prop.list(new PrintStream("e:\\systeminof.txt"));//list(PrintStream out) :将属性列表输出到指定的输出流。
9. }
10.}
四.IO流_Flie类
File类
- 1.将文件或者文件夹封装成对象
- 2.方便对文件与文件夹的属性信息进行操作
- 3.File对象可以作为参数传递给流的构造函数
1.File类的基本方法
1.创建
1.boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false,和输出流不一样,输出流对象一建立就创建文件,而且文件已经存在会被覆盖;
2.static File createTempFile(String prefix, String suffix):在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称
3.boolean mkdir():创建此抽象路径名指定的目录,但是只能创建一级目录,返回布尔值;
4.boolean mkdirs():创建此抽象路径名指定的目录,能创建多级目录。
2.删除
1.boolean delete():删除此抽象路径名表示的文件或目录,删除成功返回true,删除失败返回false。
2.void deleteOnExit():在程序退出时删除指定文件。
3.判断
1.boolean canExecute():测试应用程序是否可以执行此抽象路径名表示的文件。
2.boolean canRead():测试应用程序是否可以读取此抽象路径名表示的文件。
3.boolean canWrite():测试应用程序是否可以修改此抽象路径名表示的文件。
4.int compareTo(File pathname):按字母顺序比较两个抽象路径名。
5.
6.boolean exists():测试此抽象路径名表示的文件或目录是否存在。
7.boolean isAbsolute():测试此抽象路径名是否为绝对路径名。
8.boolean isDirectory():测试此抽象路径名表示的文件是否是一个目录。
9.boolean isFile():测试此抽象路径名表示的文件是否是一个标准文件。
10.boolean isHidden():测试此抽象路径名指定的文件是否是一个隐藏文件。
4.获取
1.String getName():返回由此抽象路径名表示的文件或目录的名称。
2.String getParent():返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
3.String getPath():将此抽象路径名转换为一个路径名字符串。
4.String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。
5.long lastModified():返回此抽象路径名表示的文件最后一次被修改的时间。
6.long length():返回由此抽象路径名表示的文件的长度。
7.
8.boolean renameTo(File dest):重新命名此抽象路径名表示的文件。
5.代码示例
1.import java.io.*;
2.class FileDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. method4();
7. }
8. //重命名,移动
9. public static void method4() throws IOException
10. {
11. File f1 = new File("e:\\haha.txt");
12. File f2 = new File("d:\\xixi.txt");
13. sop(f2.renameTo(f1));//我想c盘里面移动不进去.....不知道为什么
14. }
15. //获取
16. public static void method3() throws IOException
17. {
18. File f = new File("e:\\haha1.txt");
19. f.createNewFile();
20. sop(f.getPath());
21. sop(f.getAbsolutePath());
22. sop(f.getParent());//该方法返回的是绝对路径下的父目录,如果相对路径总有上一层目录,那么该目录就是结果
23. sop(f.lastModified());
24. sop(f.length());
25. }
26. //判断
27. public static void method2() throws IOException
28. {
29. File f = new File("e:\\haha1.txt");
30. f.createNewFile();
31. sop(f.exists());
32. sop(f.canExecute());
33. //在判断是否是文件或者文件夹前,必须得判断文件是否存在,因为文件可能没有被创建
34. sop(f.isDirectory());
35. sop(f.isFile());
36. sop(f.isAbsolute());
37.
38. }
39. //创建
40. public static void method1() throws IOException
41. {
42. File f = new File("e:\\","haha.txt");
43. f.createNewFile();
44. //f.delete();
45. File f1 = new File("e:\\haha");
46. f1.mkdir();
47.
48. File f2 = new File("e:\\xixi\\haha");
49. f2.mkdirs();//创建多级目录
50. }
51. //构造
52. public static void consMethod()
53. {
54. //将已有或者未出现的文件或者文件夹封装成对象
55. File f1 = new File("e:\\haha\\a.txt");
56. //File f1 = new File("e:"+File.separator+"haha"+File.separator+"a.txt")//这段代码可以跨平台,可以在Linux下运行
57. //File.separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
58. File f2 = new File("e:","b.txt");
59. File f3 = new File("e:");
60. File f4 = new File(f3,"c.txt");
61. sop(f1);
62. }
63. public static void sop(Object obj)
64. {
65. System.out.println(obj);
66. }
67.}
2.list(),listRoots(),listFiles()
- static File[] listRoots():列出可用的文件系统根。
- String[] list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
- String[] list(FilenameFilter filter):返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
- File[] listFiles():返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
1.import java.io.*;
2.class FileDemo2
3.{
4. public static void main(String[] args)
5. {
6. listFilesDemo();
7. }
8. //真实开发中很常用listFiles()
9. //File[] listFiles():返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
10. public static void listFilesDemo()
11. {
12. File dir = new File("e:\\");
13. File[] arr = dir.listFiles();
14. for (File f : arr)
15. {
16. System.out.println(f.getName()+" "+f.length());//这里得到该路径下所有文件和文件夹,以及他们的大小,但是文件夹不能得到大小,为0
17. }
18. }
19.
20. //String[] list(FilenameFilter filter):返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
21. public static void listDemo2()
22. {
23. File dir = new File("e:\\java\\");
24. String[] arr = dir.list(new FilenameFilter()//使用了匿名内部类
25. {
26. public boolean accept(File dir,String name)
27. {
28. return name.endsWith(".java");
29. }
30. });
31. System.out.println(arr.length);
32. for (String name : arr)
33. {
34. System.out.println(name);
35. }
36. }
37.
38.
39. //String[] list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
40. public static void listRootsDemo()
41. {
42. File[] files = File.listRoots();//静态方法,列出可用的文件系统根。
43. for (File f : files)
44. {
45. System.out.println(f);//结果为列出计算机里面所有的盘符,c:\ d:\
46. System.out.println(f.length());//结果为0
47. }
48. }
49.
50. //static File[] listRoots():列出可用的文件系统根。
51. public static void listDemo()
52. {
53. File f = new File("e:\\");//调用list()方法的File对象必须是封装的一个目录,且该目录必须存在
54. String[] str = f.list();
55. for (String s : str)
56. {
57. System.out.println(s);//File f = new File("e:\\haha.txt")如果上面是这样的,那么这里会出现空指针异常,因为f是个文件,那么str数组不存在,所以空指针异常
58. }
59. }
60.}
61.
3.列出指定目录下文件,递归方法
- 需求:
列出指定目录下文件或者文件夹,包含子目录中的文件,也就是列出指定目录下所有内容- 分析:
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,
在列出过程中出现的还有目录的话,还可以再次调用本功能,
也就是函数自身调用自身,这种编程手法称为递归
递归要注意
1.限定条件
2.要注意递归的次数,尽量避免内存溢出
1.import java.io.*;
2.class FileDemo3
3.{
4. public static void main(String[] args)
5. {
6. File dir = new File("g:\\");
7.
8.
9. showDir(dir,0);
10. }
11. public static void showDir(File dir,int level)
12. {
13. System.out.println(getLevel(level)+dir);
14. level++;
15. File[] files = dir.listFiles();
16. if (files != null)//如果文件夹为空,这里会报空指针异常
17. {
18. for (int x=0; x<files.length; x++)
19. {
20. if (files[x].isDirectory())
21. {
22. showDir(files[x],level);
23. }
24. else
25. System.out.println(getLevel(level)+files[x]);
26. }
27. }
28. }
29. //在打印出的结果中加入层次感
30. public static String getLevel(int level)
31. {
32. StringBuffer sb = new StringBuffer();
33. for (int x=0; x<level; x++)
34. {
35. sb.append("|--");
36. }
37. return sb.toString();
38. }
39.}
40.
上面程序的结果
递归的流程图
4.删除指定目录下的文件,递归方法
- 1.删除原理:在Windows中,删除目录从里面往外删除,既然是从里面往外删除,就需要用到递归
- 2.Java删除文件的文件不会放在回收站
1.import java.io.*;
2.class removeDirDemo
3.{
4. public static void main(String[] args)
5. {
6. File dir = new File("e:\\haha");
7. removeDir(dir);
8. }
9. public static void removeDir(File dir)
10. {
11. File[] files = dir.listFiles();
12. for (int x=0; x<files.length; x++)
13. {
14. if (files[x].isDirectory())
15. {
16. removeDir(files[x]);
17. }
18. else
19. System.out.println(files[x].getName()+" :file: "+files[x].delete());
20. }
21. System.out.println(dir.getName()+" :dir: "+dir.delete());//删除文件夹
22. }
23.}
5.将一个指定目录下的.java文件的绝对路径存储到一个文本文件
练习:
将一个指定目录下的.java文件的绝对路径存储到一个文本文件中,建立一个Java文件列表文件.
思路:
1.对指定的目录进行递归;
2.获取递归过程所有的java文件的路径;
3.将这些路径存储到集合中;
4.将集合中的数据存入文件中去;
1.import java.io.*;
2.import java.util.*;
3.class JavaFileListDemo
4.{
5. public static void main(String[] args) throws IOException
6. {
7. File f = new File("e:\\java");
8. List<String> list = new ArrayList<String>();
9. fileToList(f,list);
10. File file = new File("e:\\","xixi.txt");
11. writeToFile(list,file.toString());//File.toString():返回此抽象路径名的路径名字符串。
12. }
13. public static void fileToList(File dir,List<String> list)
14. {
15. File[] files = dir.listFiles();
16. for (File file : files)
17. {
18. if (file.isDirectory())
19. {
20. fileToList(file,list);
21. }
22. else
23. {
24. if (file.getName().endsWith(".java"))
25. {
26. list.add(file.getAbsolutePath());
27. }
28. }
29. }
30. }
31. public static void writeToFile(List<String> list,String filename) throws IOException
32. {
33. BufferedWriter bufw = null;
34. try
35. {
36. bufw =new BufferedWriter(new FileWriter(filename));
37. for (int x=0; x<list.size(); x++)
38. {
39. bufw.write(list.get(x));
40. bufw.newLine();
41. }
42.
43. bufw.flush();
44. }
45. catch (IOException e)
46. {
47. throw e;
48. }
49. finally
50. {
51. try
52. {
53. if (bufw !=null)
54. {
55. bufw.close();
56. }
57. }
58. catch (IOException e)
59. {
60. throw e;
61. }
62. }
63. }
64.}
五.util包中Properties类
- Properties是Hashtable的子类,也就是说它具备Map集合的特点,而且里面的键值对都是字符串;
- Properties是集合中和IO技术相结合的集合容器,该对象可以用于键值对形式的配置文件;
- 在加载时,需要数据有固定的格式:键=值
1.import java.util.*;
2.import java.io.*;
3.class PropertiesDemo
4.{
5. public static void main(String[] args) throws IOException
6. {
7. loadMethod();
8. }
9. public static void loadMethod() throws IOException
10. {
11. FileInputStream fis =new FileInputStream("e:\\haha.txt");
12. Properties prop = new Properties();
13. prop.load(fis);
14. FileOutputStream fos = new FileOutputStream("e:\\haha.txt");
15. prop.setProperty("bv","15555");
16. prop.list(System.out);
17. prop.store(fos,"haha");
18. fis.close();
19. fos.close();
20. }
21.
22. //将e:\\haha.txt文件中的键值对信息存到Propertise集合中进行操作
23. /*
24. 1.用一个流和haha.txt文件关联;
25. 2.读取一行数据,将该行数据用"="进行分割;
26. 3.等号左边为键,右边为值存入Propertise集合中
27. */
28. public static void method() throws IOException
29. {
30. BufferedReader bufr = new BufferedReader(new FileReader("e:\\haha.txt"));
31. String line = null;
32. Properties prop = new Properties();
33. while ((line=bufr.readLine()) !=null)
34. {
35. String[] arr = line.split("=");
36. prop.setProperty(arr[0],arr[1]);
37. }
38. bufr.close();
39. System.out.println(prop);
40.
41.
42. }
43. public static void setAndGet()
44. {
45. Properties prop = new Properties();
46. prop.setProperty("yangyang","18");
47. prop.setProperty("biaobiao","25");
48. System.out.println(prop);//结果:{biaobiao=25, yangyang=18}
49. String value = prop.getProperty("yangyang");
50. System.out.println(value);
51. Set<String> names = prop.stringPropertyNames();
52. for (String s : names)
53. {
54. System.out.println(s+"="+prop.getProperty(s));
55. }
56. }
57.}
58.
练习:用本文记录应用程序运行次数
练习:
用于记录应用程序运行次数,如果使用次数一到,就给出注册提示
思路:
建立配置文件,用于记录该软件运行次数
1.import java.io.*;
2.import java.util.*;
3.class RunCount
4.{
5. public static void main(String[] args) throws IOException
6. {
7. Properties prop = new Properties();
8. File file = new File("e:\\hehe.txt");
9. if (!(file.exists()))
10. {
11. file.createNewFile();
12. }
13. InputStream ips = new FileInputStream(file);
14. prop.load(ips);
15. String value = prop.getProperty("times");
16. int count = 0;
17. if (value !=null)
18. {
19. count = Integer.parseInt(value);
20.
21. if (count>=5)
22. {
23. System.out.println("使用结束,请注册");
24. return;
25. }
26. }
27. count++;
28. prop.setProperty("times",count+"");
29. OutputStream ops = new FileOutputStream(file);
30. prop.store(ops,"");
31. ips.close();
32. ops.close();
33. }
34.}
六.io_字节打印流和字符打印流
字节打印流
PrintStream,父类是OutputStream
构造函数可以接收的参数形式:
1.file对象,File
2.字符串路径,String
3.字节输出流,OutputStream
PrintStream(File file):创建具有指定文件且不带自动行刷新的新打印流。
PrintStream(File file, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
PrintStream(OutputStream out):创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush):创建新的打印流。
PrintStream(OutputStream out, boolean autoFlush, String encoding):创建新的打印流。
PrintStream(String fileName):创建具有指定文件名称且不带自动行刷新的新打印流。
PrintStream(String fileName, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流。
字符打印流
PrintWriter,父类是Writer
构造函数可以接收的参数形式:
1.file对象,File
2.字符串路径,String
3.字节输出流,OutputStream
4.字符输出流,Writer
1.import java.io.*;
2.class PrintStreamDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
7. PrintWriter out = new PrintWriter(new FileWriter("e:\\xixi.txt"),true);//如果为 true,则每当写入 byte 数组、调用其中一个 println 方法或写入换行符或字节 ('\n') 时都会刷新输出缓冲区
8. String line = null;
9. while ((line=bufr.readLine())!=null)
10. {
11. if ("over".equals(line))
12. {
13. break;
14. }
15. out.println(line.toUpperCase());
16. //out.flush();//因为上面自动行刷新了,所以这里不用刷新,也照样每行刷入文件
17. }
18. bufr.close();
19. out.close();
20. }
21.}
22.
七.io_序列流SequenceInputStream类:将多个输出流串联
SequenceInputStream:将多个输出流串联,父类是InputStream
构造方法:
- SequenceInputStream(Enumeration<? extends InputStream> e) :通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
- SequenceInputStream(InputStream s1, InputStream s2) :通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。
1.import java.io.*;
2.import java.util.*;
3.class SequenceInputStreamDemo
4.{
5. public static void main(String[] args) throws IOException
6. {
7. Vector<FileInputStream> v = new Vector<FileInputStream>();
8. v.add(new FileInputStream("e:\\1.txt"));
9. v.add(new FileInputStream("e:\\2.txt"));
10. v.add(new FileInputStream("e:\\3.txt"));
11. //Vector集合中方法Enumeration<E> elements():返回此向量的组件的枚举。
12. Enumeration<FileInputStream> en = v.elements();
13. SequenceInputStream sis = new SequenceInputStream(en);
14. OutputStream ops = new FileOutputStream("e:\\6.txt");
15. byte[] arr = new byte[1024];
16. int len = 0;
17. while ((len=sis.read(arr)) !=-1)
18. {
19. ops.write(arr,0,len);
20. ops.flush();
21. }
22. sis.close();
23. ops.close();
24.
25. }
26.}
27.
八.范例:文件的切割与合并
1./*
2.文件的切割与合并
3.*/
4.import java.io.*;
5.import java.util.*;
6.class splitFileDemo
7.{
8. public static void main(String[] args) throws IOException
9. {
10. //splitFile();
11. merge();
12. }
13. //文件切割
14. public static void splitFile() throws IOException
15. {
16. FileInputStream fis = new FileInputStream("e:\\1\\1.jpg");
17. FileOutputStream fos = null;
18. byte[] arr = new byte[1024*1024*2];
19. int len = 0;
20. int num = 1;
21. while ((len=fis.read(arr)) !=-1)
22. {
23. fos = new FileOutputStream("e:\\1\\"+(num++)+".part");
24. fos.write(arr,0,len);
25. fos.close();
26. }
27. fis.close();
28. }
29. //文件合并
30. public static void merge() throws IOException
31. {
32. //因为Vector的效率很低,所有我们用ArrayList,但是里面没有Enumeration,所以重写Enumeration
33. ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
34. for (int x=1; x<=4; x++)
35. {
36. al.add(new FileInputStream("e:\\1\\"+x+".part"));
37. }
38. Iterator<FileInputStream> it = al.iterator();
39. Enumeration<FileInputStream> en =new Enumeration<FileInputStream>()
40. {
41. public boolean hasMoreElements()
42. {
43. return it.hasNext();
44. }
45. public FileInputStream nextElement()
46. {
47. return it.next();
48. }
49. };
50. SequenceInputStream sis = new SequenceInputStream(en);
51. FileOutputStream fos = new FileOutputStream("e:\\1\\2.jpg");
52. byte[] arr = new byte[1024];
53. int len = 0;
54. while ((len=sis.read(arr)) !=-1)
55. {
56. fos.write(arr,0,len);
57. fos.flush();
58. }
59. sis.close();
60. fos.close();
61. }
62.
63.}
九.io_ObjectInputStream和ObjectOutputStream,对象的序列化
ObjectStreamDemo
1.*/
2.import java.io.*;
3.class ObjectStreamDemo
4.{
5. public static void main(String[] args) throws Exception
6. {
7. //writeObj();
8. readObj();
9. }
10. public static void writeObj() throws IOException
11. {
12. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\person.object"));
13. oos.writeObject(new Person("zhangsan",12,"Fr"));//因为在Person类中country是静态的,成员被静态修饰后,不能被序列化的,因为静态在方法区,只能将堆内存中序列化,这里打印结果还是cn
14. oos.close();
15. }
16. public static void readObj() throws Exception
17. {
18. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\person.object"));
19. Person p = (Person)ois.readObject();
20. System.out.println(p.toString());////成员被transient修饰,保证了该成员在堆内存中存在,不能存入文件,所以结果为age为0
21.
22. }
23.}
Person类
1.import java.io.*;
2.class Person implements Serializable
3.{
4. static final long serialVersionUID = 42L;
5. private String name;
6. transient int age;//成员被transient修饰,保证了该成员在堆内存中存在,不能存入文件
7. static String country = "cn";//成员被静态修饰后,不能被序列化的,因为静态在方法区,只能将堆内存中序列化
8. Person(String name,int age,String country)
9. {
10. this.name = name;
11. this.age = age;
12. this.country = country;
13. }
14. public String toString()
15. {
16. return name+":"+age+country;
17. }
18.}
十.PipedInputStream和PipedOutputStream:管道流
public class PipedInputStream extends InputStream:管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。
不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。
1.import java.util.*;
2.import java.io.*;
3.class PipedStreamDemo
4.{
5. public static void main(String[] args) throws IOException
6. {
7. PipedInputStream pis = new PipedInputStream();
8. PipedOutputStream pos = new PipedOutputStream();
9. pis.connect(pos);
10. Read r = new Read(pis);
11. Write w = new Write(pos);
12. Thread t1 = new Thread(r);
13. Thread t2 = new Thread(w);
14. t1.start();
15. t2.start();
16. }
17.}
18.class Read implements Runnable
19.{
20. private PipedInputStream pis;
21. Read(PipedInputStream pis)
22. {
23. this.pis = pis;
24. }
25. public void run()
26. {
27. try
28. {
29. byte[] arr = new byte[1024];
30. System.out.println("等待数据写入,阻塞");
31. int len = pis.read(arr);
32. System.out.println("数据写入成功,阻塞结束");
33. String s = new String(arr,0,len);
34. System.out.println(s);
35. pis.close();
36. }
37. catch (IOException e)
38. {
39. throw new RuntimeException("读取失败");
40. }
41. }
42.}
43.class Write implements Runnable
44.{
45. private PipedOutputStream pos;
46. Write(PipedOutputStream pos)
47. {
48. this.pos = pos;
49. }
50. public void run()
51. {
52. try
53. {
54. System.out.println("等待6秒后,写入数据");
55. Thread.sleep(6000);//让写入线程等待6秒后才写入数据
56. pos.write("数据来了".getBytes());
57. pos.close();
58. }
59. catch (Exception e)
60. {
61. throw new RuntimeException("写入失败");
62. }
63. }
64.}
十一.RandomAccessFile:该类实例支持对随机访问文件的读取和写入
RandomAccessFile:该类实例支持对随机访问文件的读取和写入
- 1.该类不算是IO体系中的子类,而是直接继承Object;
- 2.该类是IO包中的成员,具备读写的功能,里面封装了字节输入流和字节输出流;
- 3.内部封装了数组,并可以通过指针对数组的元素进行操作,通过getFilePointer获取指针位置,通过seek改变指针位置;
- 4.该类只能操作文件,而且操作文件模式分为:只读(r),读写(wr),以及其他
RandomAccessFile(File file, String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。- 5.如果模式为r,不会创建文件,只读取,如果文件不存在,则会出现异常;如果模式为rw,当文件存在不会覆盖,而之前的OutputStream会覆盖文件,文件不存在会创建文件;
- 6.该类可以实现数据的分段写入,比如多线程下载
1.import java.io.*;
2.class RandomAccessFileDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. //writeFile();
7. readFile();
8. //writeFile2();
9. }
10. public static void writeFile() throws IOException
11. {
12. RandomAccessFile raf = new RandomAccessFile("e:\\hh.txt","rw");
13. raf.write("张三".getBytes());
14. raf.writeInt(98);
15.
16. raf.write("李四".getBytes());
17. raf.writeInt(97);//按四个字节将 int 写入该文件
18. raf.close();
19. //在hh.txt中的结果是:张三 b李四 a
20. }
21. public static void readFile() throws IOException
22. {
23. RandomAccessFile raf = new RandomAccessFile("e:\\hh.txt","rw");
24. raf.seek(8);//将指针调到指定位置开始读取数据
25. byte[] arr = new byte[4];
26. raf.read(arr);
27. String s = new String(arr);
28. System.out.println(s);
29. int i = raf.readInt();//接着上一步读取4个字节
30. System.out.println(i);
31. raf.close();
32.
33.
34. }
35. public static void writeFile2() throws IOException
36. {
37. RandomAccessFile raf = new RandomAccessFile("e:\\hh.txt","rw");
38. raf.seek(8*3);//将指针指到第24位开始写数据
39. raf.write("赵六".getBytes());
40. raf.write(103);
41. raf.close();
42.
43. }
44.}
45.
十二.DataInputStream与DataOutputStream:用于操作基本数据类型的流对象
1.import java.io.*;
2.class DateStreamDemo
3.{
4. public static void main(String[] args) throws IOException
5. {
6. //writeData();
7. //readData();
8. //writeUTFDemo();
9. readUTFdemo();
10. }
11. public static void writeData() throws IOException
12. {
13. DataOutputStream dos = new DataOutputStream(new FileOutputStream("e:\\xixi.txt"));
14. dos.writeInt(122);
15. dos.writeBoolean(true);
16. dos.writeDouble(52.24);
17. dos.close();
18. }
19. public static void readData() throws IOException
20. {
21. DataInputStream dis = new DataInputStream(new FileInputStream("e:\\xixi.txt"));
22. int i = dis.readInt();
23. Boolean b = dis.readBoolean();
24. Double d = dis.readDouble();
25. System.out.println(i);
26. System.out.println(b);
27. System.out.println(d);
28. dis.close();
29. }
30. public static void writeUTFDemo() throws IOException
31. {
32. DataOutputStream dos = new DataOutputStream(new FileOutputStream("e:\\hehe.txt"));
33. dos.writeUTF("你好");//使用 UTF-8 修改版编码,所以读取的话也得是readUTF()
34. /*
35. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e:\\tuf-8.txt","utf-8"));
36. osw.write("你好")//这样就是按照utf-8写入,而不是修改版
37. */
38. dos.close();
39. }
40. public static void readUTFdemo() throws IOException
41. {
42. DataInputStream dis = new DataInputStream(new FileInputStream("e:\\hehe.txt"));
43. String s = dis.readUTF();
44. System.out.println(s);
45. dis.close();
46. }
47.
48.}
49.
十三.ByteArrayInputStream和ByteArrayOutputStream:用于操作字节数组的流对象
ByteArrayInputStream和ByteArrayOutputStream:用于操作字节数组的流对象
- 1.ByteArrayInputStream:在构造时,需要接收数据源.而且数据源是一个字节数组;
- 2.ByteArrayOutputStream:在构造时,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组;
- 3.因为这个两个流对象都操作数组,并没有系统资源,所以不会抛异常,也不用close关闭;
- 4.同样还有另外操作字符数组的流:CharArrayReader和CharArrayWriter
- 5.操作字符串的流:StringReader和StringWriter
源:
键盘(System.in), 硬盘(FileStream), 内存(ByteArrayInputStream)
目的:
键盘(System.out), 硬盘(FileStream), 内存(ByteArrayOutputStream)
1.import java.io.*;
2.class ByteArrayDemo
3.{
4. public static void main(String[] args)
5. {
6. ByteArrayInputStream bis = new ByteArrayInputStream("adferd".getBytes());
7. ByteArrayOutputStream bos = new ByteArrayOutputStream();
8. int by = 0;
9. while ((by=bis.read())!=-1)
10. {
11. bos.write(by);
12. }
13. System.out.println(bos.size());
14. System.out.println(bos.toString());
15. }
16.}
17.