• 熟悉文件的各种流类
  • 了解字符的编码
  • 掌握文件I/O操作的相关概念
  • 了解对象的序列化

简单的引入

   I:input  由外围输入到内存

  O:output  由内存写出到外存。

  I/O:是相对于内存来说的

在Java中所有的IO机制都是基于“流”方式进行输入和输出。这些流可以视为同一台计算机不同设备或者是不同计算机之间数据序列的流动。这些流序列的数据通常有两种格式:文本流和二进制流。文本流每一个字节存放一个ASCII码代表一个字符(而对于Unicode编码来说,每两个字节代表一个字符)。如整形数12345,其在内存中需要两个字节,其系统为整型分配四个字节,所以高两位的字节为0,而按文本流输出则占用五个字符,由于分别是12345这五个字符所对应的ASCII码

内存中的存储形式
00000000 00000000 00110000 00111001
二进制行形式:与内存中的存储形式完全相同
00000000 00000000 00110000 00111001
文本形式:分别对应各自的ASCII码
00000001 00000010 00000011 00000101

文本流与二进制流的优缺点

文本流:文本流形式和字节流一一对应,因而便于对于对字符进行逐个处理,也便于输出显示,但是占用较多的内存空间,且花费较多的转换时间(二进制和 编码之间的转换)。在Java中的Unicode编码,这是一种定长编码,每个字符两个字节,因此在存储ASCII码时会额外浪费一个字节的空间。

二进制流:可以节省外存空间和转化时间,但是一个字节不对应一个字符,不能直接输出字符形式。

总结:对于纯文本信息(比如字符串),以文本形式存储较佳;而对于数值信息,则用二进制形式较好。

I/O流的优势在于简单易用,缺点是效率低。Java的I/O提供了读写数据 的标准方法。Java语法中定义了许多类专门负责各种方式的输入输出,这些类被放在java.io包中。在java类库中,有关IO操作内容非常的庞大:有标准的输入输出、文件的操作、网路上的数据流、字符串流和对象流等。

1.文件操作类--File

  总结:

    对文件或文件夹进行操作(仅仅操作文件本身的属性不指定怎样从文件读取或者存储)

  在java.io包中,File类是唯一一个与文件本身操作有关的操作类。它定义了一系列与平台无关的方法来操作文件,通过调用File类,能够完成创建、删除、重命名文件,判断文件的读写权限以及问价是否存在,设置

  和查询问价创建的时间、权限等操作。File类除了对文件的操作外,还可以将目录当做文件来处理。

     File(String directoryPath);//创建指定文件或者目录文件的File对象
        File(String directoryPath,String filename);//创建由File对象和指定文件名的FIle对象
        File(File dirObj,String filename);//创建指定文件目录和文件名册File对象
        File F1=new File("G:\\");//创建 指向“G:\”的File对象
        File F2=new File("G:\\","1.txt");//创建指向“G:\1.txt”的File对象
        File F3=new File(F1,"1.txt");//创建指向“G:\1.txt”的File对象

注意:

  路径分隔符。在Linux/Unix下用斜线(/)路径处理正确;在Windows/DOS下使用反斜线(\),,那么就需要在字符串内使用转义字符\(\\)。

常用方法如下

方法 功能描述
boolean canRead() 测试应用程序是否能从指定的文件中读取
boolean canWirte() 测试应用程序是否能够写当前文件
boolean delete() 删除当前指定的文件
boolean equals() 比较该对象指定的对象
boolean exists() 测试当前的File是否存在
String getAbosolutePath() 返回该对象表示的文件的绝对的路径名
String getCanonicalPath() 返回当前File对象的路径名的规范格式
String getName() 返回当前对象的文件名
String getParent() 获取父路径名,没有就返回null
String getPath) 返回当前对象的路径名
boolean isAbosolute() 测试当前对象是否是一个绝对路径名
boolean isDirectory()

是否是一个路径

boolean isFile() 是否是一个file
long islastModified() 返回最后修改的时间
long length() 返回当前File的文件的长度
String list() 返回路径文件列表
boolean mkdir() 创建一个目录路径名由当前File对象指定
boolean  mkdirs() 创建一个目录路径名由当前File对象指定包括任一必须的父路径
boolean renameTo() 将当前file对象指定的文件更改名为指定参数File指定的路径名

 

范例

package Learn;

import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File f=new File("c:\\1.txt");
        if(f.exists()){
            f.delete();
        }
        try{
            f.createNewFile();
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

        System.out.println(f.getName());//取得文件名
        System.out.println(f.getPath());//取得文件路径
        System.out.println(f.getAbsolutePath());//取得绝对路径名
        System.out.println(f.getParent());//父文件夹名
        System.out.println(f.exists());//文件是否存在
        System.out.println(f.canWrite());//文件可不可写
        System.out.println(f.canRead());//文件可不可度
        System.out.println(f.isDirectory());//文件是不是个目录
        System.out.println(f.isFile());//文件是不是文件
        System.out.println(f.isAbsolute());//文件是不是绝对路径
        System.out.println(f.lastModified());//文件最后的修改时间
        System.out.println(f.length());//文件的额长度
    }

}

在本范例中你会发现如下问题

问题一:在进行操作是出现了延迟,因为文件管理肯定是操作系统完成的,那么程序通过JVM与操作系统进行操作,多了一层操作,所以势必会产生延迟。

问题二:在windows中使用用“\”,而Linux使用“/”,想要使得Java程序具备可移植性,就必须考虑分隔符的问题,所以在File类中提供了一个常量:public static final String separator。

File file =new File("c:"+File.separator+"1.txt");

问题三: 如果文件目录不存在,要想创建文件之前首先要创建目录

创建一级目录:public boolean mkdir();

创建多级目录:public boolean mkdirs();

取得父路径: public File getParentFile();

public static void main(String[] args) throws IOException {
  File file=new File("d:"+File.separator+"mytest"+File.separator+"1.t.txt");
  if(!file.getParentFile().exists()){
     file.getParentFile().mkdirs();//创建父目录
  }
  System.out.println(file.createNewFile());}

2.RandomAccessFile类

  总结:可以跳转到文件的任意位置处读写数据(随机访问文件)

  该类有一个位置指示器,指向当前的读写处的位置。该类的构造方法如下。

RandomAcessFile(File file,String mode)//创建随机存储文件流,文件属性有参数File对象指定。

RandomAcessFile(String name,String mode)//创建随机存储文件流,文件名由参数name指定

范例

package IO;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAcessFileDemo {
    public static void main(String[] args) throws IOException {
        // TODO 自动生成的方法存根
        Emplyee  e1=new Emplyee("zh",23);
        Emplyee  e2=new Emplyee("Li",24);
        Emplyee  e3=new Emplyee("wa",23);
        RandomAccessFile ra=new RandomAccessFile("G:\\employee.txt","rw");
        ra.write(e1.name.getBytes());
        ra.writeInt(e1.age);
        ra.write(e2.name.getBytes());
        ra.writeInt(e2.age);
        ra.write(e3.name.getBytes());
        ra.writeInt(e3.age);
        ra.close();
        RandomAccessFile raf=new RandomAccessFile("G:\\employee.txt","r");
        int len=8;
        raf.skipBytes(12);//跳过第一个员工的信息
        System.out.println("第二个员工的基本信息为:");
        String str="";
        for(int i=0;i<len;i++) {
            str=str+(char)raf.readByte();
        }
        System.out.println("name:"+str);
        System.out.println("age:"+raf.readInt());
        System.out.println("第一个员工的信息:");
        raf.seek(0);//将文件的额之争移动到文件开始的地方
        str="";
        for(int i=0;i<len;i++) {
            str=str+(char)raf.readByte();
        }
        System.out.println("name:"+str);
        System.out.println("age:"+raf.readInt());
        System.out.println("第三个员工的信息:");
        raf.skipBytes(12);//跳过第二个员工的信息
        str="";
        for(int i=0;i<len;i++) {
            str=str+(char)raf.readByte();
        }
        System.out.println("name:"+str);
        System.out.println("age:"+raf.readInt());
        raf.seek(0);
        raf.close();

    }

}

package IO;

public class Emplyee {
    String name;
    int age;
    final static int LEN=8;
    public Emplyee(String name,int age){
        if(name.length()>LEN) {
            name=name.substring(0, 8);
        }
        else {
            while(name.length()<LEN) {
                name=name+"\u0000";
            }
        }
        this.name=name;
        this.age=age;
    }
}
结果为:
第二个员工的基本信息为:
name:Li
age:24
第一个员工的信息:
name:zh
age:23
第三个员工的信息:
name:wa
age:23

上面的范例会出现错误:  (感觉是编码的问题哪位看到的大神可以帮我解决一下吗?(已经解决!在输入年龄的时候应该用writeInt()而不是write()))

String.sunString(int beginIndex,int endIndex)方法中,取得部分字符创,字符串的长度是endIndex-beginIndex,所以位置是从beginIndex到endIndex-1

3.字节流和字符流

  字节流

    读:INputStream(抽象类)

    写:OutputStream(抽象类)

  字符流

    读:Writer

    写:Reader

Java的流操作包括字符流和字节流。字符流处理的对象的单元是Unicode字符,每个Unicode字符占两个字节,而字节流输入输出是以单个字节为单位的。这种流操作对双字节字符的操作带来了麻烦。字符流是由Java虚拟机将单个字节转换为两个字节的的Unicode字符,所以它对多国语言支持较好。

常用的字节流名称及对应的功能的简单介绍

InputStream:继承架构

类定义如下

intputStream主要方法

常用的构造方法如下

     InputStream  fo=new FileInputStream("d:\\test.txt");//构造犯法一:FileInputStream(String filepath),file是绝对路径
        File f=new File("d:\\test.txt");
        InputStream f1=new FileInputStream(f);//构造方法二:FileInputStream(File fileObj),fileObj是描述该文件的File对象
        

实例向文件中写入字符串并读出

package IO;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class inputStream {

    public static void main(String[] args) throws FileNotFoundException {
        // TODO 自动生成的方法存根
        /*InputStream  fo=new FileInputStream("d:\\test.txt");//构造犯法一:FileInputStream(String filepath),file是绝对路径
        File f=new File("d:\\test.txt");
        InputStream f1=new FileInputStream(f);//构造方法二:FileInputStream(File fileObj),fileObj是描述该文件的File对象
        */
        File f=new File("G:\\temp.txt");
        OutputStream out=null;
        try {
            out=new FileOutputStream(f);
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        }
        //将字符串转为字节数组
        byte b[]="Hello world!!!".getBytes();
        try {
            out.write(b);
        }catch(IOException e) {
            e.printStackTrace();
        }
        try {
            out.close();
        }catch(IOException e) {
            e.printStackTrace();
        }
        //以下为读操作
        InputStream in=null;
        try {
            in=new FileInputStream(f);
        }catch(FileNotFoundException e) {
            e.printStackTrace();
        }
        //开辟一个空间用于接收文件读进来的数据
        byte b1[] =new byte[1024];
        int i=0;
        try {
            i=in.read(b1);
        }catch(IOException e) {
            e.printStackTrace();
        }
        try {
            in.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(new String(b1,0,i));

    }

}

实例来源和目的未知情况下实现输入流输出流

package IO;
import java.io.*;
public class IO {
    public static void dump(InputStream src,OutputStream dest) throws IOException {
        try(InputStream input=src;OutputStream output=dest){//尝试自动关闭串流OutputStream操作了java.io.Closeable接口,其父接口为java.lang.AutoCloseable接口
            byte[] data =new byte[1024];//尝试每次从来源读取1024个字节
            int length;
            while((length=input.read(data))!=-1) {//读取数据
                output.write(data, 0, length);//写出数据
            }
        }
    }
    public static void main(String[] args) throws IOException {
        IO.dump(new FileInputStream(args[0]),new FileOutputStream(args[1]));
    }

}

实例http服务器读取网页,并且另存为文档

package IO;
import java.io.*;
import java.net.URL;
public class IO {
    public static void dump(InputStream src,OutputStream dest) throws IOException {
        try(InputStream input=src;OutputStream output=dest){//尝试自动关闭串流OutputStream操作了java.io.Closeable接口,其父接口为java.lang.AutoCloseable接口
            byte[] data =new byte[1024];//尝试每次从来源读取1024个字节
            int length;
            while((length=input.read(data))!=-1) {//读取数据
                output.write(data, 0, length);//写出数据
            }
        }
    }
    public static void main(String[] args) throws IOException {
        /*IO.dump(new FileInputStream(args[0]),new FileOutputStream(args[1]));*/
        URL url=new URL(args[0]);
        InputStream src=url.openStream();
        OutputStream dest=new FileOutputStream(args[1]);
        IO.dump(src, dest);
    }
}

接收客户端联机的例子

    ServerSocket server=null;
        Socket client=null;
        while(true) {
            client=server.accept();
            InputStream input=client.getInputStream();
            OutputStream output=client.getOutputStream();
        }
.....
接下来就是操作InputStream、OutputStream实例了。

servlet将文档输入至浏览器例子

response.setContentType("application/pdf");
        InputStream in=this.getServletContext.getResourceAsStream("/WEB-INF/jdbc.pdf");
        OutputStream out=response.getOutputStream();
        byte[] data=new byte[1024];
        int length;
        while((length=in.read(data))!=-1) {
            out.write(data,0,length);

OutputStrean继承架构

该类是一个抽象类,它定义了流式字节的输出模式,该类的所有方法返回一个void值,在出错的情况下回抛出一个IOException

补充:标准输入输出

System.in与System.out。它们分别是InputStream和PrintStream的实例。对于System.in而言在文本模式下通常是取得整行的收入,很少直接操作InputStream相关方法。使用java.util.Scanner打包System.in取得数据,并转换为你想取得的数据类型。可以使用System的SetIn()方法制定InputStream实例,重新指定标准输入来源。例子如下:

        System.setIn(new FileInputStream(args[0]));
        try(Scanner scanner=new Scanner(System.in )){
            while(scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
        }

文件I/O操作的更多相关文章

  1. 用 JSP 实现对文件的相关操作

    前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...

  2. PHP文件相关的操作函数——目录操作

    1.有关文件类型的函数 PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”.“dir”或者“unknown”三种文件类型.而在UNIX系统中,我们可以获得“blo ...

  3. C#对文件/目录的操作:Path、File、Directory、FileStream、StreamReader、StreamWriter等类的浅析

    以下类的命名空间都是:System.I/0; 一.Path:主要对文件路径的操作! 常用方法: String path=@"C:\a\b\c\123.txt"; 1-1.Path. ...

  4. 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法

    无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法   问题描述: 在附加数据库到sql server时,附 ...

  5. java io流 对文件夹的操作

    java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...

  6. php对xml文件进行CURD操作

    XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...

  7. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  8. Python::OS 模块 -- 文件和目录操作

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...

  9. INI 文件的读写操作

    在C#中对INI文件进行读写操作,在此要引入using System.Runtime.InteropServices; 命名空间,具体方法如下: #region 变量 private static r ...

  10. Android 对 properties文件的读写操作

    -. 放在res中的properties文件的读取,例如对放在assets目录中的setting.properties的读取:PS:之所以这里只是有读取操作,而没有写的操作,是因为我发现不能对res下 ...

随机推荐

  1. GUI_菜单练习

    package com.mywindow.test; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; ...

  2. python五十六课——正则表达式(常用函数之findall)

    4).函数:findall(regex,string,[flags=0]): 参数: 和match.search一样理解 功能: 将所有匹配成功的子数据(子串),以列表的形式返回: 如果一个都没有匹配 ...

  3. enq: FB - contention

    Troubleshooting 'enq: FB - contention' Format Block Enqueues. (Doc ID 1379986.1) In this DocumentPur ...

  4. 数据库连性池性能测试(hikariCP,druid,tomcat-jdbc,dbcp,c3p0)

    文章转自  https://www.tuicool.com/articles/qayayiM 摘要: 本文主要是对这hikariCP,druid,tomcat-jdbc,dbcp,c3p0几种连接池的 ...

  5. PAT A1020 Tree Traversals (25 分)——建树,层序遍历

    Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and i ...

  6. AI 卷积神经网络

    卷积神经网络(Convolutional Neural Network,简称CNN),顾名思义,使用了卷积.不过,这里用到的卷积和数学中的不完全一致. 1.连续卷积 2.离散卷积 3.二维离散卷积 4 ...

  7. spring 和spring cloud 组成

    spring 顶级项目:Spring IO platform:用于系统部署,是可集成的,构建现代化应用的版本平台,具体来说当你使用maven dependency引入spring jar包时它就在工作 ...

  8. lesson 8:小程序

    程序源代码: //20163683 蔡金阳 信1605-3 import java.io.*; import java.util.Scanner; public class kaoshi { publ ...

  9. TerraGate软件安装后,不能启动的解决办法

    在服务端安装Skyline的TerraGate软件的时候,大家可能会遇到过这样的问题,“TerraGate软件安装后,不能启动”,很多时候,这个问题是因为TerraGate设 置的端口号已经被占用造成 ...

  10. Java多线程编程模式实战指南一:Active Object模式(下)

    Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...