IO流

一、java.io.File类的使用

 java.io.File类

1.凡是与输入输出相关的类、接口的定义在java.io包下

2.File是一个类,可以有构造器创建其对象。此对象对应着一个文件(.txt .avi .doc)或文件目录

             // 路径分为绝对路径(包括盘符在内的完整的文件路径)和相对路径(在当前文件目录下的文件路径)

             File file = new File("d:\\test\\test.txt");

             //或者File file = new File("d:/test/test.txt");

3.File类对象是与平台无关的

4.File中的方法,仅涉及到如何创建、删除、重命名等等,只要涉及文件内容的,File是无能为力的,必须由io流来完成

5.File类的对象常作为io流的具体类的构造器的形参

Fiel类方法

1.访问文件名

getName()

getPath()

getAbsoluteFile()

getAbsolutePath()

getParent()

renameTo(File newName):file.removeTo(file1)。file重命名为file1。要求file文件一定存在,file1一定不存在

2.文件检测

exists()

canWrite()

canRead()

isFile()

isDirectory()

3.获取常规文件信息

lastModified()

length()

4.文件操作相关

createNewFile()

delete()

5.目录操作相关

mkDir()

mkDirs()

list()

listFiles()

二、IO原理及流的分类

Java IO原理

1.IO流用来处理设备之间的数据传输

2.Java程序中,对于数据的输入/输出操作以“流(Stream)”的方式进行

3.java.io包下提供了各种“流”类和接口,用以获取不同类的数据,并通过标准的方法输入input或输出output数据

4.流的分类

按照操作数据单位不同分为:字节流(8bit),字符流(16bit)

按数据流的流向不同分为:输入流,输出流

按流的角色的不同分为:节点流(4个:FileInputStream、FileOutputStream、FileReader、FileWriter)、处理流

  IO流

5.IO流体系

IO流

三、文件流

FileInputStream

1.代码一:按个读取,用throws处理异常

//从硬盘存在的一个文件中,读取其内容到程序中
//要读取的文件一定要存在,否则抛FileNotFoundException异常
@Test
public void testFileInputStream() throws Exception{
       //1.创建一个File类的对象
       File file = new File("hello.txt");
       //2.创建一个FileInputStream类的对象
       FileInputStream fis = new FileInputStream(file);
       //3.调用FileInputStream的方法,实现file文件的读取
       //read():读取文件的一个字节。当执行到文件结尾时,返回-1
       int b;
       while((b = fis.read()) != -1){
           System.out.println((char)b);
       }
       //4.关闭相应的流
       fis.close();
}

2.代码二:按个读取,用try-catch处理异常 

//使用try-catch的方式处理如下的异常更合理:保证流的关闭操作一定可以执行
    @Test
    public void testFileInputStream() {
       //1.创建一个FileInputStream类的对象
       FileInputStream fis = null;
       try {
           //2.创建一个File类的对象
           File file = new File("hello.txt");
           fis = new FileInputStream(file);
           //3.调用FileInputStream的方法,实现file文件的读取
           int b;
           while((b = fis.read()) != -1){
              System.out.println((char)b);
           }
       }catch (IOException e) {
               e.printStackTrace();
       }finally{
       //4.关闭相应的流
       try {
           fis.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
       }
    }

3.代码三:按数组读取,用try-catch处理异常

   @Test
	public void testFileInputStream() {
		FileInputStream fis = null;
		try {
			File file = new File("hello.txt");
			fis = new FileInputStream(file);
			byte[] b = new byte[5];// 读取到的数据要写入数组
			int len;// 每次读入到byte中字节的长度
			while ((len = fis.read(b)) != -1) {
				// 注意len不要写成length
				for (int i = 0; i < len; i++) {
					System.out.print((char) b[i]);
				}
				//String str = new String(b,0,len);
				//Syatem.out.print(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

FileOutputStream

1.代码一:写入          

@Test
public void testFileOutputStream() {
       // 1.创建一个File对象,表明要写入的文件位置。
       // 输出的物理文件可以不存在,当执行过程中,若不存在,会自动的创建。若存在,会将原有的文件覆盖
       File file = new File("hello.txt");
       // 2.创建一个FileOutputStream的对象,将file的对象作为形参传递给FileOutputStream的构造器中
       FileOutputStream fos = null;
       try {
           fos = new FileOutputStream(file);
           // 3.写入的操作
           fos.write(new String("I love China!").getBytes());
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           // 4.关闭输出流
           if (fos != null) {
              try {
                  fos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
}

2.代码二:从硬盘读取一个文件,并写入到另一个位置。(相当于文件的复制)

 


       @Test
       public void testFileInputOutputStream() {
       // 1.提供读入、写出的文件
       File file1 = new File("C:\\Users\\shkstart\\Desktop\\1.jpg");
       File file2 = new File("C:\\Users\\shkstart\\Desktop\\2.jpg");
       // 2.提供相应的流
       FileInputStream fis = null;
       FileOutputStream fos = null;
       try {
           fis = new FileInputStream(file1);
           fos = new FileOutputStream(file2);
           // 3.实现文件的复制
           byte[] b = new byte[20];
           int len;
           while ((len = fis.read(b)) != -1) {
              //错误的写法两种: fos.write(b,0,b.length);fos.write(b);
              fos.write(b, 0, len);
           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           if (fos != null) {
              try {
                  fos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
           if (fis != null) {
              try {
                  fis.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }

       }
    }

FileReader          

       @Test
       public void testFileReader(){
       FileReader fr = null;
       try {
           File file = new File("hello.txt");
           fr = new FileReader(file);
           char[] c = new char[24];
           int len;
           while((len = fr.read(c)) != -1){
              String str = new String(c, 0, len);
              System.out.print(str);
           }
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(fr != null){
              try {
                  fr.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

FileWriter      


    @Test
    //不能实现非文本文件的复制
    public void testFileReaderWriter(){
       //输入流对应的文件src一定要存在,否则抛异常。输出流对应的文件dest可以不存在,执行过程中会自动创建
       FileReader fr = null;
       FileWriter fw = null;
       try{
           File file1= new File("hello.txt");
           File file2 = new File("copyhello.txt");
           fr = new FileReader(file1);
           fw = new FileWriter(file2);
           char[] c = new char[24];
           int len;
           while((len = fr.read(c)) != -1){
              fw.write(c, 0, len);
           }
       }catch(Exception e){
           e.printStackTrace();
       }finally{
           if(fw != null){
              try {
                  fw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
           if(fr != null){
              try {
                  fr.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

四、缓冲流

BufferedInputStream和BufferedOutputStream      


    @Test
    public void testBufferedInputOutputStream(){
       BufferedInputStream bis = null;
       BufferedOutputStream bos = null;
       try {
           //1.提供读入、写出的文件
           File file1 = new File("1.jpg");
           File file2 = new File("2.jpg");
           //2.想创建相应的节点流:FileInputStream、FileOutputStream
           FileInputStream fis = new FileInputStream(file1);
           FileOutputStream fos = new FileOutputStream(file2);
           //3.将创建的节点流的对象作为形参传递给缓冲流的构造器中
           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);
           //4.具体的实现文件复制的操作
           byte[] b = new byte[1024];
           int len;
           while((len = bis.read(b)) != -1){
              bos.write(b, 0, len);
              bos.flush();
           }
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           //5.关闭相应的流
           if(bos != null){
              try {
                  bos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
           if(bis != null){
              try {
                  bis.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
       }
    }

BufferedReader和BufferedWriter      



    @Test
    public void testBufferedReaderWriter(){
       BufferedReader br = null;
       BufferedWriter bw = null;
       try {
           File file = new File("hello.txt");
           File file1 = new File("copyhello.txt");
           FileReader fr = new FileReader(file);
           FileWriter fw = new FileWriter(file1);
           br = new BufferedReader(fr);
           bw = new BufferedWriter(fw);
           /*
           char[] c = new char[1024];
           int len;
           while((len = br.read(c))!= -1){
              String str = new String(c, 0, len);
              System.out.print(str);
           }
           */
           String str;
           while((str = br.readLine()) != null){
              bw.write(str + "\n");
              //bw.newLine();
              bw.flush();
           }
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(bw != null){
              try {
                  bw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
           if(br != null){
              try {
                  br.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
          
       }
    }

五、转换流

InputStreamReader和 OutputStreamWriter

    //如何实现字节流与字符流之间的转换:
    //编码:字符串  --->字节数组
    //解码:字节数组--->字符串
    @Test
    public void test(){
       BufferedReader br = null;
       BufferedWriter bw = null;
       try {
           //解码
           File file1 = new File("hello.txt");
           FileInputStream fis = new FileInputStream(file1);
           InputStreamReader isr = new InputStreamReader(fis, "GBK");
           br = new BufferedReader(isr);
           //编码
           File file2 = new File("copyhello.txt");
           FileOutputStream fos = new FileOutputStream(file2);
           OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
           bw = new BufferedWriter(osw);
           String str;
           while((str = br.readLine()) != null){
              bw.write(str);
              bw.newLine();
              bw.flush();
           }
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(bw != null){
              try {
                  bw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
           if(br != null){
              try {
                  br.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
       }
      
    }

六、标准输入_输出流

标准的输入(System.in)输出(System.out)流      

    @Test
    public void test(){
       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 s = str.toUpperCase();
              System.out.println(s);
           }
       } catch (IOException e) {
           e.printStackTrace();
        }finally{
           if(br != null){
              try {
                  br.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
       }
    }

七、打印流(了解)

字节流(PrintStream)和字符流(PrintWriter)   

    @Test
    public void printStreamWriter() {
       FileOutputStream fos = null;
       try {
           fos = new FileOutputStream(new File("print.txt"));
       } catch (FileNotFoundException e) {
           e.printStackTrace();
       }
       // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
       PrintStream ps = new PrintStream(fos, true);
       if (ps != null) { 
           // 把标准输出流(控制台输出)改成文件
           System.setOut(ps);
       }
       for (int i = 0; i <= 255; i++) { 
           // 输出ASCII字符
           System.out.print((char) i);
           if (i % 50 == 0) { 
               // 每50个数据一行
               System.out.println();
           }
       }
       ps.close();
    }

八、对象流_设计序列化、反序列化

对象流

1.用于存储和读取对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

2.序列化(Serialize):用ObjectInputStream类将一个Java对象写入IO流中。对象的序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存 在磁盘上,或通过网络将这种二进制流传输到另一个网络节点,当其他程序获取了这种二进制流,就可以恢复成原来的Java对象。序列化的好处在于可将任何实现了Serilzable接口的对象转化成为字节数据,使其在保存和传输时可被还原。序列化是RMI(Romote Method Invoke – 远程方法调用)过程的参数和返回值都必须实现的机制,而RMI是JavaEE的基础。因此序列化机制是JavaEE平台的基础。如果需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:Serializable、Externalizable。注意:要求类的属性同样的要实现Serializable接口。凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。

private static final long serialVersionUID;

serialVersionUID用来表明类的不同版本间的兼容性。

如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的源代码做了修改,serialVersionUID可能发生变化,故建议,显示声明。

显示定义serialVersionUID的用途:希望类的不同版本对序列化兼容,因此需确保类的不同版本具有相同的serialVersionUID。

不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID。

3.反序列化(Deserialize):用ObjectOutputStream类从IO流中恢复该Java对象。

4.ObjectInputStream和ObjectOutputStream不能序列化static和transient修饰的成员变量。

ObjectInputStream      

    @Test
    public void testObjectInputStream() {
       ObjectInputStream ois = null;
       try {
           ois = new ObjectInputStream(new FileInputStream(
                  "person.txt"));
           Person p = (Person)ois.readObject();
           System.out.println(p);
       }catch (Exception e) {
           e.printStackTrace();
       }finally{
           if(ois != null){
             
              try {
                  ois.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

ObjectOutputStream

    @Test
    public void testObjectOutputStream() {
       Person p = new Person("小米", 23,new Pet("花花"));
              ObjectOutputStream oos = null;
       try {
           oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
           oos.writeObject(p);
           oos.flush();
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           if (oos != null) {
              try {
                  oos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }
}

 Person类


//要实现序列化的类:
//1.要求此类是可序列化的:实现Serializable接口
//2.要求类的属性同样的要实现Serializable接口
//3.提供一个版本号:private static final long serialVersionUID
//4.使用static或transient修饰的属性,不可实现序列化
class Person implements Serializable {
    private static final long serialVersionUID = 23425124521L;
    static String name;
    transient Integer age;
    Pet pet;
    public Person(String name, Integer age,Pet pet) {
       this.name = name;
       this.age = age;
       this.pet = pet;
    }
    @Override
    public String toString() {
       return "Person [name=" + name + ", age=" + age + ", pet=" + pet + "]";
    }
}

九、随机存储文件流

RandomAccessFile

1.RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读、写文件。支持只访问文件的部分内容、可以向已存在的文件后追加内容。

2.RandomAccessFile对象包含一个记录指针,用以表示当前读写出的位置。RandomAccessFile类对象可以*移动记录指针:

long getFilePointer():获取文件记录指针的当前位置

void seek(long pos):将文件记录指针定位到pos位置

3.构造器

public RandomAccessFile(File file,String mode)

public RandomAccessFile(String name,String mode)

4.创建RandomAccessFile类实例需要指定一个mode参数,该参数指定RandomAccessFile的访问模式

r:以只读方式打开

rw:打开以便读取和写入

rwd:打开以便读取和写入;同步文件内容的更新

rws:打开以便读取和写入;同步文件内容和元数据的更新

5.特点

既可以充当一个输入流,又可以充当一个输出流

支持从文件的开头读取、写入

支持从任意位置的读取和写入(插入)

源代码

1.代码一


    @Test
    //进行文件的读写
    public void test(){
       RandomAccessFile raf1 = null;
       RandomAccessFile raf2 = null;
       try {
           raf1 = new RandomAccessFile(new File("hello1.txt"), "r");
           raf2 = new RandomAccessFile(new File("hello2.txt"),"rw");
          
           byte[] b = new byte[20];
           int len;
           while((len = raf1.read(b)) != -1){
              raf2.write(b, 0, len);
           }
       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(raf2 != null){
              try {
                  raf2.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
           if(raf1 != null){
              try {
                  raf1.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

2.代码二

@Test
//实现的实际上是覆盖的效果
    public void test(){
       RandomAccessFile raf = null;
       try {
           raf = new RandomAccessFile(new File("hello2.txt"),"rw");
           raf.seek(4);
           raf.write("xy".getBytes());
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(raf != null){
              try {
                  raf.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

3.代码三

   @Test
    //实现插入的效果:在d字符后面插入“xy”
    public void test(){
       RandomAccessFile raf = null;
       try {
           raf = new RandomAccessFile(new File("hello2.txt"),"rw");
          
           raf.seek(4);
           String str = raf.readLine();
           raf.seek(4);
           raf.write("xy".getBytes());
           raf.write(str.getBytes());
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(raf != null){
              try {
                  raf.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

4.代码四

    @Test
    //相较于代码三,更通用
    public void test(){
       RandomAccessFile raf = null;
       try {
           raf = new RandomAccessFile(new File("hello2.txt"),"rw");
           raf.seek(4);
           byte[] b = new byte[10];
           int len;
           StringBuffer sb = new StringBuffer();
           while((len = raf.read(b)) != -1){
              sb.append(new String(b,0,len));
           }
           raf.seek(4);
           raf.write("xy".getBytes());
           raf.write(sb.toString().getBytes());
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(raf != null){
              try {
                  raf.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

十、数据流(了解)

DataInputStream 和 DataOutputStream


    @Test
    //数据流:用来处理基本数据类型readXxx()、String类型readUTF()、字节数组readFully()的数据
    public void testData(){
       DataInputStream dis = null;
       try{
           dis = new DataInputStream(new FileInputStream(new File("data.txt")));
           String str = dis.readUTF();
           System.out.println(str);
           boolean b = dis.readBoolean();
           System.out.println(b);
       }catch(Exception e){
           e.printStackTrace();
       }finally{
           if(dis != null){
              try {
                  dis.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       }
    }

    @Test 
    public void testData(){
       DataOutputStream dos = null;
       try {
           FileOutputStream fos = new FileOutputStream("data.txt");
           dos = new DataOutputStream(fos);
           dos.writeUTF("我爱你,而你却不知道!");
           dos.writeBoolean(true);
       }catch (IOException e) {
           e.printStackTrace();
       }finally{
           if(dos != null){
              try {
                  dos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
             
           }
       }
      
    }
   

 

上一篇:使用log4j的时候如何输出printStackTrace()的堆栈信息


下一篇:JavaIO流