@guoxs
2016-05-24T23:31:56.000000Z
字数 8669
阅读 2565
java
JAVA中的双字节编码(UTF-16be),中文和英文都占用两个字节。
toHexString()
: 把字节转换成int以16进制的方式显示
当你的字节序列是某种编码时,如果想要把字节序列变成字符串,也需要用这种编码方式,否则会出现乱码。
文本文件就是字节序列,可以是任意编码的字节序列,如果在中文机器上直接创建文本文件,那么该文本文件只认识ANSI编码。
java.io.File类用于表示文件(目录)
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。
1.File file = new File("e:\\filename");
File file1 = new File("e:"+File.separator()+"filename);自动创建分隔符
File file2 = new File("e:\\io\\日记.txt");//自动创建没有的文件
(File file2 = new File("e:\\io","日记.txt");
if(!file.exist()) {
file2 = createNewFile();
}
2.file.exist();//判断文件是否存在,会有异常,需要捕捉
3.if(!file.exist()) {
file.mkdir();//创建目录
file.mkdirs();//创建多级目录
file.delete();//删除目录
4.file.isDirectory();//判断是否是目录
5.file.isFile();//是否是一个文件
6.常用的file对象的api
System.out.print(file);//打印toString对象,目录
file.getAbsolutePath();//目录
file.getName();//打印名字
file.getParent();//父目录
遍历目录
public ststic void listDirectory(File dir) throws IOException{
if(!dir.exists()){
throw new IllegalArgumentException("目录" + dir + "不存在");
}
if(!dir.isDirectory()){
throw new IllegalArgumentException(dir + "不是目录");
}
File[] files = dir.listFiles();
if(files!=null && files.length > 0){
for(File file : files){
if(file.isDirectory()){
listDirectory(file);
}else{
System.out.println(file);
}
}
}
}
RandomAccessFile
java提供的对文件内容的访问,既可以读文件,也可以写文件。
RandomAccessFile支持随机访问文件,可以访问文件的任意位置
打开文件
有两种模式"rw"(读写) "r"(只读)
RandomAccessFile raf = new RandomeAccessFile(file,"rw")
文件指针,打开文件时指针在开头 pointer = 0;
InputStream
抽象了应用程序读取数据的方式 OutputStream
抽象了应用程序写出数据的方式
int b = in.read();//读取一个字节无符号填充到int**低八位**,高八位补0-1是 EOF
in.read(byte[] buf);// 直接读到字节数组中
in.read(byte[] buf,int start,int size) ;//读取数据到字节数组buf,从buf的start位置开始存放size长度的数据
out.write(int b); //写出一个byte到流,b的低8位
out.write(byte[] buf); //将buf字节数组都写入到流
out.write(byte[] buf,int start,int size)
**
* 读取指定文件内容,按照16进制输出到控制台
* 并且每输出10个byte换行
* @param fileName
* 单字节读取不适合大文件,大文件效率很低
*/
public static void printHex(String fileName) throws IOException{
//把文件作为字节流进行读操作
FileInputStream in = new FileInputStream(fileName);
int b ;
int i = 1;
while((b = in.read())!=-1){
if(b <= 0xf){
//单位数前面补0
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
if(i++%10==0){
System.out.println();
}
}
in.close();
}
/**
* 批量读取,对大文件而言效率高,也是我们最常用的读文件的方式
* @param fileName
* @throws IOException
*/
public static void printHexByByteArray(String fileName)throws IOException{
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[8 * 1024];
/*从in中批量读取字节,放入到buf这个字节数组中,
* 从第0个位置开始放,最多放buf.length个
* 返回的是读到的字节的个数
*/
/*int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
int j = 1;
for(int i = 0; i < bytes;i++){
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10==0){
System.out.println();
}
}*/
int bytes = 0;
int j = 1;
while((bytes = in.read(buf,0,buf.length))!=-1){
for(int i = 0 ; i < bytes;i++){
/*byte类型为8位,int类型为32位,为了避免数据转换错误,通过 & 0xff将高24位清零*/
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10==0){
System.out.println();
}
}
}
in.close();
}
文件拷贝操作:
/*效率最高*/
public static void copyFile(File srcFile,File destFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是文件");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[8*1024];
int b ;
while((b = in.read(buf,0,buf.length))!=-1){
out.write(buf,0,b);
out.flush();//最好加上
}
in.close();
out.close();
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//如果该文件不存在,则直接创建,如果存在,删除后创建
FileOutputStream out = new FileOutputStream("demo/out.dat");
out.write('A');//写出了'A'的低八位
out.write('B');//写出了'B'的低八位
int a = 10;//write只能写八位,那么写一个int需要些4次每次8位
out.write(a >>> 24);
out.write(a >>> 16);
out.write(a >>> 8);
out.write(a);
byte[] gbk = "中国".getBytes("gbk");
out.write(gbk);
out.close();
}
}
DataOutputStream writeInt()/writeDouble()/writeUTF()
public class DosDemo {
public static void main(String[] args) throws IOException {
String file = "demo/dos.dat";
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(file));
dos.writeInt(10);
dos.writeInt(-10);
dos.writeLong(10l);
dos.writeDouble(10.5);
//采用utf-8编码写出
dos.writeUTF("中国");
//采用utf-16be编码写出
dos.writeChars("中国");
dos.close();
}
}
FileOutputStream
--->write()方法相当于一滴一滴地把水“转移”过去 DataOutputStream
-->writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去 BufferedOutputStream
--->write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了
/**
* 进行文件的拷贝,利用带缓冲的字节流
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是文件");
}
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int c ;
while((c = bis.read())!=-1){
bos.write(c);
bos.flush();//一定要加,刷新缓冲区
}
bis.close();
bos.close();
}
/**
* 单字节,不带缓冲进行文件拷贝,效率最低
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFileByByte(File srcFile,File destFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是文件");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(destFile);
int c ;
while((c = in.read())!=-1){
out.write(c);
out.flush();
}
in.close();
out.close();
}
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文件是byte byte byte ...的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果
public static void main(String[] args)throws IOException {
FileInputStream in = new FileInputStream("e:\\javaio\\imoocutf8.txt");
InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式
FileOutputStream out = new FileOutputStream("e:\\javaio\\imoocutf81.txt");
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
/*int c ;
while((c = isr.read())!=-1){
System.out.print((char)c);
}*/
char[] buffer = new char[8*1024];
int c;
/*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个
返回的是读到的字符的个数
*/
while(( c = isr.read(buffer,0,buffer.length))!=-1){
String s = new String(buffer,0,c);
System.out.print(s);
osw.write(buffer,0,c);
osw.flush();
}
isr.close();
osw.close();
}
字符的处理,一次处理一个字符
字符的底层任然是基本的字节序列
字符流的基本实现
InputStreamReader
完成byte流解析为char流,按照编码解析
OutputStreamWriter
提供char流到byte流,按照编码处理
FileReader/FileWriter
public static void main(String[] args) throws IOException{
FileReader fr = new FileReader("e:\\javaio\\imooc.txt");
FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt");
//FileWriter fw = new FileWriter("e:\\javaio\\imooc2.txt",true);//追加
char[] buffer = new char[2056];
int c ;
while((c = fr.read(buffer,0,buffer.length))!=-1){
fw.write(buffer,0,c);
fw.flush();
}
fr.close();
fw.close();
}
public static void main(String[] args) throws IOException{
//对文件进行读写操作
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("e:\\javaio\\imooc.txt")));
/*BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("e:\\javaio\\imooc3.txt")));*/
PrintWriter pw = new PrintWriter("e:\\javaio\\imooc4.txt");
//PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush);
String line ;
while((line = br.readLine())!=null){
System.out.println(line);//一次读一行,并不能识别换行
/*bw.write(line);
//单独写出换行操作
bw.newLine();//换行操作
bw.flush();*/
pw.println(line);
pw.flush();
}
br.close();
//bw.close();
pw.close();
}
对象必须实现序列化接口 ,才能进行序列化,否则将出现异常这个接口,接口没有任何方法,只是一个标准
public static void main(String[] args) throws Exception{
String file = "demo/obj.dat";
//1.对象的序列化
/*ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
Student stu = new Student("10001", "张三", 20);
oos.writeObject(stu);
oos.flush();
oos.close();*/
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(file));
Student stu = (Student)ois.readObject();
System.out.println(stu);
ois.close();
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
分析ArrayList源码中序列化和反序列化的问题
- 序列化中 子类和父类构造函数的调用问题
对子类对象进行反序列化操作时, 如果其父类没有实现序列化接口,那么其父类的构造函数会被调用