文件I/O操作
- 熟悉文件的各种流类
- 了解字符的编码
- 掌握文件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操作的更多相关文章
- 用 JSP 实现对文件的相关操作
前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...
- PHP文件相关的操作函数——目录操作
1.有关文件类型的函数 PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”.“dir”或者“unknown”三种文件类型.而在UNIX系统中,我们可以获得“blo ...
- C#对文件/目录的操作:Path、File、Directory、FileStream、StreamReader、StreamWriter等类的浅析
以下类的命名空间都是:System.I/0; 一.Path:主要对文件路径的操作! 常用方法: String path=@"C:\a\b\c\123.txt"; 1-1.Path. ...
- 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法
无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法 问题描述: 在附加数据库到sql server时,附 ...
- java io流 对文件夹的操作
java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...
- php对xml文件进行CURD操作
XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...
- 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】
一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...
- Python::OS 模块 -- 文件和目录操作
os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...
- INI 文件的读写操作
在C#中对INI文件进行读写操作,在此要引入using System.Runtime.InteropServices; 命名空间,具体方法如下: #region 变量 private static r ...
- Android 对 properties文件的读写操作
-. 放在res中的properties文件的读取,例如对放在assets目录中的setting.properties的读取:PS:之所以这里只是有读取操作,而没有写的操作,是因为我发现不能对res下 ...
随机推荐
- 使用 React-Sketchapp 管理你的设计资产
首发:https://www.yuque.com/jingwhale/blog/do37mc 最近在整理设计规范的过程中,尝试使用了 Airbnb 公司发布的 react-sketchapp 工具.从 ...
- webpack 开发环境与生成环境的 配置
写在前面 最近学习react,之前做vue项目的时候,一直都是拿来主义,浑浑噩噩,感觉不太好,趁学习react的机会,在顺带学习一下webpack.一般配置文件分两份,为开发环境和生成环境.有此区分, ...
- IO流_SequenceInputStream(序列流)
SequenceInputStream(序列流):就是将多个流合成一个有序的流 需求:将三个文件中的数据合并到一个文件中 import java.io.FileInputStream; import ...
- Android中消息系统模型和Handler Looper
http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html Android中消息系统模型和Handler Looper 作为Andro ...
- request.servervariables参数
ServerVariables ServerVariables 集合检索预定的环境变量. 语法 Request.ServerVariables (server environment variable ...
- 20145236《网络对抗》Exp 6 信息搜集与漏洞扫描
20145236<网络对抗>Exp 6 信息搜集与漏洞扫描 一.基础问题回答 哪些组织负责DNS,IP的管理? 互联网名称与数字地址分配机构,简称ICANN机构,决定了域名和IP地址的分配 ...
- P1004 方格取数-洛谷luogu-dp动态规划
题目描述 设有N \times NN×N的方格图(N \le 9)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A 0 0 0 0 0 0 0 0 ...
- 如何在Qt Creator中导入图标资源
本文主要描述如何在Qt Creator中创建资源文件,并的打入导入图标文件. 查看图标资源文件时,可以在项目的工程文件上鼠标单击右键-Open With-资源编辑器,效果如下图所示: 在项目的工程文件 ...
- linux下模拟一个木马程序运行过程
预备知识: 将一个程序放入到后台,悄悄的执行 ./xxx.sh & 进程: 用户进程:由用户来管理 系统进程:由系统内核自行管理 系统中的每个进程,都有一个位置的ID,这就是pid,而且每次启 ...
- odoo学习之带出信息
# 输入客户带出它默认的发运方式和包装方式 def on_change_partner_id_return(self,cr,uid,ids,partner_id,context=None): resu ...