在Java中有输入、输出两种IO流,每种输入、输出流又分为字节流和字符流两大类。关于字节,我们在学习8大基本数据类型中都有了解,每个字节(byte)有8bit组成,每种数据类型又几个字节组成等。关于字符,我们可能知道代表一个汉字或者英文字母。
但是字节与字符之间的关系是怎样的?
Java采用unicode编码,2个字节来表示一个字符,这点与C语言中不同,C语言中采用ASCII,在大多数系统中,一个字符通常占1个字节,但是在0~127整数之间的字符映射,unicode向下兼容ASCII。而Java采用unicode来表示字符,一个中文或英文字符的unicode编码都占2个字节。但如果采用其他编码方式,一个字符占用的字节数则各不相同。可能有点晕,举个例子解释下。
例如:Java中的String类是按照unicode进行编码的,当使用String(byte[] bytes, String encoding)构造字符串时,encoding所指的是bytes中的数据是按照那种方式编码的,而不是最后产生的String是什么编码方式,换句话说,是让系统把bytes中的数据由encoding编码方式转换成unicode编码。如果不指明,bytes的编码方式将由jdk根据操作系统决定。
getBytes(String charsetName)使用指定的编码方式将此String编码为 byte 序列,并将结果存储到一个新的 byte 数组中。如果不指定将使用操作系统默认的编码方式,我的电脑默认的是GBK编码。
getBytes(String charsetName)
public class Hel { public static void main(String[] args){ String str = "你好hello"; int byte_len = str.getBytes().length; int len = str.length(); System.out.println("字节长度为:" + byte_len); System.out.println("字符长度为:" + len); System.out.println("系统默认编码方式:" + System.getProperty("file.encoding")); } }
输出结果
字节长度为:9 字符长度为:7 系统默认编码方式:GBK
这是因为:在 GB 2312 编码或 GBK 编码中,一个英文字母字符存储需要1个字节,一个汉字字符存储需要2个字节。 在UTF-8编码中,一个英文字母字符存储需要1个字节,一个汉字字符储存需要3到4个字节。在UTF-16编码中,一个英文字母字符存储需要2个字节,一个汉字字符储存需要3到4个字节(Unicode扩展区的一些汉字存储需要4个字节)。在UTF-32编码中,世界上任何字符的存储都需要4个字节。
简单来讲,一个字符表示一个汉字或英文字母,具体字符与字节之间的大小比例视编码情况而定。有时候读取的数据是乱码,就是因为编码方式不一致,需要进行转换,然后再按照unicode进行编码。
File类是java.io包下代表与平台无关的文件和目录,也就是说,如果希望在程序中操作文件和目录,都可以通过File类来完成。
//构造函数File(String pathname) File f1 =new File("c:\\abc\\1.txt"); //File(String parent,String child) File f2 =new File("c:\\abc","2.txt"); //File(File parent,String child) File f3 =new File("c:"+File.separator+"abc");//separator 跨平台分隔符 File f4 =new File(f3,"3.txt"); System.out.println(f1);//c:\abc\1.txt
路径分隔符: windows: "/" "\" 都可以 linux/unix: "/" 注意:如果windows选择用"\"做分割符的话,那么请记得替换成"\",因为Java中"\"代表转义字符 所以推荐都使用"/",也可以直接使用代码File.separator,表示跨平台分隔符。 路径: 相对路径: ./表示当前路径 ../表示上一级路径 其中当前路径:默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。”
File.separator
绝对路径: 绝对路径名是完整的路径名,不需要任何其他信息就可以定位自身表示的文件
//如果文件存在返回false,否则返回true并且创建文件 boolean createNewFile(); //创建一个File对象所对应的目录,成功返回true,否则false。且File对象必须为路径而不是文件。只会创建最后一级目录,如果上级目录不存在就抛异常。 boolean mkdir(); //创建一个File对象所对应的目录,成功返回true,否则false。且File对象必须为路径而不是文件。创建多级目录,创建路径中所有不存在的目录 boolean mkdirs() ; //如果文件存在返回true并且删除文件,否则返回false boolean delete(); //在虚拟机终止时,删除File对象所表示的文件或目录。 void deleteOnExit();
boolean canExecute() ;//判断文件是否可执行 boolean canRead();//判断文件是否可读 boolean canWrite();//判断文件是否可写 boolean exists();//判断文件是否存在 boolean isDirectory();//判断是否是目录 boolean isFile();//判断是否是文件 boolean isHidden();//判断是否是隐藏文件或隐藏目录 boolean isAbsolute();//判断是否是绝对路径 文件不存在也能判断
String getName();//返回文件或者是目录的名称 String getPath();//返回路径 String getAbsolutePath();//返回绝对路径 String getParent();//返回父目录,如果没有父目录则返回null long lastModified();//返回最后一次修改的时间 long length();//返回文件的长度 File[] listRoots();// 列出所有的根目录(Window中就是所有系统的盘符) String[] list() ;//返回一个字符串数组,给定路径下的文件或目录名称字符串 String[] list(FilenameFilter filter);//返回满足过滤器要求的一个字符串数组 File[] listFiles();//返回一个文件对象数组,给定路径下文件或目录 File[] listFiles(FilenameFilter filter);//返回满足过滤器要求的一个文件对象数组
其中包含了一个重要的接口FileNameFilter,该接口是个文件过滤器,包含了一个accept(File dir,String name)方法,该方法依次对指定File的所有子目录或者文件进行迭代,按照指定条件,进行过滤,过滤出满足条件的所有文件。
accept(File dir,String name)
// 文件过滤 File[] files = file.listFiles(new FilenameFilter() { @Override public boolean accept(File file, String filename) { return filename.endsWith(".mp3"); } });
file目录下的所有子文件如果满足后缀是.mp3的条件的文件都会被过滤出来。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8