视频教程参考:https://www.imooc.com/video/1832
1、文件的编码: 用什么编码的书写的文本,则需要对应的编码解码来读,否则会出现乱码
文本文件就是字节序列, 可以是任意编码的字节序列,如果我们在中文机器上直接创建文本文件,那么该文本文件只认识 ansi编码
package test;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class TestClass {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "学习ABC";
byte[] bytes = str.getBytes();//转换成字节序列是默认的编码
for (byte b : bytes) {
//toHexString把字节(转换成了int)以16进制的方式显示,并且只打印
//oxff默认为整形,二进制位最低8位是1111 1111,前面24位都是0;
System.out.print(Integer.toHexString(b & 0xff)+" ");
}
System.out.println();
byte[] bytes2 = str.getBytes("gbk");//
for (byte b : bytes2) {
//输出结果为【d1 a7 cf b0 41 42 43】,
//从结果看gbk编码中:中文占用两个字节,英文占用1个字节
System.out.print(Integer.toHexString(b & 0xff)+" ");
}
System.out.println();
byte[] bytes3 = str.getBytes("utf-8");//
for (byte b : bytes3) {
//输出结果为【e5 ad a6 e4 b9 a0 41 42 43 】,
//从结果看utf-8编码中文占用三个字节,英文占用1个字节
System.out.print(Integer.toHexString(b & 0xff)+" ");
}
//java是双字节编码 utf-16be
System.out.println();
byte[] bytes4 = str.getBytes("utf-16be");//
for (byte b : bytes4) {
//输出结果为【e5 ad a6 e4 b9 a0 41 42 43 】,
//从结果看utf-16be编码中文占用两个字节,英文占用两个字节
System.out.print(Integer.toHexString(b & 0xff)+" ");
}
/*
* 当你的字节序列是以某种编码时,这时候想把字节序列变成字符串,也需要用这种编码方式,
* 否则会出现乱码,换句话,编码时用A,解码时也得用A
* */
System.out.println();
String str1 = new String(bytes4);
//输出结果是【[fN` A B C】
System.out.println(str1); //出现了乱码,因为系统默认的是GBK去解码的,而字节bytes4是utf-16be编码的
System.out.println();
String str2 = new String(bytes4,"utf-16be");
//输出结果是【正确】
System.out.println(str2); //出现了乱码,因为系统默认的是GBK去解码的,而字节bytes4是utf-16be编码的
/*文本文件 就是字节序列,
* 可以是任意编码的字节序列,
* 如果我们在中文机器上直接创建文本文件,那么该文本文件只认识ansi编码*/
}
}
2、java.io.File类用于表示文件(目录)
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问
package test;
import java.io.File;
import java.io.IOException;
public class TestClass {
public static void main(String[] args) {
//了解构造函数的情况,查帮助
File file = new File("e:\\javaio");
//判断file是否存在
System.out.println(file.exists());
if (!file.exists()) {
file.mkdirs();//
}else {
file.delete();
}
//是否是一个目录
System.out.println(file.isDirectory());
//判断是否是一个文件
System.out.println(file.isFile());
System.out.println("***********************************");
File file2 = new File("e:\\javaio\\日记1.ppt"); //两种构造函数
//File file2 = new File("e:\\javaio1\\","日记1.ppt");
if (!file2.exists()) {
try {
file2.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
file2.delete();
}
System.out.println(file2.isFile());
//常用的File对象的API
System.out.println(file);//toString的方法
System.out.println(file.getAbsolutePath());
System.out.println(file2.getName());
System.out.println(file2.getAbsolutePath());
}
}
3、列出指定目录下(包括其子目录)的所有文件
测试
package test;
import java.io.File;
import java.io.IOException;
public class TestClass {
public static void main(String[] args) throws IOException {
File file = new File("e:\\javaio");
FileUtils.listDirectory(file);
}
}
package test;
import java.io.File;
import java.io.IOException;
import com.sun.xml.internal.ws.api.pipe.ThrowableContainerPropertySet;
public class FileUtils {
/**
* 列出指定目录下(包括其子目录)的所有文件
* @param dir
* @throws IOException
* */
public static void listDirectory(File dir) throws IOException{
if (!dir.exists()) {
throw new IllegalArgumentException("目录:"+dir+"不存在");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException(dir+"不是路径");
}
/*
String[] dirList = dir.list();//返回的字符串数据,直接是子的名称,不包含子目录下的内容
for (String str : dirList) {
System.out.println(dir.getAbsolutePath()+"\\"+str);
}
System.out.println("***************************************************");
*/
//如果要遍历子目录的内容就需要构造成File对象做递归操作,File提供了直接返回File对象的API
File[] files = dir.listFiles();//返回的是直接子目录的(文件)的抽象
if(files!= null && files.length>0){
for(File file : files){
if (file.isDirectory()) { //如果是.txt或者不是路径的情况直接打印
listDirectory(file); //递归
}else{
System.out.println(file);
}
}
}else{
System.out.println(dir);
}
}
}
4、 RandomAccessFile: java 提供的对文件内容的方法,即可以读,也可以写文件,支持随机访问文件,可以访问文件的任意位置。
1)java文件模型
在硬盘上的文件是byte byte byte 存储的,是数据的集合
2)打开文件
有两种模式“rw”(读写) “r”(只读)
RandomAccessFile raf = new RandomAccessFile(file, "rw")
文件指针,打开文件时指针在开头 pointer =0;
3)写方法
raf.write(int);-->只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
4)读方法
int b =raf.read() ---->读一个字节
5)文件读写完成以后一定要关闭(oracle官方说明)
package test;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import com.sun.imageio.spi.RAFImageInputStreamSpi;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
public class TestClass {
public static void main(String[] args) throws IOException {
File dir = new File("e:\\javaio");//没写绝对路径就是相对路径
if (!dir.exists()) {
dir.mkdir();
}
File file = new File("e:\\javaio\\io.dat");
if (!file.isDirectory()) {
file.createNewFile();
}
RandomAccessFile raf = new RandomAccessFile(file, "rw");
//输出指针位置为起始值0
System.out.println(raf.getFilePointer());
raf.write('A');//写一个字节,默认写低八位
raf.write('B');//写一个字节,默认写低八位
System.out.println(raf.getFilePointer());
int i = 0x7fffffff;
//用write方法每次只能写一个字节,如果把i(32位)写进去,就得写4次
raf.write(i>>>24);//先写高8位
raf.write(i>>>16);
raf.write(i>>>8);
raf.write(i);
raf.writeInt(i);//提供直接写整型的方法,源码其实就是上面的写法
String s = "中";
byte[] gbk = s.getBytes();
raf.write(gbk);
System.out.println(raf.getFilePointer());
//System.out.println(raf.length());
//读文件,必须把指针移动到头部
raf.seek(0);
byte[] buf = new byte[(int)raf.length()];
int sum = raf.read(buf);//返回字节的总数
System.out.println(sum+Arrays.toString(buf));
//以16进行的格式输出
for (byte b : buf) {
System.out.print(Integer.toHexString(b&0xff)+", ");
}
//必须关闭的
raf.close();
}
}
5 IO流(输入流、输出流)
/**
* IO流(输入流、输出流)
* 1)InputStream、OutStream
* InputStream抽象了应用程序读取数据的方式
* OutputStream抽象了应用程序写出数据的方式
* 2)EOF =End 读到 -1就读到结尾
* 3)输入流基本方法
* int b = in.read();读取一个字节无符号填充到int低八位,-1是EOF
* in.read(byte[] buf)
* in.read(byte[] buf,int start,int size)
* 4)输出流基本方法
* out.write(int b) 写出一个byte到流,b的低8位
* out.write(byte[] buf)将buf字节数组都写入到流
* out.write(byte[]buf,int start,int size),字节数组buf从start位置开始写size长度的字节到流
* 5)FileInputStream,具体实现了在文件上读取数据
*
* */
package test;
import java.io.IOException;
public class TestClass {
public static void main(String[] args) throws IOException {
IOUtils.printHex("E:\\javaio\\io.dat");
}
}
package test;
import java.io.FileInputStream;
import java.io.IOException;
public class IOUtils {
/**
* 读取制定文件内容,按照16进行输出到控制台
* 并且每输出10个byte换行
* @param filename
* @throws IOException
* */
public static void printHex(String filename) throws IOException{
//把文件作为字节流进行操作
FileInputStream in = new FileInputStream(filename);
int b; int i = 1;
while((b=in.read())!=-1){
System.out.println(Integer.toHexString(b)+" ");
if (i++%10 ==0) {
//换行
System.out.println();
}
}
in.close();
}
}