Java基础——IO流

IO流基础知识内容:


1.java.io包下
File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。
File file1 = new File("d:\\io\\helloworld.txt");
File file2 = new File("d:\\io\\io1");
>1.File既可以表示一个文件(.doc  .xls   .mp3  .avi   .jpg  .dat),也可以表示一个文件目录!
>2.File类的对象是与平台无关的。

>3.File类针对于文件或文件目录,只能进行新建、删除、重命名、上层目录等等的操作。

        如果涉及到访问文件的内容,File    是无能为力的,只能使用IO流下提供的相应的输入输出流来实现。

>4.常把File类的对象作为形参传递给相应的输入输出流的构造器中!

2.IO 流的结构


3.IO流的划分
  1) 按照流的流向的不同:输入流   输出流  (站位于程序的角度)
  2) 按照流中的数据单位的不同:字节流   字符流  (纯文本文件使用字符流 ,除此之外使用字节流)

  3) 按照流的角色的不同:节点流   处理流   (流直接作用于文件上是节点流(4个),除此之外都是处理流)







4.重点掌握
 * 抽象基类
节点流(文件流)                               缓冲流(处理流的一种,可以提升文件操作的效率)
 * InputStream FileInputStream (int read(byte[] b)) BufferedInputStream  (int read(byte[] b))
* OutputStream      FileOutputStream (void write(b,0,len))      BufferedOutputStream  (flush())  (void write(b,0,len))
 * Reader FileReader (int read(char[] c)) BufferedReader  (readLine())  (int read(char[] c))或String readLine()
 * Writer         FileWriter (void write(c,0,len))         BufferedWriter  (flush()) (void write(c,0,len)或void write(String str))

注: 1.从硬盘中读入一个文件,要求此文件一定得存在。若不存在,报FileNotFoundException的异常
       2.从程序中输出一个文件到硬盘,此文件可以不存在。若不存在,就创建一个实现输出。若存在,则将已存在的文件覆盖
       3.真正开发时,就使用【缓冲流】来代替 节点流
       4.主要最后要关闭相应的流。先关闭输出流,再关闭输入流。将此操作放入finally


5.其它的流


1.转换流:实现字节流与字符流之间的转换

 InputStreamReader:输入时,实现字节流到字符流的转换,提高操作的效率(前提是,数据是文本文件)  

 ===>解码:字节数组--->字符串

 OutputStreamWriter:输出时,实现字符流到字节流的转换。 ===>编码:  字符串---->字节数组

   例子:从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作直至当输入“e”或者“exit”时,退出程序。

 /*
     * 标准的输入输出流:
     * 标准的输出流:System.out
     * 标准的输入流:System.in(是InputStream类型的,都是字节流)
     * 
     * 题目:
     * 从键盘输入字符串,要求将读取到的整行字符串转成大写输出,
     * 然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。
     */
    @Test
    public void test2(){
        BufferedReader br = null;
        try {
            InputStream is = System.in;//键盘输入的字母是字节流
            InputStreamReader isr = new InputStreamReader(is);//将字节流转换成字符流
            br = new BufferedReader(isr);
            String str;
            while(true){
                System.out.println("请输入字符串:");
                str = br.readLine();
                if(str.equalsIgnoreCase("e") || str.equalsIgnoreCase("exit")){
                    break;
                }
                String str1 = str.toUpperCase();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }
        }
        
    }
    
  2.标准的输入输出流
    System.in: The "standard" input stream:从键盘输入数据
    System.out:The "standard" output stream:从显示器输出数据

   3.打印流 (都是输出流)  PrintStream(处理字节)  PrintWriter(处理字符) 

可以使用System.setOut(PrintStream p)重新设置一下输出的位置。  

PrintStream p = new PrintStream(new FileOutputStream("hello.txt"),true);


   4.数据流(处理基本数据类型、String类、字节数组)

DataInputStream  DataOutputStream


   5.对象流(用来处理对象的)
     >对象的序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,
        或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

     ObjectInputStream(Object readObject();)   ObjectOutputStream  (void writeObject(Object obj))

如何创建流的对象:

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("person.txt")));

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("person.txt")));

实现序列化机制的对象对应的类的要求:

①要求类要实现Serializable接口

②同样要求类的所有属性也必须实现Serializable接口

③ 要求给类提供一个序列版本号:private static final long serialVersionUID;
④属性声明为static 或transient的,不可以实现序列化


6.随机存取文件流:RandomAccessFile

      6.1既可以充当一个输入流,又可以充当一个输出流:public RandomAccessFile(File file, String mode) 
      6.2支持从文件的开头读取、写入。若输出的文件不存在,直接创建。若存在,则是对原有文件内容的覆盖。

      6.3 支持任意位置的“插入”。

------------------------------------------------------------------------------------------------------------------------
------------------------------------------------练习代码---------------------------------------------------------------
例题1:

//单线程:主线程
public class TestMain {
public static void main(String[] args) {
method2("cjw.com");
}
public static void method1(String str){
System.out.println("method1....");
System.out.println(str);
}
public static void method2(String str){
System.out.println("method2...");
method1(str);
}
}
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------练习代码---------------------------------------------------------------
例题2:
/*
 * 创建一个子线程,完成1-100之间自然数的输出。同样地,主线程执行同样的操作
 * 创建多线程的第一种方式:继承java.lang.Thread类
 */
//1.创建一个继承于Thread的子类
class SubThread extends Thread{

//2.重写Thread类的run()方法.方法内实现此子线程要完成的功能
public void run(){
for(int i = 1;i <= 100;i++){
System.out.println(Thread.currentThread().getName() +":" + i);
}
}
}


public class TestThread {

public static void main(String[] args) {
//3.创建子类的对象
SubThread st1 = new SubThread();
SubThread st2 = new SubThread();


//4.调用线程的start():启动此线程;调用相应的run()方法
//一个线程只能够执行一次start()
//不能通过Thread实现类对象的run()去启动一个线程
st1.start();

//st.start();
//st.run();
st2.start();

for(int i = 1;i <= 100;i++){
System.out.println(Thread.currentThread().getName() +":" + i);
}
}
}

------------------------------------------------------------------------------------------------------------------------
------------------------------------------------练习代码---------------------------------------------------------------

例题3:
/*
 * Thread的常用方法:
 * 1.start():启动线程并执行相应的run()方法
 * 2.run():子线程要执行的代码放入run()方法中
 * 3.currentThread():静态的,调取当前的线程
 * 4.getName():获取此线程的名字
 * 5.setName():设置此线程的名字
 * 6.yield():调用此方法的线程释放当前CPU的执行权
 * 7.join():在A线程中调用B线程的join()方法,表示:当执行到此方法,A线程停止执行,直至B线程执行完毕,
 * A线程再接着join()之后的代码执行
 * 8.isAlive():判断当前线程是否还存活
 * 9.sleep(long l):显式的让当前线程睡眠l毫秒
 * 10.线程通信:wait()   notify()  notifyAll()
 * 
 * 设置线程的优先级
 * getPriority() :返回线程优先值 
   setPriority(int newPriority) :改变线程的优先级


 */
class SubThread1 extends Thread {

public void run() {
for (int i = 1; i <= 100; i++) {
// try {
// Thread.currentThread().sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName() + ":"
+ Thread.currentThread().getPriority() + ":" + i);
}
}
}


public class TestThread1 {

public static void main(String[] args) {


SubThread1 st1 = new SubThread1();
st1.setName("子线程1");
st1.setPriority(Thread.MAX_PRIORITY);
st1.start();
Thread.currentThread().setName("========主线程");
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + ":"
+ Thread.currentThread().getPriority() + ":" + i);
// if(i % 10 == 0){
// Thread.currentThread().yield();
// }
// if(i == 20){
// try {
// st1.join();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
}
System.out.println(st1.isAlive());
}
}

------------------------------------------------------------------------------------------------------------------------
------------------------------------------------练习代码---------------------------------------------------------------

例题4:
//创建两个子线程,让其中一个输出1-100之间的偶数,另一个输出1-100之间的奇数。
class SubThread1 extends Thread{

public void run(){
for(int i = 1;i <= 100;i++){
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
class SubThread2 extends Thread{

public void run(){
for(int i = 1;i <= 100;i++){
if(i % 2 != 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}


public class TestThread {

public static void main(String[] args) {
SubThread1 st1 = new SubThread1();
SubThread2 st2 = new SubThread2();
st1.start();
st2.start();
//继承于Thread类的匿名类的对象
//
new Thread(){
//
public void run(){
//
for(int i = 1;i <= 100;i++){
//
if(i % 2 == 0){
//
System.out.println(Thread.currentThread().getName() + ":" + i);
//
}
//
}
//
}
//
}.start();
//

// new Thread(){
//
public void run(){
//
for(int i = 1;i <= 100;i++){
//
if(i % 2 != 0){
//
System.out.println(Thread.currentThread().getName() + ":" + i);
//
}
//
}
//
}
//
}.start();

}
}



------------------------------------------------------------------------------------------------------------------------
------------------------------------------------面试题---------------------------------------------------------------

1.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
答:字节流,字符流。
字节流继承于InputStream OutputStream,
字符流继承于Reader Writer。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。


-----------------------------------------------------
2.什么是java序列化,如何实现java序列化?

答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。
可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。
序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,
implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造
一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以
将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。


-----------------------------------------------------
在Java中,输入输出的处理需要引入的包是java.io,
面向字节的输入输出类的基类是Inputstream和Outputstream。
面向字符的输入输出类的基类是Reader和Writer。


-----------------------------------------------------
3.使用处理流的优势有哪些?如何识别所使用的流是处理流还是节点流?

【答案】
【优势】对开发人员来说,使用处理流进行输入/输出操作更简单;使用处理流的执行效率更高。
【判别】
处理流的构造器的参数不是一个物理节点,而是已经存在的流。而节点流都是直接以物理IO及节点作为构造器参数的。


-----------------------------------------------------
填空:下列程序将从file1.dat文件中读取全部数据,然后写到file2.dat文件中。
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;


public class FileStreamInOut {

public static void main(String[] args){
try{
File inFile = new File("_________");
File outFile = new File("_________");
FileInputStream  fis = new FileInputStream(_________);
FileOutputStream  fos = new FileOutputStream(_________);
int c;
while((c = fis.read())!=-1){
fos.write(c);
}
_____.close();
_____.close();
}catch(FileNotFoundException e){
System.out.println("FileStreamsTest:"+e);
}catch(IOException e){
System.out.println("FileStreamTest"+e);
}
}
}


-----------------------------------------------------
4.Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请指出它们分别是哪些类?

【答案】Java中按所操作的数据单元的不同,分为字节流和字符流。
字节流继承于InputStream和OutputStream类,字符流继承于Reader和Writer。
按流的流向的不同,分为输入流和输出流。
按流的角色来分,可分为节点流和处理流。缓冲流、转换流、对象流和打印流等都属于处理流,使得输入/输出更简单,执行效率更高。


------------------------------------------------------
5.什么是标准的I/O流?

在java语言中,用stdin表示键盘,用stdout表示监视器。他们均被封装在System类的类变量in 和out中,
对应于系统调用System.in和System.out。这样的两个流加上System.err统称为标准流,它们是在System类中声明的3个类变量:
public static InputStream in
publicstaticPrintStream out
public static PrintStream err




-----------------------------------------------------
选择题
1.计算机处理的数据最终分解为▁▁的组合。
A 0 
B 数据包
C 字母
D 1 
2.计算机处理的最小数据单元称为▁▁。
A 位
B 字节
C 兆
D 文件
3.字母、数字和特殊符号称为▁▁。
A 位
B 字节
C 字符
D 文件
4.▁▁文件流类的 close 方法可用于关闭文件。
A FileOutputStream
B FileInputStream
C RandomAccessFile
D FileWrite
5.RandomAccessFile 类的▁▁方法可用于从指定流上读取整数。
A readInt
B readLine
C seek 
D close 
6.RandomAccessFile 类的▁▁方法可用于从指定流上读取字符串。
A readInt
B readLine
C seek 
D close 
7.RandomAccessFile 类的▁▁方法可用于设置文件定位指针在文件中的位置。
A readInt
B readLiIne
C seek 
D close 
8.在FilterOutputStream类的构造方法中,下面哪个类是合法:
A File 
B InputStream
C OutputStream
D FileOutputStream


-----------------------------------------------------


-----------------------------------------------------


-----------------------------------------------------
【答案】
1.难度:容易答案:AD 知识点:计算机最终能处理的数据只能为 0 和 1。
2.难度:容易答案:B 知识点:计算机处理的最小数据单元是字节。


3.难度:容易答案:C 知识点:字符的概念。
4.难度:适中答案: ABC 知识点:FileOutStream、FileInputStream、RandomAccessFile
文件流类的 close 方法可用于关闭文件。
5.难度:适中答案:A 知识点:readInt方法的使用。
6.难度:适中答案:B 知识点:readLIne方法的使用。
7.难度:适中答案:C 知识点:seek 方法的使用。
8.难度:适中答案:C 知识点:在FilterOutputStream类中只有一种结构:public
FilterOutputStream(OutputStream)。


-----------------------------------------------------


-----------------------------------------------------



-----------------------------------------------------

版权说明:本文为博主原创文章,转载请标明文章转载处。

2013.03.21



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值