java中的IO流和多线程
1.如何用file操作目录和文件?
java对待目录和文件统一使用file来表示,在创建file对象时,使用isDictionary和isFile方法进行判断
package test;
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
File file1 = new File("E:/a.txt");
if (!file1.exists()) {
try {
file1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("创建文件失败!");
}
}
// 创建一个目录
File dir = new File("E:/testxjq");
// 判断是否为目录
if (dir.isDirectory()) {
// 得到所有的文件
String[] files = dir.list();
for (String fileName : files) {
// 用目录和文件名生成File对象
File f = new File(dir.getPath() + File.separator + fileName);
// 对生成的File对象进行分类打印
if (f.isFile()) {
System.out.println("文件为:" + f.getName());
} else if (f.isDirectory()) {
System.out.println("目录为:" + f.getName());
}else{
System.out.println("null");
}
}
}
else{
System.out.println("dsddssf");
}
}
}
总结:FIle类的常用方法:
(1)构造方法:传递字符串形式的文件路径的方式来创建file对象,file并不会检查该目录或者文件是否已经存在。
(2)IsDirectory和isFile方法用于判断File对象所代表的是目录还是普通的文件。
(3)createNewFile方法,采用file对象所存储的路径和文件名进行创建。
(4)List方法,用于目录,得到目录下所有的文件名,类型为字符串数组
(5)getName():得到文件名,不包含他的路径。
(6)Delete,删除文件
2.写一个复制文件的程序?
package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//生成的输入文件的输入流对象
FileInputStream fin = new FileInputStream("e:/a.txt");
//生成输出文件的输出流对象
FileOutputStream fout = new FileOutputStream("e:/b.txt");
//定义一个暂存数据的数组
byte[] buff = new byte[256];
//每次读取数据的长度
int len = 0;
while((len=fin.read(buff))>0){
fout.write(buff, 0, len);
}
fin.close();
fout.close();
}
}
3.如何使用随机存取文件RandomAccessfile类?
package test;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RanAccessFile {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//创建随机读取文件对象
RandomAccessFile file = new RandomAccessFile("E:/a.txt","rw");
//遍历file字节数据
for(int i = 0;i<file.length();i++){
//从内存中读取的都为二进制,将二进制转换为字节,字节转为字符
byte b = (byte)file.read();
char c = (char)b;
//如果对应的字符为a
if(c=='a'){
//指针回退原位置
file.seek(i);
//重写该位置的数据
file.write('c');
}
}
file.close();
System.out.println("ok");
}
}
总结:length方法获取文件的内容长度
seek方法随机达到任何需要存取数据的地方
read方法获取当前位置的数据,write方法写入数据
close方法关闭文件的打开。
4.字节流的处理方式?
计算机内部处理数据总是以一个byte为基本单位,字节流 就是每次读取的单位为byte,字节流是所有的流的基础,也是其他高级流 的前提。
java中的基础字节输入流和输出流类别:
inputStream和outputStream
以及:
FileInputStream和FileOutputStream
ObjectInputStream 和ObjectOutputStream
BufferedInputStream和BufferedOutputStream
也主要通过read和write方法把byte数组中的数据写入和读出。
5.字符流的处理方式?
字符流是由字节流包装而来的,输入和输出流的格式为
StringReader 和StringWriter
BufferedReader 和BufferedWriter:有特殊具备的ReadLine()方法
一个例子:
package test;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/*
* 按行读取文件并且打印
* */
public class ReaderTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//根据文件得到一个输入流
InputStream in = new FileInputStream("E:/a.txt");
//得到inputStreamReader对象
InputStreamReader isr = new InputStreamReader(in,"GBK");
//根据输入流创建Reader对象
BufferedReader br = new BufferedReader(isr);
//创建StringBuffer对象临时保存字符内容
StringBuffer sb = new StringBuffer();
String str = null;
while((str = br.readLine())!=null){
sb.append(str);
}
System.out.println("content:"+sb);
br.close();
isr.close();
in.close();
}
}
6.什么是序列化?
java对象内村中的数据采编成一串二进制数据,把这些数据存放在可以持久的数据存储设备,当需要还原数据时,通过反序列化,把对象重新还原到内存中。
java.io.Serializable接口是进行序列化的类的标志性接口,本省没有任何需要实现的抽象的方法,告诉jvm该类的对象可以进行序列化,序列化id由serialVersionUID变量提供。
serialVersionUID用来辨别类,如果在在反序列的时候,两个类的类名是相同的,就通过该id来进行辨别。
一个实现序列化和反序列化的例子:
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Person implements Serializable{
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//序列化id
private static final long serialVersionUID = 1L;
private String name;
private int age;
}
public class SerialTest {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
// TODO Auto-generated method stub
Person stu = new Person();
stu.setAge(20);
stu.setName("admin");
//创建对象的输出流,将对象输出到磁盘
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/a.dat"));
//开始写对象
oos.writeObject(stu);
oos.close();
//创建对象的输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/a.dat"));
//从磁盘中读取对象,再转换成一个实体
Person p = (Person)ois.readObject();
//输出
System.out.println(p.getAge());
System.out.println(p.getName());
}
}
结果:
20
admin
7.什么是多线程?
进程是整个程序或者部分程序的动态执行,线程是一组指令的集合,可以在程序中单独的运行。多线程是这样的一种机制,允许在程序中并发执行多个指令流,每个指令流都被称为一个线程,彼此间相互独立。
好处:
<1>使用线程可以把占据长时间的程序中的任务放到后台去处理。
<2>加快程序的运行速度
<3>在等待的任务下,线程可以去释放一些资源,如占用的内存。
8.进程和线程的区别?
<1>线程的划分尺度小于进程,线程属于某个进程
<2>进程是程序的一种动态形式,是CPU,内存等资源占用的基本单位,线程不可以独立拥有这些资源。
<3>线程之间共享一块内存区域,通信比较方便。
<4>进程在执行的过程中,会包含比较固定的入口,执行的顺序和出口,线程的这些过程会被应用程序所控制。
9.如何让一个类成为线程类?
方法一:实现java.lang.Runable接口
方法二:继承自java.lang.Thread类
本质上,Thread以及实现了Runable接口,你在继承Thread类的时候,已经实现了Runable接口,只是Thread类还提供了额外的方法。
package test;
public class RunTest implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("thread running");
}
}
package test;
public class RunTest extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("thread running");
}
}
10.Runnable接口和Thread类的区别?
<1>如果线程类继承了Thread类那么久不可以再继承其他的类,而Runnable接口是可以的,因为Java支持单继承。
<2>如果要使用很多的线程的方法,使用Thread更方便。
<3>实现Runnable接口的线程类的多个线程,可以更方便地访问同一个变量。
11.如何去启动一个线程?
针对继承自Thread类和实现了Runnable接口:
package test;
class ThreadTest extends Thread{
public void run(){
System.out.println("实现了Thread类");
}
}
class RunnableTest implements Runnable{
public void run(){
System.out.println("实现了runnable接口");
}
}
public class ThreadStartTest {
public static void main(String[] args) {
//直接继承了Thread ,创建一个Thread的实例
ThreadTest t1 = new ThreadTest();
//t1启动
t1.start();
//如果是实现了接口的线程类,需要用对象的实例作为Thread类构造方法的参数
Thread t2 = new Thread(new RunnableTest());
t2.start();
}
}
12.如何使用sychronized使得线程同步?
工作原理:每个对象都有一个线程锁,sychronized可以使用任何一个对象的线程锁来锁住一段代码,任何想要进入该段代码的线程必须在解锁后才可以继续进行,否则就进入等待状态。其中就进入等待的状态。
package test;
class Test extends Thread{
public static int index;
//定义一个对象用于控制线程同步
public static Object obj = new Object();
public void run(){
synchronized (obj) {
for(int i =0;i<10;i++){
System.out.println(index++);
}
}//end of synchronized
}
}
public class MyThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Test().start();
new Test().start();
new Test().start();
}
}
13.如何使用线程池?
组成部分:
完成一个任务的一个或者多个线程;
用于调度管理的管理线程;
要求执行的任务队列;
目的:为了最大程度的复用对象,最大程度的利用线程。
14.反射的理解?
反射提供了一种动态的功能,主要通过反射相关的API,就可以知道一个陌生的java类的所有的信息,包括属性、方法、构造器,这些元素完全可以在运行时动态的创建或者调用,不必再JVM运行时就进行确定。利用的是该类形成的java.lang.Class类的实例。
java用class类来代表所有的类,方便开发者掌控类的信息,如果得到了一个类的属性,方法等信息,就可以利用这个class创建实例,调用任何的方法,访问任何的属性,这就是反射的主要用处。
反射机制的API,主要集中在java.lang.reflect包下。
15.class类的的含义和作用是什么?
第一步:一个类会在什么时候被加载到JVM中呢?
<1>通过new关键字,使用该类的对象
Student stu = new Student()
<2>访问该类的静态的成员
Student.age;
<3>使用class.forName()方法进行加载
class.forName(“com.test.Student”);
第二布:如何得到一个类的class对象?
<1>Class.forName()方法
<2>访问类的class属性
<3>创建对象,调用对象的getClass()方法。
16.如何操作类的成员变量?field
反射式可以获取到类的对象,那就可以通过对象去获取成员变量。
方法:getDeclareField()方法或者getDeclareFields()方法获取。
一个例子:
package test;
import java.lang.reflect.Field;
//测试类
class Teacher{
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
//通过反射将会访问到的属性
String name;
int age;
}
public class FieldTest {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Teacher t1 = new Teacher("admin",23);
Teacher t2 = new Teacher("王老师",52);
System.out.println(compare(t1,t2).name+"'s age is bigger!");
}
//利用反射机制定义一个通用的比较的方法
@SuppressWarnings("unused")
private static Teacher compare(Teacher tea1,Teacher tea2) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
//第一个策略:通过对象的getClass()方法得到类的class对象
Field field = tea1.getClass().getDeclaredField("age");
//第二个策略:通过类的class的静态属性得到类的class对象
field = Teacher.class.getDeclaredField("age");
//获得两个对象的age值
int val1 = (int) field.get(tea1);
int val2 = (int) field.get(tea2);
//进行比较
if(val1>val2){
return tea1;
}else{
return tea2;
}
}//end of compare
}
17.如何通过反射操作类的方法?Method?
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class MethodTestClass {
public void m1() {
System.out.println("m1 is called!");
}
public void m2() {
System.out.println("m2 is called");
}
}
public class CallMethodTest {
public static void main(String[] args)
throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
args = new String[] { "m1" };
// 得到方法名
String methodName = args[0];
if (methodName != null) {
// 得到class实例
Class<MethodTestClass> clazz = MethodTestClass.class;
// 通过该实例去得到方法
Method m = clazz.getDeclaredMethod(methodName);
// 通过方法,如果方法不为空,就创建对应类的实例
if (m != null) {
MethodTestClass obj = clazz.newInstance();
// 通过m调用唤醒的方法,去唤醒这个对象
m.invoke(obj);
}
}
}
}
18.如利用反射去实例化一个类?
两种情况:
<1>默认的无参数的额构造方法:
Class类的newInstance()方法
<2>对于有参数的构造方法:
先获取一个constructor实例,再用newInsatnce()方法创建对象。
一个例子:
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class people{
public String getName() {
return name;
}
public void setName(String name) { this.name = name; } public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override public String toString() { return "people [name=" + name + ", age=" + age + "]"; } public people() {
super(); // TODO Auto-generated constructor stub } public people(String name, int age) { super(); this.name = name; this.age = age; } private String name; private int age; } public class NewInstanceTest { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub //step1:获取Class对象 Class<people> clazz = people.class; //step2:途径一:使用无参数的构造方法 //class对象直接获取实例 people obj = clazz.newInstance(); System.out.println("第一个对象:"+obj); obj.setName("xsxs"); obj.setAge(50); System.out.println("使用get/set方法后的名字:"+obj.getName()); System.out.println("使用get/set方法后的年龄:"+obj.getAge()); //step3:途径二:使用带参数的构造方法 //为构造器注入对应的值 Constructor<people> con = clazz.getConstructor(String.class,int.class); obj = con.newInstance("admin",30); System.out.println("第二个对象:"+obj); } }
19.如何利用反射来访问私有的成员?
package test;
import java.lang.reflect.Field;
class PrivateTestClass{
//定义构造方法
public PrivateTestClass(String field) {
super();
this.field = field;
}
private String field;//定义一个私有的属性
}
public class PrivateTest {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// TODO Auto-generated method stub
//创建测试类的实例
PrivateTestClass ptc = new PrivateTestClass("hello");
//通过该实例得到Class对象
Class clazz = ptc.getClass();
//通过对象调用方法得到字段字段
Field myprivatefield = clazz.getDeclaredField("field");
//设置访问属性为true
myprivatefield.setAccessible(true);
//get方法返回该Field对象所代表的特定的值
System.out.println(myprivatefield.get(ptc));
}
}
20.如何通过反射来覆盖数据对象的toString()方法?
产生的背景:
如果在一个类中要改变属性名称,新增属性,去掉属性,则在toString方法中也会重新再加入或者删除某些属性。
package test;
import java.lang.reflect.Field;
class DataObject{
public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public DataObject() { super(); // TODO Auto-generated constructor stub } public DataObject(String name, int age) { super(); this.name = name; this.age = age; } //为该类定义了俩个属性 private String name; private int age; //在类中实现自己的ToString方法 public String toString(){ //定义一个StringBuffer用于进行拼接 StringBuffer sb = new StringBuffer(); //通过反射得到所有成员变量的fields Field[] fields = this.getClass().getDeclaredFields(); //遍历集合 for(Field f:fields){ //得到一个变量的名 sb.append(f.getName()); //拼接上== sb.append("="); //得到变量的值 try { sb.append(f.get(this)); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } //每次拼接完一个变量,换行处理/空格处理 sb.append(" "); } //返回拼接后的字符串 return sb.toString(); }//end of toString() } public class DataObjectTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException { // TODO Auto-generated method stub //利用动态代理去实例化一个类 DataObject obj = new DataObject(); @SuppressWarnings("unchecked") Class<DataObject> clazz = (Class<DataObject>) obj.getClass(); DataObject my = clazz.newInstance(); //利用属性方法为属性赋值 my.setAge(100); my.setName("dddddd"); //输出打印时,调用了自定义toString方法 System.out.println(my); }
}
java中的IO流和多线程的更多相关文章
- java中的IO流
Java中的IO流 在之前的时候我已经接触过C#中的IO流,也就是说集中数据固化的方式之一,那么我们今天来说一下java中的IO流. 首先,我们学习IO流就是要对文件或目录进行一系列的操作,那么怎样操 ...
- Java中的IO流总结
Java中的IO流总结 1. 流的继承关系,以及字节流和字符流. 2. 节点流FileOutputStream和FileInputStream和处理流BufferedInputStream和Buffe ...
- Java中的IO流大体介绍
由于Java中的IO流是在是知识点繁多,所以我大约花了1周的时间将其整理起来.但是整理起来后并不是将完事了,我还是要分字节流和字符流来讲述.然后字节流和字符流中还有是否带有缓冲流. 讲述完IO流后我将 ...
- Java中的IO流,Input和Output的用法,字节流和字符流的区别
Java中的IO流:就是内存与设备之间的输入和输出操作就成为IO操作,也就是IO流.内存中的数据持久化到设备上-------->输出(Output).把 硬盘上的数据读取到内存中,这种操作 成为 ...
- Java中的IO流(五)
上一篇<Java中的IO流(四)>记录了一下Properties类,此类不属于IO流,它属于集合框架.接下来说一下IO流中的其它流 一,打印流PrintStream PrintStream ...
- Java中的IO流(六)
上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...
- JAVA 中的IO流
Java中的IO流是用来处理设备与设备之前的数据传输,在java中以流的形式传输.流分为两类:字节流和字符流. 字节流:InputStream,OutPutSteam.(计算机内的数据都是以字节存储的 ...
- Java中的IO流(四)
上一篇<Java中的IO流(三)>把IO流中的文件及目录操作的对象File类记录了一下,本篇把本不属性IO流但又和IO流有关系的一个对象作一下记录,此对象本属于集合框架里的一个子集,即Pr ...
- Java中的IO流(三)
上一篇<Java中的IO流(二)>把学习Java的字符流以及转换流作了一下记录,从本篇开始将把IO流中对文件或文件夹操作的对象File类的学习进行一下记录. 一,File类的构造函数及字段 ...
随机推荐
- iOS仿写下厨房
把之前简书的博客搬到博客园了,还是放在一个地方看着舒服. 先看一下做的效果,是不是还不错?(可以看一下早餐那块的轮播,上面盖着一个都是点点的图片,但是它不是和轮播一起滚动的,是盖在轮播上面的,需要在那 ...
- Js 组合键
同时按Ctrl+Enter或Alt+s 先上html代码 <style type="text/css"> #box{width: 500px; height: 500p ...
- os.linesep提取当前平台使用的换行符
1. unix平台的换行符:\n 2.DOS/Win32平台的换行符:\r\n 3.通过os.linesep函数可以提取当前所处平台的换行符,从而实现不需要关注程序运行在什么平台,也不需要根据不同的平 ...
- Codeforces 735D Taxes(简单数论)
题目链接 http://codeforces.com/problemset/problem/735/D 题意:一个人的收入为n他要交的税是n的最大除数,他为了少缴税将n分成k个数n1,n2,n2... ...
- Spring boot 全局配置 properties或者yml文件报错
主要问题是没有扫描到配置文件 在pom文件里面<build> </build>中加上以下代码就可以保证能扫描到了 <resources> <resour ...
- 在Linux查看版本命令
1.在终端中执行下列指令: cat /etc/issue 可以查看当前正在运行的 Ubuntu 的版本号. 2. 使用 lsb_release 命令也可以查看 Ubuntu 的版本号,与方法一相比,内 ...
- eclipse的properties文件中文被转码问题
如图所示:首次在properties里打中文注释,结果一输入中文就自动被转码,于是查看了一下项目的编码是UTF-8的,而eclipse中默认的properties文件编码是ISO的,所以修改一下即可 ...
- 机器学习——支持向量机(SVM)
支持向量机原理 支持向量机要解决的问题其实就是寻求最优分类边界.且最大化支持向量间距,用直线或者平面,分隔分隔超平面. 基于核函数的升维变换 通过名为核函数的特征变换,增加新的特征,使得低维度空间中的 ...
- 如何在IDEA中导入一个普通的java工程
1.如下: 2.如下,选中要导入的工程: 3.如下: 4.如下图 5.点击next,后如下图: 6.点击next后,如下图: 7.点击next后,如下图: 8.点击next后,如下图: 9.点击nex ...
- tarjan缩点(洛谷P387)
此题解部分借鉴于九野的博客 题目分析 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个 ...