遍历Map
//Map接口中常用方法
增:put(K k,V v)
删:V remove(K k)
改:put(K k,V v)
查:V get(K k)
长度:int size()
遍历
Map<String,Integer> map = new HashMap<String,Integer>();
map.put();....
//遍历key
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key);
}
//遍历value
Collection<Integer> values = map.values();
Iterator<Integer> iterator = values.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//遍历key-value
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<String,Integer>> iterator = entrySet.iterator();
while(iterator.hasNext()){
Map.Entry<String,Integer> entry = iterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + "---->" + value);
}
//遍历获取HashMap<String,String>中所有value,并存放在list中返回,考虑上集合中泛用型的使用
public List<String> getValueList(HashMap<String,String> map){
ArrayList<String> valueList = new ArrayList<>();
Collection<String> values = map.values();
for(String value : values){
valueList.add(value);
}
return valueList;
}
//创建一个与a.txt文件同目录下的另外一个文件b.txt
File file1 = new File("d:\\a\\a.txt");
File file1 = new File(file1.getParent(),"b.txt");
泛型
JDK1.5之前 Object
JDK1.5之后 <E>
IO
文件IO:Input是读文件,Output是写文件
网络IO:Input是接收数据,Output是发送数据
1.文件名的后缀可自由定义(*.txt *.123 *.abc)
2.打开文件 outputStream = new FileOutputStream(file)
如果目标文件不存在,则创建新的文件
如果目标文件已经存在,则覆盖文件内容
//数据
byte[] data = {0, 2 ,4, 6, 8, 10, 12, 14}
//写入文件
File file = new File("example.123");
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(data, 0, 8);
outputStream.close();
//文件读取
1.从文件中读取数据到buffer
2.将buffer转成String
String str = new String(buffer, 0, "UTF-8");
写入时使用UTF-8编码,读取时也得使用UTF-8
UTF-8/GBK均可
//读取文件
byte[] buffer = new byte[1000];
File file = new File("example.123");
InputStream inputStream = new FileInputStream(file);
int n = inputStream.read(buffer, 0, 1000);
inputStream.close();
//文本写入
//数据
String str = "hello";
byte[] data = str.getBytes("UTF-8");
//写入文件
File file = new File("example.123");
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(data);
outputStream.close();
//用于接收数据的缓冲区,需足够大
byte[] buffer = new byte[1000];
//注意:把文件放在项目根目录下,不是src\子目录
File file = new File("example.123");
//从文件中读取数据,放到缓冲区中
InputStream ouInputStream = new FileInputStream(file);
int n =ouInputStream.read(buffer, 0, 1000);
ouInputStream.close();
System.out.printf("读取了 %d 个字节\n", n);
//将前N个字节转化成字符串
String str = new String(buffer, 0, n, "UTF-8"); //0-开始位置 n-长度
System.out.println("内容:" + str);
字符集Charset
所有英文字符、标点放在一起,称为ASCII字符集
ASCII:英文字符、标点
ISO8859:欧洲字符集,法、德、意、希腊等
GBK,GB2312,GB18030:中文字符集
GJK:中日韩
Unicode:全球统一编码,世界上所有字符和符号
字符编码Charset Encoding
用一个或多个字节来表示一个字符
ASCII:用1个字节表示一个字符
GBK:用2个字节表示一个字符
UTF-8:用1-3个字节表示一个Unicode字符
UTF-16:用2个字节表示一个Unicode字符
UTF-32:用4个字节表示一个Unicode字符
String.getBytes()实现字符编码
ByteBuffer_二进制编码解码
allocate():内部自己创建一个byte[]
wrap():利用外部现成的byte[]
//二进制编码
ByteBuffer bbuf = ByteBuffer.allocate(100);
bbuf.putInt(1234);
bbuf.putFloat(10.2f); //4个字节
int size = bbuf.position(); //内部指针位置
byte[] data = bbuf.array(); //内部数组
int capacity = bbuf.capacity(); //内部数组容量
Util.print(data, 0, size);
//二进制解码
File file = new File("example.123");
byte[] buffer = new byte[100];
int size = ReadFile(file, buffer);
ByteBuffer bbuf = ByteBuffer.wrap(buffer, 0, size);
bbuf.position(0); //把位置指针迁移到开头
int a = bbuf.getInt();
double b = bbuf.getDouble();
System.out.printf("a=%d, b=%f \n", a, b);
定长记录
当用文件存储列表数据时,每一条数据称为一条记录
变长记录:每条记录的大小是变化的
定长记录:每条记录的大小是固定的
比如,固定有100字节来保存一条Student数据
流式读写
InputStream 输入流,接收数据
OutputStream 输出流,发送数据
其中的Stream, 就是‘流’的意思
打开水龙头:
InputStream inputStream = new FileInputStream(file);
放水:
byte[] buffer = new byte[100];
int n = inputStream.read(buffer);
流式读写,又称为 顺序读写
发送时:一个接一个,依顺序发送
接收时:一个接一个,依顺序接收
流(Stream)是一种形象的说法:不可中断、不可跳跃
小文件的访问:
当文件较小时(比如,<1M字节)
写数据:先将所有数据编码到缓冲区,然后一次性写入
读数据:先将所有数据一次性读取,然后再作解析
内存操作是快的,硬盘read/write是慢速操作
byte[] buffer = new byte[X];
创建缓冲区时,X值太大,会创建失败
写入:
//将所有数据一次性编码到一个大缓冲区中
int numOfRecord = stuList.size();
byte[] buffer = new byte[100 * numOfRecord];
for (int i = 0; i < stuList.size(); i++) {
Student stu = stuList.get(i);
ByteBuffer bbuf = ByteBuffer.wrap(buffer, 100*i, 100);
bbuf.putInt(stu.id);
Util.encodeString(bbuf, stu.name, "UTF-8");
bbuf.put(stu.sex ? (byte)1 : (byte)0);
Util.encodeString(bbuf, stu.phone, "UTF-8");
}
//一次性全部写入到文件
File file = new File("example.123");
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(buffer, 0, 100 * numOfRecord);
outputStream.close();
System.out.println("共保存 %d条数据\n",stuList.size());
读取:
File file = new File("example.123");
int filesize = (int)file.length();
byte[] buffer = new byte[filesize];
//一次性读取文件中的所有数据
InputStream inputStream = new FileInputStream(file);
inputStream.read(buffer);
inputStream.close();
//解出数据
int numOfRecord = filesize/100;
for (int i = 0; i < numOfRecord; i++) {
ByteBuffer bbuf = ByteBuffer.wrap(buffer, i*100, 100);
int id = bbuf.getInt();
String name = Util.decodeString(bbuf,"UTF-8");
boolean sex = bbuf.get()>0;
String phone = Util.decodeString(bbuf, "UTF-8");
}
System.out.println(id + ", " + name + ", " + sex + ", " + phone);
大文件的访问:
1.流式访问:分段读写
2.随机访问
分段读写:
写入时,一段一段写入
读取时,一段一段读取
特点:read/write次数比较多
写入:
File file = new File("example.123");
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[100];
//多段写入
for (Student stu : stuList) {
ByteBuffer bbuf = ByteBuffer.wrap(buffer);
bbuf.putInt(stu.id);
Util.encodeString(bbuf, stu.name, "UTF-8");
bbuf.put(stu.sex ? (byte)1 : (byte)0);
Util.encodeString(bbuf, stu.phone, "UTF-8");
//固定长度的数据块:固定为100字节
outputStream.write(bbuf.array(), 0, 100);
}
outputStream.close();
读取:
File file = new File("example.123");
InputStream inputStream = new FileInputStream(file);
while (true) {
//每次读100字节
byte[] buffer = new byte[100];
int n = inputStream.read(buffer);
if (n!=100) break;
//解析出学生数据
ByteBuffer bbuf = ByteBuffer.wrap(buffer);
bbuf.position(0); //将位置指针移到开头
int id = bbuf.getInt();
String name = Util.decodeString(bbuf,"UTF-8");
boolean sex = bbuf.get()>0;
String phone = Util.decodeString(bbuf, "UTF-8");
System.out.println(id + ", " + name + ", " + sex + ", " + phone);
}
inputStream.close();
随机读写
随机读写:可以跳到文件的任意位置,读写任意位置的数据
RandomAccessFile rafile = new RandomAccessFile(file,"r");
rafile.seek(100);
int n = rafile.read(buffer);
读文件"r" 写文件"rw"
读取:
File file = new File("example.123");
byte[] buffer = new byte[100];
RandomAccessFile rafile = new RandomAccessFile(file,"r");
rafile.seek(100); //跳到100的位置
int n = rafile.read(buffer);
if (n!=100) break;
//解析出学生数据
ByteBuffer bbuf = ByteBuffer.wrap(buffer);
bbuf.position(0); //将位置指针移到开头
int id = bbuf.getInt();
String name = Util.decodeString(bbuf,"UTF-8");
boolean sex = bbuf.get()>0;
String phone = Util.decodeString(bbuf, "UTF-8");
System.out.println(id + ", " + name + ", " + sex + ", " + phone);
写:
rafile.write(bbuf.array(), 0, 100);
rafile.close();
rafile.seek(100); //fp:100
rafile.read(buffer, 0, 100); //fp:200
rafile.seek(500); //fp:500
rafile.write(buffer, 0, 200); //fp:700