五 字符集转换和乱码问题
a) 文件都是按字节存储的,即使是使用字符流对文件进行写入,最终也会转换成字节
进行存储。这时就需要将字符转换成字节,不同的字符集一般转换成的字节格式是
不同的。看下面代码
String str = "字符"; byte[] utf8 = str.getBytes("utf-8"); System.err.println(Arrays.toString(utf8)); //输出:[-27, -83, -105, -25, -84, -90] byte[] gbk = str.getBytes("gbk"); System.err.println(Arrays.toString(gbk)); //输出:[-41, -42, -73, -5]
b) 由上面的代码可以看出,UTF-8字符集中,一个汉字占了3个字节,GBK占了两个
字节。所以如果用UTF-8转换的字节写入文件,用GBK读取是会出现乱码的情况。
建议用什么字符集写入就用什么字符集读取 。
c) 不同的字符集,一般所表示的字符是相同的,不同的是表示字符的字节。所以遇到
乱码情况,可以先以存入时的字符集,进行读取。然后再以需要的字符集进行存入。
d) 通过String实现字符集转换
String str = "字符"; //按utf-8字符集格式,将字符转换成字节 byte[] utf8 = str.getBytes("utf-8"); //按utf-8字符集格式,将字节转换成字符 str = new String(utf8, "utf-8"); //按gbk字符集格式,将字符转换成字节 byte[] gbk = str.getBytes("gbk"); //按gbk字符集格式,将字节转换成字符 str = new String(gbk, "gbk"); System.out.println(str);//输出:字符
e) 通过java.nio.Charset实现字符集转换,ByteBuffer和CharBuffer都是nio包中的类
一般作为nio通道的缓存使用
// 虚拟机中的可用字符集 SortedMap<String, Charset> sort = Charset.availableCharsets(); for (String charsetName : sort.keySet()) System.err.println(charsetName);// 输出所有字符集名称 // 查看虚拟机默认字符集,在虚拟机启动时默认字符集确定,通常取决于底层操作系统的语言环境和字符集。 Charset charset = Charset.defaultCharset(); System.err.println(charset);// 输出:GBK // 判断虚拟机字符集是否可用 boolean boo = Charset.isSupported("GBK"); System.err.println(boo);// 输出:true String str = "字符"; // 注册一个字符集 Charset gbk = Charset.forName("GBK"); // 按gbk字符集格式,将字符转换成字节 ByteBuffer bb = gbk.encode(str); // byte[] bytes = bb.array(); // 按gbk字符集格式,将字节转换成字符 CharBuffer cb = gbk.decode(bb); System.out.println(cb);// 输出:字符 Charset utf8 = Charset.forName("utf-8"); System.out.println(utf8.decode(utf8.encode(cb)));// 输出:字符
一 File类
a)File.pathSeparator系统有关的默认路径分隔符 windows是; unix是:
b)File.separator系统有关的默认名称分隔符 windows是\,unix是/
c)mkdirs()方法可以创建路径中所有不存在的目录
public static void main(String[] args) throws IOException { String path = "D:" + File.separator + "test.txt"; File file = new File(path); // 文件如果不存在 if (!file.exists()) { // 创建一个文件夹 file.mkdir(); // 删除一个文件/文件夹 if (file.exists()) file.delete(); // 创建一个文件 file.createNewFile(); } }
c) 文件/文件夹的名字、路径
public static void main(String[] args) throws IOException { String path = "D:" + File.separator; File file = new File(path); // 判断file是否是文件夹 if (file.isDirectory()) { // 返回当前目录下所有文件\文件夹名字 String[] names = file.list(); for (String name : names) { System.out.println(name); } // 返回当前目录下,每个文件\文件夹的File对象 File[] files = file.listFiles(); for (File elem : files) {//遍历名字、路径 System.out.println(elem.getName()); System.out.println(elem.getPath()); } } }
d) 递归目录中所有文件
public class IoTest { /** * 递归当前目录下所有文件 */ public static void filePrintln(File file) throws IOException { //遍历当前目录下所有项 for (File f : file.listFiles()) if (f.isDirectory()) //如果是一个目录 filePrintln(f);// 递归 else System.out.println(f.getPath()); } public static void main(String[] args) throws IOException { String path = "D:" + File.separator ; IoTest.filePrintln(new File(path)); } }
e) file.listFiles(filter)方法可以传一个FilenameFilter接口的实现类,这个接口只有一个方法
accept(),提供该参数的目的是listFiles()会回调accept(),进而决定哪些文件是所需的。
f)这是一个典型的策略模式,listFiles()可以根据FilenameFilter的不同实现类,进行文件
的筛选。
import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.regex.Pattern; public class IoTest { public static class FileName implements FilenameFilter{ private Pattern pattern; /** * 构造器 * @param regex 传入一个正则表达式,指定为一个字符串 */ public FileName(String regex){ //regex必须先编译成这个类的一个实例,由此可以产生一个匹配器,可以匹配任何字符序列 this.pattern = Pattern.compile(regex); } @Override public boolean accept(File dir, String name) { //通过正则表示匹配器,对每个文件名name进行筛选是否符合条件 return pattern.matcher(name).matches(); } } public static void main(String[] args) throws IOException { String path = "D:" + File.separator ; File file = new File(path); //匹配小写字母命名的java文件 File[] files = file.listFiles(new IoTest.FileName("[a-z]+\\.[Jj]ava")); for(File f : files){ System.out.println(f.getPath()); } } }
二 Paths类、Files类、Path接口
a)以上的类或接口都是Java SE7中添加进来的,在java.nio.file包中
b)Paths类只有两个方法,主要作用是生成Path对象
c)Path对象跟其名字意义是一样的,只涉及对路径的操作
public static void main(String[] args) throws IOException { String p = "D:" + File.separator + "file" + File.separator + "TEXT.txt"; // 初始化一个Path对象 Path path = Paths.get(p); //或者,功能等同于上面 path = Paths.get("D:","file","TEXT.txt"); //方法参数Paths.get(String first, String... more) // Path对象——>File对象 File file = path.toFile(); // File对象——>Path对象 path = file.toPath(); // 文件路径 System.out.println(path); // 输出:D:\file\TEXT.txt // 文件名 System.out.println(path.getFileName()); // 输出:TEXT.txt // 父路径,没有时返回null System.out.println(path.getParent()); // 输出:D:\file //跟路径 System.out.println(path.getRoot()); //输出:D:\ //移除.和..等冗余的路径元素 path.normalize(); //创建一个同级的Path对象 Path path2 = path.resolveSibling("TEXT2.txt"); System.out.println(path2); //输出:D:\file\TEXT2.txt //可以在目录下创建文件Path对象 Path path3 = path.resolve("TEXT2.txt"); System.out.println(path3); //输出:D:\file\TEXT.txt\TEXT2.txt }
d)Files只涉及对文件的操作,但是基本都是通过路径Path这个媒介
public static void main(String[] args) throws IOException { // 初始化一个Path对象 Path path = Paths.get("D:", "file", "TEXT.txt"); // 文件是否存在,第二个参数貌似还没有什么实际意义 Files.exists(path, LinkOption.NOFOLLOW_LINKS); // 是否目录 Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS); // 按字节度量尺寸,只适用文件 Files.size(path); //读取文件的属性,可以得到文件的创建、修改时间等 BasicFileAttributes ba = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); // 删除文件 Files.deleteIfExists(path); }
e)Files类可以很方便的处理中等长度的文本文件
public static void main(String[] args) throws IOException { // 初始化一个Path对象 Path path = Paths.get("D:", "file", "TEXT.txt"); // 读取文件中所有内容 byte[] bytes = Files.readAllBytes(path); // 按照行进行读入 List<String> lines = Files.readAllLines(path, Charset.forName("GBK")); // 写入内容到文件,第二个参数貌似有问题,不太好用 Files.write(path, "sss".getBytes(), StandardOpenOption.WRITE); // 在文件后面追加内容 Files.write(path, "追加".getBytes(), StandardOpenOption.APPEND); // 复制字节输入流到文件 Files.copy(System.in, path, StandardCopyOption.REPLACE_EXISTING); // 可以生成字节流、字符流 InputStream in = Files.newInputStream(path, StandardOpenOption.READ); BufferedReader bf = Files.newBufferedReader(path, Charset.forName("GBK")); }
f)通过Files创建目录或者文件不成功,记下以后解决
public static void main(String[] args) throws IOException { // 初始化一个Path对象 Path path = Paths.get("D:","file","TEXTa.txt"); //创建新目录 //文件属性集合 Set<PosixFilePermission> set = EnumSet.allOf(PosixFilePermission.class); // 这里会抛错,貌似windows不支持posix Files.createDirectories(path, PosixFilePermissions.asFileAttribute(set)); //创建一个文件,同上面一样执行无法通过 Files.createFile(path, PosixFilePermissions.asFileAttribute(set)); }
g)Files可以很方便的复制文件
public static void main(String[] args) throws IOException { // 初始化一个Path对象 Path fromPath = Paths.get("D:","file","TEXT.txt"); Path pathTo = Paths.get("D:","file","aaa","TEXT.txt"); // 将文件从一个位置复制到另一个位置 Files.copy(fromPath, pathTo, StandardCopyOption.REPLACE_EXISTING); //复制并删除源文件 Files.move(fromPath, pathTo, StandardCopyOption.REPLACE_EXISTING); //REPLACE_EXISTING 取代现有文件 //COPY_ATTRIBUTES复制所有文件属性 //ATOMIC_MOVE 操作原子性,成功||什么都没做 }
h)Files 对文件进行遍历,在遍历所有目录及其子目录时功能很强大
public static void main(String[] args) throws IOException { // 初始化一个Path对象 Path path = Paths.get("D:", "file"); // 得到当前目录下所有文件路径。这种try的写法,1.7中新功能,可以自动关闭流 try(DirectoryStream<Path> dir = Files.newDirectoryStream(path)){ for (Path entry : dir) System.out.println(entry); } // 通过glob模式对文件进行过滤 DirectoryStream<Path> dirGlob = Files.newDirectoryStream(path, "*.java"); // 遍历所有目录及其子目录,后台也是通过递归来实现 Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { // 输出所有文件路径 System.out.println(file); return super.visitFile(file, attrs); } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { // 输出所有目录路径 System.out.println(dir); return super.preVisitDirectory(dir, attrs); } }); }
讲解一下上面的最后一个方法
//其中第二个参数FileVisitor有四个方法 //方法1:在遇到文件时调用(非目录) FileVisitResult visitFile(T file, BasicFileAttributes attrs) //方法2:在处理一个目录之前调用 FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) // 方法3:在处理一个目录之后调用 FileVisitResult postVisitDirectory(T dir, IOException exc) //方法4:在试图处理一个文件或目录时发生错误,例如没有权限打开目录 FileVisitResult visitFileFailed(T file, IOException exc) //在执行上面4个步骤时,都会返回FileVisitResult对象,可以指定是否希望执行下面的操作 //1:继续访问下一个文件 FileVisitResult.CONTINUE //2:继续访问,但是不访问这个目录下的任何项 FileVisitResult.SKIP_SIBLINGS //3:终止访问 FileVisitResult.TERMINATE
相关推荐
Java IO NIO and NIO 2 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn...
1. 改进的文件系统接口(File API):引入了java.nio.file包,其中包括Path、Paths、Files类,提供了更为现代和灵活的文件处理方法。 2. 异步I/O(Asynchronous I/O):提供了更多的异步操作支持,允许I/O操作在后台...
涉及到java io, nio, aio相关知识点,学习过程中的一些总结,持续更新中,xmind 格式
Java IO NIO and NIO 2 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Java IO(Input/Output)是Java编程语言中用于处理输入输出操作的基础框架,它提供了丰富的类库,使得程序能够与各种设备、文件、网络进行数据交互。然而,传统的IO模型在处理大量并发连接时表现出效率较低的问题,...
Java IO与NIO是Java平台中用于处理输入输出操作的核心技术。它们在处理数据传输、文件操作、网络通信等方面起着至关重要的作用。本篇将深入探讨这两个领域,旨在帮助开发者更好地理解和应用这些概念。 首先,Java ...
### Java IO 与 Java NIO 的区别 在深入探讨Java IO与Java NIO之间的区别之前,我们先简单回顾一下这两种I/O模型的基本概念。 #### 1. Java IO(Blocking IO) Java IO,也称为传统的阻塞式IO或同步阻塞式IO,是...
- **Charsets**:详细讨论了 Java 中支持的各种字符集,以及如何在 Java 程序中正确地使用它们。 - **CharsetServiceProvider 接口**:介绍了 CharsetServiceProvider 接口的作用及其实现方式。 ### 结论 Java NIO...
java.io clojure.java.io 的 JK7 java.nio.file.Path 兼容性依赖信息该库托管在 Releases 上。 依赖: [me.moocar/java.io " 0.1.0 " ]用法是 JDK7 中引入的文件路径的抽象。 这个库提供了和 Paths 之间的兼容性。 ...
Java IO (Input/Output) 和 NIO (Non-blocking Input/Output) 是Java平台中用于处理输入和输出操作的重要部分。这两种技术在实现客户端与服务器之间的通信时起着至关重要的作用。下面将详细介绍Java IO和NIO的特点、...
Java NIO(New IO)是Java平台提供的一种新的IO操作模式,它首次出现在Java 1.4版本中,并在后续版本中不断完善。Java NIO 的设计目的是为了克服传统Java IO API在面对大量并发连接时存在的性能瓶颈。 ##### 使用...
Java IO和NIO提供了两种不同的I/O处理方式,各有优势和适用场景。IO适用于简单的I/O操作,而NIO则适合于需要高性能和高并发的应用。了解这两种I/O处理方式的区别和特点,可以帮助开发者根据具体的应用需求选择合适的...
java学习笔记1(java io/nio)设计模式
java io nio nio2 java io的百科全书 mobi格式 需要kindle 软件
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...
Java IO(Input/Output)和NIO(New IO)是Java平台中用于处理输入和输出操作的核心库。这两个系统提供了不同的方式来读取和写入数据,分别适用于不同类型的场景和需求。 Java IO体系主要基于流(Stream)的概念,...
在探讨Java.nio与Java.io之间的比较时,我们首先需要理解这两个包在Java编程语言中的核心作用和它们各自的优势。Java.io和Java.nio是Java中处理输入/输出操作的两个主要框架,它们各自拥有独特的特性和应用场景。 #...
File类是Java IO中的基础类,它主要用于文件和目录的创建、删除、重命名以及属性查询等操作。例如,你可以使用`new File("path")`创建一个File对象,然后调用`exists()`检查文件是否存在,`mkdirs()`创建多级目录,`...
相比于传统的IO(Input/Output)模型,NIO引入了非阻塞I/O、字符转换、缓冲和通道等新特性,极大地提高了Java程序在处理I/O操作时的性能。 1. **Buffer**:在传统的IO操作中,数据通常直接在流之间传输,这可能导致...