文件传输基础——Java IO流
来源:互联网 发布:curl json 编辑:程序博客网 时间:2024/06/05 22:10
- 文件的编码
- 1 文件的编码
- File 类的使用
- 1 File 类常用 API 介绍
- 2 遍历目录
- RandomAccessFile类的使用
- 1 RandomAccessFile基本操作
- 字节流
- 1 字节流之文件输入流FileInputStream-1
- 2 字节流之文件输入流FileInputStream-2
- 3 字节流之文件输出流FileOutputStream
- 4 字节流之数据输入输出流
- 5 字节缓冲流
- 字符流
- 1 字节字符转换流
- 文件的编码
1 文件的编码
1.1 文件的编码
public static void main(String[] args) { // TODO Auto-generated method stub String s = "慕课ABC"; /** * 转换成字节序列利用的是项目默认的编码, * eclipse查看项目默认编码的方式:点击项目->右击Properties->Resource->Text file encoding * 项目编码也可以显示的指定:byte[] bytes = s.getBytes("gbk"); */ byte[] bytes1 = s.getBytes(); for(byte b:bytes1) { // 把字节转换为int,以16进制的方式显示 System.out.print(Integer.toHexString(b & 0xff) + " "); } System.out.println(); try { byte[] bytes2 = s.getBytes("gbk"); /** * gbk编码中文占2个字节,英文占1个字节 */ for(byte b:bytes2) { System.out.print(Integer.toHexString(b & 0xff) + " "); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(); try { byte[] bytes3 = s.getBytes("utf-8"); /** * 在utf-8编码中,中文占用3个字节,英文占用1个字节 */ for(byte b:bytes3) { System.out.print(Integer.toHexString(b & 0xff)+" "); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(); byte[] bytes4 = null; try { /** * 在utf-16be中,中文和英文都占用2个字节 */ bytes4 = s.getBytes("utf-16be"); for(byte b:bytes4) { System.out.print(Integer.toHexString(b & 0xff)+" "); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(); /** * 字节序列转化为字符串时,当你的字节序列的编码方式与项目默认编码方式不同时, * 这个时候需要手动添加编码方式进行转换, * 否则会出现乱码 * */ String str1 = new String(bytes4); System.out.println(str1); try { String str2 = new String(bytes4,"utf-16be"); System.out.println(str2); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } /** * eclipse中什么编码的项目只认识什么编码的文件, * 将一个项目的文件拷贝到另一个编码方式不同的项目中,就会出现乱码, * 这就是直接拷贝别人项目文件出现乱码的原因 */ /** * 文本文件 就是字节序列 * 可以是任意编码的字节序列 * 如果我们在中文机器上直接创建文本文件,那么该文本文件只认识ansi编码 */}
2 File 类的使用
2.1 File 类常用 API 介绍
java.io.File 类用于表示文件(目录)
File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问
public static void main(String[] args) { // TODO Auto-generated method stub /** * eclipse中用 Alt+/ 来查看File的构造函数, * 文件分割符可以用 \\ 或者 / 或者 File.separator, * File.separator不论win系统还是linux系统,都表示分割符 */ File file = new File("D:\\javaio"); System.out.println(file.exists()); // 判断文件是否存在 if(!file.exists()) { file.mkdir(); // 创建一级目录 file.mkdirs(); // 如果文件不存在,创建多级目录 }else { file.delete(); // 如果文件存在,删除目录 } /** * 判断是否是一个目录 , * 如果是目录返回true,如果不是目录或者不存在返回false */ System.out.println(file.isDirectory()); // 判断是否是一个文件 System.out.println(file.isFile()); /** * 创建文件 */ File file2 = new File("d:\\javaio\\日记1.txt"); File file3 = new File("d:\\javaio","日记2.txt"); if(!file2.exists()) { try { file2.createNewFile(); // 文件不存在,创建这个文件 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else { file2.delete(); // 文件存在删除文件 } // 常用的File对象的API System.out.println(file); // 打印file.toString()的内容 System.out.println(file.getAbsolutePath()); // 打印路径 System.out.println(file.getName()); // 打印目录名 System.out.println(file2.getName()); // 打印文件名 System.out.println(file.getParent()); // 返回父目录路径 System.out.println(file2.getParent()); // 返回父目录路径 System.out.println(file.getParentFile().getAbsolutePath()); // 返回父目录路径}
2.2 遍历目录
package com.amoscxy;import java.io.File;import java.io.IOException;/** * 列出File的一些常用操作比如过滤、遍历等操作 * @author BG235144 * */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[] filenames = dir.list(); // for(String filename:filenames) {// System.out.println(dir+"\\"+filename);// } /** * 如果要遍历子目录下的内容就要构造成File对象做递归操作, * File提供了直接返回File对象的api, * 返回的是直接子目录(文件)的对象 */ File[] files = dir.listFiles();// for(File file:files) {// System.out.println(file);// } if(files!=null && files.length>0) { for(File file:files) { if(file.isDirectory()) { /** * 递归 */ listDirectory(file); }else { System.out.println(file); } } } }}
3 RandomAccessFile类的使用
3.1 RandomAccessFile基本操作
RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件。
RandomAccessFile支持随机访问文件,可以访问文件的任意位置
RandomAccessFile 读写过程:
1. Java文件模型:
在硬盘上的文件是byte byte byte存储,是数据的集合
2. 打开文件:
有两种模式”rw”(读写)”r”(只读)
RandomAccessFile raf = new RandomAccessFile(file,”rw”);
文件指针,pointer = raf.getFilePointer(),
打开文件时指针在开头 pointer = 0;
3. 写方法:
raf.write(int)—>只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
4. 读方法:
文件读写完成以后一定要关闭(oracle官方说明)
public static void main(String[] args) throws IOException{ File demo = new File("D:\\javaio"); if(!demo.exists()) { demo.mkdir(); } File file = new File(demo,"raf.dat"); if(!file.exists()) { file.createNewFile(); } RandomAccessFile raf = new RandomAccessFile(file,"rw"); // 指针位置 System.out.println(raf.getFilePointer()); /** * java中char是2个字节, * 只写最后边一个字节进去 */ raf.write('A'); System.out.println(raf.getFilePointer()); raf.write('B'); /** * 用write方法每次只能写一个字节, * 如果要把i写进去就得写4次 */ int i = 0x7fffffff; raf.write(i>>>24); // 高8位 raf.write(i>>>16); raf.write(i>>>8); raf.write(i); System.out.println(raf.getFilePointer()); // 可以直接写一个int raf.writeInt(i); /** * 可以直接写一个中文汉子, */ String s = "中"; byte[] gbk = s.getBytes("gbk"); /** * 可以写入字节数组 */ raf.write(gbk); System.out.println(raf.length()); /** * 读文件,必须把指针移到头部 */ raf.seek(0); /** * 一次性读取,把文件中的内容都读到字节数组中 */ byte[] buf = new byte[(int)raf.length()]; raf.read(buf); System.out.println(Arrays.toString(buf)); String s1 = new String(buf,"gbk"); System.out.println(s1); /** * 以16进制方式输出 */ for(byte b:buf) { System.out.print(Integer.toHexString(b & 0xff) + " "); } /** * 关闭 */ raf.close();}
输出
01612[65, 66, 127, -1, -1, -1, 127, -1, -1, -1, -42, -48]AB������中41 42 7f ff ff ff 7f ff ff ff d6 d0
4 字节流
4.1 字节流之文件输入流FileInputStream-1
public class IOUtil { /** * 读取指定文件内容,按照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.println("0"); } // 将整数b转换为16进制表示的字符串 System.out.print(Integer.toHexString(b) + " "); if(i++%10 == 0) { System.out.println(); } } in.close(); }}
4.2 字节流之文件输入流FileInputStream-2
/** * 从int中批量读取字节,放入到buf这个字节数组中, * 从第0个位置开始放,最多放buf.length个, * 返回的是读到的字节个数 */public static void printHexByByteArray(String fileName) throws IOException{ FileInputStream in = new FileInputStream(fileName); /** * 适宜大小,直到读取全部文件为止 */ byte[] buf = new byte[8*1024]; int bytes = 0; int j = 1; while((bytes = in.read(buf,0,buf.length))!=-1) { for(int i = 0; i < bytes; i ++) { if((buf[i] & 0xff) <= 0xf) { System.out.print("0"); } /** * byte类型8位,int类型32位, * 为避免数据转换错误,通过&0xff将高位24位请零 */ System.out.print(Integer.toHexString(buf[i] & 0xff)+" "); if(j++%10 == 0) { System.out.println(); } } }}
4.3 字节流之文件输出流FileOutputStream
public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub /** * 参数一:文件 * 参数二:是否在文本后面追加 */ FileOutputStream out = new FileOutputStream("D:\\javaio\\out.dat",true); out.write('A'); // 写出了'A'的低8位 out.write('B'); // 写出了'B'的低8位 int a = 10; // write 只能写低8位,那么写一个int需要写4次 out.write(a>>>24); // 写入高8位 out.write(a>>>16); out.write(a>>>16); out.write(a); byte[] gbk = "中国".getBytes("gbk"); out.write(gbk); // 可以写出字符数组 out.close();}
/** * 拷贝文件 * @param srcFile * @param destFile * @throws IOException */public static void copyFile(File srcFile,File destFile) throws IOException { if(!srcFile.exists()) { throw new IllegalArgumentException("文件" + srcFile + "不存在"); } if(!srcFile.isFile()) { throw new IllegalArgumentException(srcFile + "不是文件"); } if(!destFile.exists()) { destFile.createNewFile(); } 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();}
4.4 字节流之数据输入输出流
DataOutputStream/DataInputStream
对“流”功能的扩展,可以更加方便的读取int,long,字符等类型数据 DataOutputStream
writeInt()/writeDouble()/writeUTF()
public static void main(String[] args) throws IOException{ // TODO Auto-generated method stub String file = "D:\\javaio\\dos.dat"; /** * FileOutputStream 包装成 DataOutputStream 目的就是为了用它的 write 方法, * 写出基本数据类型的时候更加方便 */ 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(); /** * FileInputStream 包装成 DataInputStream 目的就是为了用 read 方法, * 读取基本数据类型的时候更加方便 */ DataInputStream dis = new DataInputStream(new FileInputStream(file)); int i = dis.readInt(); System.out.println(i); i = dis.readInt(); System.out.println(i); long j = dis.readLong(); System.out.println(j); double h = dis.readDouble(); System.out.println(h); String k = dis.readUTF(); System.out.println(k); dis.close();}
4.5 字节缓冲流
8) BufferedInputStream & BufferedOutputStream 这两个流类为 IO 提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了 IO 的性能,从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:
FileOutputStream —> write() 方法相当于一滴一滴地把水“转移”过去,
DataOutputStream—>writeXxx() 方法会方便一些,相当于一瓢一瓢把水“转移”过去,
BufferedOutputStream—>write()方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入缸中
FileInputStream/FileOutputStream(需要时间:20多万ms)
单字节,不带缓冲,进行文件拷贝
/**
* 单字节,不带缓冲,进行文件拷贝
* @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();
}
文件拷贝,字节批量读取(需要时间:7ms,拷贝文件速度最快)
/**
* 文件拷贝,字节批量读取
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFileBybuf(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();
}
DataInputStream/DataOutputStream
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
String file = "D:\\javaio\\dos.dat";
/**
* FileOutputStream 包装成 DataOutputStream 目的就是为了用它的 write 方法,
* 写出基本数据类型的时候更加方便
*/
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();
/**
* FileInputStream 包装成 DataInputStream 目的就是为了用 read 方法,
* 读取基本数据类型的时候更加方便
*/
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int i = dis.readInt();
System.out.println(i);
i = dis.readInt();
System.out.println(i);
long j = dis.readLong();
System.out.println(j);
double h = dis.readDouble();
System.out.println(h);
String k = dis.readUTF();
System.out.println(k);
dis.close();
}
BufferedInputStream/BufferedOutputStream(需要时间10万多ms)
进行文件的拷贝,利用带缓冲的字节流
/**
* 进行文件的拷贝,利用带缓冲的字节流
* @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();
}
5 字符流
5.1 字节字符转换流
1)编码问题
2)认识文本和文本文件
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码),文本是byte byte byte…的数据序列
文本文件是文本(char)按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果
3)字符流(输入流的抽象类:Reader、输出流的抽象类:Writer)
字符流的处理方式:读/写一次处理一个字符(可能是英文字符、中文字符、可能是不同编码的… 所占大小不同)
字符的底层,任然是基本的字节序列
字符流的基本实现
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamWriter 提供char流到byte流,按照编码处理
- 文件传输基础——Java IO流
- 文件传输基础——Java IO流
- 文件传输基础——Java IO流
- 文件传输基础——Java IO流
- 文件传输基础——Java IO流
- Java拾遗2:文件传输基础——Java IO流
- 文件传输基础——Java IO流笔记
- 文件传输基础—Java IO流 FileInputStream 的运用
- 文件传输基础----Java IO流
- 《文件传输基础----Java IO流---《一》》
- 《文件传输基础----Java IO流---《二》》
- 《文件传输基础----Java IO流---《三》》
- Java IO 流(文件传输基础)
- 文件传输基础(Java IO流)--慕课网笔记
- Java学习之文件传输基础---Java IO流
- 慕课JAVA之文件传输基础----JAVA IO流
- Java基础—IO流
- java基础—-IO流
- C语言单元小结(6)
- 数据结构实验之排序四:寻找大富翁
- Maven-01-私服搭建及使用
- 贪吃蛇的游戏设计和算法
- android之微信分享图片
- 文件传输基础——Java IO流
- C# 设计模式-生成器(Builder)
- 求两个整数的最大公约数
- Hbase-API-KeyValue、写缓冲区
- 智能蛇
- 蓝桥杯vip题 分解质因素
- Unity 物理系统
- java学习 2017-12-23
- 知识点小积累