对Java中File I/O的理解

来源:互联网 发布:java queue线程安全 编辑:程序博客网 时间:2024/05/16 09:57


昨天一个学妹问了我一个关于File文件读写操作的问题。结果弄了2个多小时才算勉强解决。自己对File文件的读写这块学的不扎实。于是,自己又翻出视频,API,网上找资料理解。自己也简单的写几个方法来使用一下File的读写操作吧。

一、文件编码

       我们通常在进行文件的读写操作的时候,经常可能会出现乱码。这里简单介绍几种编码集:

GBK:一个中文字符占两个字节,一个英文字符占一个字节。

UTF-8:一个中文字符一般占三个字节,一个英文字符占一个字节。(不是一个固定字节编码的,而是一种边长的编码方式。它可以使用1~4个字节表示一个符号。根据不同的符号而变化字节长度。最常见的编码方式是:1110xxxx 10xxxxxx

10xxxxxx)

UTF-16BE: Java的编码方法,一个中文和一个英文字符都是占两个字节。


注意:

       1>  字节序列转换成字符时要采用相同的编码方式,否则会乱码。 

        2>文本文件就是字节序列,可以是任意编码的字节序列,但是如果直接在中文机器上创建文本文件,那么改文本文件只认识ANSI  编码。

这里我们可以简单了解一下字符编码的过程(部分摘自互联网):

    美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0;后来欧洲人发现128位根本不够用,比如法国人字母上面的还有注音符,于是就把高1位编了进来。这样欧洲普遍使用一个全字节进行编码,最多可表示256位。欧美人就是喜欢直来直去,字符少,编码用得位数少;但是即使位数少,不同国家地区用不同的字符编码,虽然0--127表示的符号是一样的,但是128--255这一段的解释完全乱套了,即使2进制完全一样,表示的字符完全不一样,比如135在法语,希伯来语,俄语编码中完全是不同的符号;更麻烦的是,尼玛这电脑高科技传到中国后,中国人发现我们有10万多个汉字,你们欧美这256字塞牙缝都不够。于是就发明了GB2312这些汉字编码,典型的用2个字节来表示绝大部分的常用汉字,最多可以表示65536个汉字字符,这样就不难理解有些汉字你在新华字典里查得到,但是电脑上如果不处理一下你是显示不出来的了吧。这下各用各的字符集编码,这世界咋统一?俄国人发封email给中国人,两边字符集编码不同,显示都是乱码。为了统一,于是就发明了unicode,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,现在unicode可以容纳100多万个符号,每个符号的编码都不一样,这下可统一了,所有语言都可以互通,一个网页页面里可以同时显示各国文字。然而,unicode虽然统一了全世界字符的二进制编码,但没有规定如何存储。x86和amd体系结构的电脑小端序和大端序都分不清,别提计算机如何识别到底是unicode还是acsii了。如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,文本文件的大小会因此大出二三倍,这对于存储来说是极大的浪费。这样导致一个后果:出现了Unicode的多种存储方式。互联网的兴起,网页上要显示各种字符,必须统一,utf-8就是Unicode最重要的实现方式之一。另外还有utf-16、utf-32等。UTF-8不是固定字长编码的,而是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
这是种比较巧妙的设计,如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。 8、注意unicode的字符编码和utf-8的存储编码表示是不同的,例如"严"字的Unicode码是4E25,UTF-8编码是E4B8A5,这个7里面解释了的,UTF-8编码不仅考虑了编码,还考虑了存储,E4B8A5是在存储识别编码的基础上塞进了4E25。UTF-8 使用一至四个字节为每个字符编码。128 个 ASCII 字符(Unicode 范围由 U+0000 至 U+007F)只需一个字节,带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及马尔代夫语(Unicode 范围由 U+0080 至 U+07FF)需要二个字节,其他基本多文种平面(BMP)中的字符(CJK属于此类-Qieqie注)使用三个字节,其他 Unicode 辅助平面的字符使用四字节编码。


二、File类的使用

      File类是IO包中的一个类。用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。说到文件,一定会涉及到三个概念:相对路径名、绝对路径名、抽象路径名 

(摘自JDK API 1.6对于这三个路径的解释)

相对路径:相对路径名必须使用取自其他路径名的信息进行解释。默认情况下,java.io 包中的类总是根据当前用户目录来解析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。

绝对路径:绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。

抽象路径名:

抽象路径名 有两个组件:

  1. 一个可选的与系统有关的前缀 字符串,比如盘符,"/" 表示 UNIX 中的根目录,"\\\\" 表示 Microsoft Windows UNC 路径名。
  2. 零个或更多字符串名称 的序列。
抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC 路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。 抽象路径名没有前缀和名称序列。

以上是API文档的解释。下面我谈下自己的理解。

对于相对路径名,绝对路径名大家一般都是叫相对路径,绝对路径。很少用到抽象路径名。

相对路径名:比如一个项目存在D:\Work\JavaWork\IO 下,你要创建一个a.txt文本文件,这时采用相对路径创建就是

File file=new File("a.txt");if(!file.exists()){file.createNewFile();}

创建的文件就在 D:\Work\JavaWork\IO\a.txt;

如果是绝对路径名创建的话就是:

File file=new File("<span style="font-size:18px;">D:\Work\JavaWork\IO\</span>a.txt");if(!file.exists()){file.createNewFile();}
同样存在目录D:\Work\JavaWork\IO\a.txt;

抽象路径名可以通过调用 getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。

通过2个程序对比一下

                        File file=new File(".\\new_file.txt"); //  ./ 是当前路径   直接写new_file也是对的。但是体现不出AbsolutePath()                File file2=new File("D:\\Work\\JavaWork\\FileIo\\new_file2.txt");if(!file.exists()){file.createNewFile();}else{file.delete();}if(!file2.exists()){file2.createNewFile();}else{file2.delete();} System.out.println("AbsolutePath"+file.getAbsolutePath());System.out.println("Path"+file.getPath());System.out.println("AbsoluteFile"+file.getAbsoluteFile());System.out.println("CanonicalPath"+file.getCanonicalPath());System.out.println();System.out.println("AbsolutePath"+file2.getAbsolutePath());System.out.println("Path"+file2.getPath());System.out.println("AbsoluteFile"+file2.getAbsoluteFile());System.out.println("CanonicalPath"+file2.getCanonicalPath());

输出的结果:

AbsolutePathD:\Work\JavaWork\FileIo\.\new_file.txt
Path.\new_file.txt
AbsoluteFileD:\Work\JavaWork\FileIo\.\new_file.txt
CanonicalPathD:\Work\JavaWork\FileIo\new_file.txt

AbsolutePathD:\Work\JavaWork\FileIo\new_file2.txt
PathD:\Work\JavaWork\FileIo\new_file2.txt
AbsoluteFileD:\Work\JavaWork\FileIo\new_file2.txt
CanonicalPathD:\Work\JavaWork\FileIo\new_file2.txt


这时我们可以看到

getPath()得到的是构造file的时候的路径。
getAbsolutePath()得到的是全路径  。如果构造的时候就是全路径那直接返回全路径 ,如果构造的时候试相对路径,返回当前目录的路径+构造file时候的路径

getCanonicalPath()得到的是绝对路径。

getAbsoluteFile()返回此抽象路径名的绝对路径名形式。等同于new File(this.getAbsolutePath())


其中File类还有些其他方法的使用,大家可以自己查阅帮助文档。常用的有

1.创建File对象:File file=new File(String path);注意:File.seperater();获取系统分隔符,如:”\“.
2.boolean file.exists();是否存在.
3.file.mkdir();或者file.mkdirs();创建目录或多级目录。
4.file.isDirectory()或者file.isFile()判断是否是目录或者是否是文件。
5.file.delete();删除文件或目录。
6.file.createNewFile();创建新文件。
7.file.getName()获取文件名称或目录绝对路径。
8.file.getAbsolutePath()获取绝对路径。
9.file.getParent();获取父级绝对路径。
10.file.getSize();获取文件大小。
11.file.getFormat();获取文件格式名。


三、RandomAccessFile类的使用

RandomAccessFile java提供的对文件内容的读写访问,支持随机访问文件,可以访问文件的任意位置
(1)java 文件模型
             在硬盘上的文件是byte存储的 ,是数据的集合
(2)打开文件
             有两种模式 rw(读写) r(只读)
             RandomAccessFile raf-new RandomAccessFile(file "rw")
             文件指针,打开文件时指针在开头 pointer=0
(3)写方法
             raf write(int)--->只写一个字节(后8位)同时指针指向下一个位置,准备再次写入
(4)读方法
             int b=raf.read()-->读一个字节
(5)文件读写完成之后一定要关闭

关于RandomAccessFile类的介绍,推荐一篇文章:http://www.360doc.com/content/13/1230/13/9297708_341224012.shtml   当然,我也已经转载了。

四、字节流



0 0
原创粉丝点击