Java IO输入输出

学前知道

Java的IO使用“”的概念来表示。IO流涉及到数据源和目的地。流,是从源“流向”目的的数据流。

Java将各种数据源目标之间数据的传输统一抽象为流,通过对流对象的操作来完成I/O功能。

数据源可以是键盘、文件、应用程序、鼠标、网络连接。数据目的地可以是屏幕、文件、应用程序、网络连接。

无论数据从哪种数据源到哪种数据目的地,也无论数据是哪种类型,IO操作的基本方法是一样的

输入:创建一个输入流类对象,读数据,关闭流。

输出:创建一个输出流类对象,写数据,关闭流。

可以将理解为连接数据源和目的的管道

按照数据流的方向分为输入流和输出流。

按照流处理数据类型的不同分为字节流和字符流。

Java IO的API使用Java.IO包其中超过50个类(可以自己查看Java API文档,标记为常用):

下面为object的四个直接子类(四个抽象类) :

注:

文本文件的输入输出推荐使用字符流。(防止乱码-->字符与子节类型占用长度的区别)

其它的,比如,视频,音频,word文档(特别的)推荐使用字节流。(这类型的文件不支持字节流处理)


小点与练习

inputstream抽象类:

InputStream类中的常用方法:

int available()返回输入流中下一次调用能够不受阻塞的读取或跳过的字节数。

void close()关闭输入流并释放相关所有系统资源。

void mark(int readlimit)标记输入流的当前位置。

abstract int read()从输入流中读取一个字节。该方法的属性为abstract,必须由子类实现。

int read(byte[] b)从输入流中读取一定数量的字节存入字节数组b,并返回读取的字节数。

int read(byte[] b, int off, int len) 从输入流中读取最多len个字节存入字节数组b,读取的第一个字节存入b[off]中,依次类推。

void reset()将流重新置位为上次mark的位置。

long skip(long n)跳过输入流中的指定数量n个字节。

outputstream抽象类:

 

OutputStream类中的常用方法:

abstract void write(int b)将整形b的低字节写到输出流。该方法的属性为abstract,必须为子类所实现。

void write(byte b[])把字节数组b中的b.length个字节写输出流。

void write(byte b[], int off, int len)把字节数组b中从off开始的len个字节写到输出流。

void flush()有时写到输出流的字节并没有被真正发送出去,而是被缓存,达到一定的积累才被真正写出。这是流的内部实现为了提高效率而设计如此的。flush( )方法强制缓存的数据立即执行写操作。

void close()关闭输出流并释放与之相关关的所有系统资源。

第一个案例:

 1 public class FileRW {
 2     
 3     /*1.完成一个完整的文件读写案例(用java的字节流写一个文件复制器软件),例如:把c:/1.txt完整复制到d:\1.txt    
 4     扩展部分:考虑单个字节读写和提高效率读写方式*/
 5     public void fileCopy() throws IOException{
 6         FileInputStream fis = new FileInputStream("c:/1.txt");
 7         FileOutputStream fos = new FileOutputStream("d:/1.txt");
 8         
 9         int len;
10         byte[] b = new byte[1024];
11         while((len = fis.read(b)) != -1){
12             fos.write(b, 0, len);
13         }
14         fis.close();
15         fos.close();
16     }
View Code
 1 public class Text {
 2 
 3     public static void main(String[] args) throws IOException {
 4         // TODO Auto-generated method stub
 5         FileRW fileRW = new FileRW();
 6 
 7         fileRW.fileCopy();
 8         
 9     }
10 
11 }
View Code

第二个案例:

 1 //    2.做一个文本文件过滤器组件,要求,用代码实现读取一个文本文件,进行处理,把文件里面的‘TMD’替换成'***'
 2     //第一种
 3     /*public void filter() throws IOException{
 4         FileReader fr = new FileReader("d:/1.txt");
 5         char[] c = new char[1];        //先一个字符读取
 6         while( fr.read(c) != -1){
 7             if (c[0] == 'T') {
 8                 char[] ch = new char[2];    //等查找到T使用两个字符读取
 9                 fr.read(ch);
10                 if (ch[0] == 'M' && ch[1] == 'D') {
11                     String string = new String("TMD");
12                     System.out.print(string.replace("TMD", "***"));
13                     continue;
14                 }
15                 else {
16                     System.out.print(c);
17                     System.out.print(ch);
18                     continue;
19                 }
20             }
21             System.out.print(c);
22         }
23         fr.close();
24     }*/
25     //第二种比上一个快
26     public void filter() throws IOException{
27         FileReader fr = new FileReader("d:/1.txt");
28         char[] c = new char[1024];    
29         while( fr.read(c) != -1){
30             String s = new String(c);
31             s = s.replace("TMD", "***");
32             System.out.println(s);
33         }
34         fr.close();
35     }
View Code
 1 public class Text {
 2 
 3     public static void main(String[] args) throws IOException {
 4         // TODO Auto-generated method stub
 5         FileRW fileRW = new FileRW();
 6     
 7         fileRW.filter();
 8 
 9     }
10 
11 }
View Code

reader抽象类:

Reader类中常用的方法:

int read() 读取单个字符。

int read(char[] cbuf) 从输入流中读取一定数量的字符到字符数组cbuf。

int read(char[] cbuf,int off,int len) 将输入流中最多len个字符读入字符数组cbuf的off位置开始的部分。

long skip(long n) 跳过次输入流中的指定数量的字符。

void mark(int readAheadLimit) 标记输入流的当前位置。

void reset() 重置输入流到上次mark方法标记的位置。

void close()关闭输入流并释放与流相关的所有系统资源。

boolean ready() 判断输入流是否可读。

writer抽象类:

Writer类中的常用方法:

void write(int c) 将指定的字符写入输出流。

void write(char[] cbuf) 将指定的字符数组cbuf的内容写入输出流。

void write(char[] cbuf,int off, int len) 把字节数组b中从索引off开始的len个字符写入输出流。

write(String str) 将指定字符串str的各个字符写入输出流。

write(String str,int off,int len) 将指定字符串str从off位置开始的len个字符写入输出流。

void flush() 刷新输出流并强制写出缓冲区中的输出字符。

void close() 关闭此输出流并释放与之相关的系统资源。

Writer append(char c)把字符c追加到输出流。

Writer append( CharSequence csq) 把字符序列csq追加到输出流。

 第三个案例:

 1 //    3.读取一个图像或者音频文件,读取过程中,每读取100个自己,跳过1个字节,然后保存成一个新文件,看看会得到什么效果的文件?
 2 //    文件已损坏,不能播放
 3     public void fileSkip() throws IOException{
 4         FileInputStream fis = new FileInputStream("music/李慧珍 - 在等待.mp3");
 5         FileOutputStream fos = new FileOutputStream("d:/李慧珍 - 在等待.mp3");
 6         
 7         int len;
 8         byte[] b = new byte[100];
 9         while((len = fis.read(b)) != -1){
10             fos.write(b, 0, len);
11             fis.skip(1);
12         }
13         fis.close();
14         fos.close();
15     }
View Code
 1 public class Text {
 2 
 3     public static void main(String[] args) throws IOException {
 4         // TODO Auto-generated method stub
 5         FileRW fileRW = new FileRW();
 6         
 7         fileRW.catalog();
 8     }
 9 
10 }
View Code

第四个案例:

 1 //Javabean
 2 public class User implements Serializable{
 3 
 4     private String username;
 5     private String password;
 6     private String regTime;
 7 
 8     public String getUsername() {
 9         return username;
10     }
11 
12     public void setUsername(String username) {
13         this.username = username;
14     }
15 
16     public String getPassword() {
17         return password;
18     }
19 
20     public void setPassword(String password) {
21         this.password = password;
22     }
23 
24     public String getRegTime() {
25         return regTime;
26     }
27 
28     public void setRegTime(String regTime) {
29         this.regTime = regTime;
30     }
31 
32     @Override
33     public String toString() {
34         return "User [username=" + username + ", password=" + password + ", regTime=" + regTime + "]";
35     }
36 
37 }
View Code
 1 //模拟迅雷下载
 2 public class Test {
 3     /*    5.使用序列化流(ObjectOutputStream)流将一个User类的对象序列化(存储)到磁盘上,然后继而用反序列化将之前存储的对象从磁盘上读取出来并将对象的属性输出到控制台。
 4         User 类设计如下:
 5         Class User{
 6             String username;//用户名
 7             String password;//密码
 8             String regTime;//注册时间
 9     }*/
10     public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
11         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/123.txt"));
12         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/123.txt"));
13         
14         User u = new User();
15         u.setUsername("张三");
16         u.setPassword("123456");
17         u.setRegTime(new Date().toLocaleString());
18         oos.writeObject(u);
19         
20         User o = (User)ois.readObject();
21         
22         System.out.println(o.toString());
23         oos.close();
24         ois.close();
25     }
26 
27 }
View Code

第五个案例:

 1 public class Test {
 2     /*6.设计一个简单的聊天记录保存功能,将控制台输入的内容保存到一个文本文件中(能够续存,而不是覆盖)。*/
 3     public static void main(String[] args) throws IOException {
 4         BufferedWriter bfw = new BufferedWriter(new FileWriter("E:/456.txt"));
 5         String n = null;
 6         do{
 7             Scanner s = new Scanner(System.in);
 8             n = s.nextLine();
 9             bfw.write(n);
10             bfw.newLine();
11             bfw.flush();
12         }while(n != "1");
13         
14         bfw.close();
15     }
16 
17 }
View Code

猜你喜欢

转载自www.cnblogs.com/xiyixin/p/9715881.html