问题描述:本人在读一个很大的文件,大概100M,因为用BufferedReader读取速度太慢,所以想用多线程读取,现在已经可以把文件内容打印到控制台输入,但是在run方法中往SWT的StyledText中添加时从是报空指针异常,如:org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3563)
at org.eclipse.swt.SWT.error(SWT.java:3481)
at org.eclipse.swt.SWT.error(SWT.java:3452)
at org.eclipse.swt.widgets.Widget.error(Widget.java:432)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:326)
at org.eclipse.swt.custom.StyledText.append(StyledText.java:1476)
at shiyan.FileDrag$FileThread.run(FileDrag.java:582)
at java.lang.Thread.run(Unknown Source)下面把线程代码贴出来,请各位大侠帮忙看下什么问题,应该怎么解决,小弟非常感谢
//线程类
public class FileThread implements Runnable { // 分块总数
private int blockCount;
// 开始读取的块序号
private int blockNo;
// 缓存大小
private int maxBuffSize = 1024 * 1024;
// 来源文件
private String sourceFile;
// 目标文件
private String targetFile;
public StyledText stytext;
String result="";
/**
* 将sourceFile文件分blockCount块后的第blockNo块复制至sourceFile
*
* @param sourceFile 来源文件全名
* @param targetFile 目标文件全名
* @param blockCount 文件分块读取数
* @param blockNo 开始读取的块序号
*/
public FileThread(String sourceFile, String targetFile, int blockCount,int blockNo,StyledText styledTextUI) {
this.sourceFile = sourceFile;
this.targetFile = targetFile;
this.blockCount = blockCount;
this.blockNo = blockNo;
this.stytext = styledTextUI;
}
public void run() { // 得到来源文件
File file = new File(sourceFile);
// 得到来源文件的大小
long size = file.length();
// 根据文件大小及分块总数算出单个块的大小
long blockLenth = size / blockCount;
// 算出当前开始读取的位置
long startPosition = blockLenth * blockNo;
// 实例化缓存
byte[] buff = new byte[maxBuffSize];
InputStream is = null;
RandomAccessFile raf = null;
try {
// 从源文件得到输入流
is = new FileInputStream(sourceFile);
// 得到目标文件的随机访问对象
// raf = new RandomAccessFile(targetFile, "rw");
// 将目标文件的指针偏移至开始位置
// raf.seek(startPosition);
// 当前读取的字节数
int curReadLength = 0;
// 累计读取字节数的和
int totalReadLength = 0;
// 将来源文件的指针偏移至开始位置
is.skip(startPosition);
// stytext.append("添加上了么");
// 依次分块读取文件
while ((curReadLength = is.read(buff)) > 0
&& totalReadLength < blockLenth) {
// 将缓存中的字节显示
// raf.write(buff, 0, curReadLength);
result =new String(buff,0,curReadLength);
System.out.println(result);
stytext.append(result);
//System.out.println();
// 累计读取的字节数
totalReadLength += curReadLength;
}
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
// 关闭相关资源
try {
if (raf != null) {
raf.close();
}
if (is != null) {
is.close();
}
}
catch (IOException ex) {
ex.printStackTrace();
raf = null;
is = null;
} }
} }//以下是调用线程的两个方法
public void readerFilesThread(String sourceFile, String targetFile, int blockCount,StyledText styledText ) { // 依次分块进行文件COPY
for (int i = 0; i < blockCount; i++) {
// 实例化文件复制对象
FileThread fileThread = new FileThread(sourceFile, targetFile, blockCount, i,styledText);
// 实例化线程
Thread thread = new Thread(fileThread);
// 开始线程
thread.start();
try {
// 加入线程
thread.join();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public void ReaderFile(){
// String str = "";
if (!text.getText().trim().equals("")) {
text.setText("");
}
String name = file.substring(file.lastIndexOf("\\") + 1, file.length());
item1.setText(name);
if (!file.equals(" ")) {
String sourceFile = file;
String targetFile = "";
int blockCount = 5;
long beginTime = System.currentTimeMillis();
this.readerFilesThread(sourceFile, targetFile, blockCount,text);
long endTime = System.currentTimeMillis();
System.out.println("共用时:" + (endTime - beginTime) + "ms");
//坚定拖动事件
this.Actions();
}
}请各位大侠帮忙看下,谢谢了
at org.eclipse.swt.SWT.error(SWT.java:3563)
at org.eclipse.swt.SWT.error(SWT.java:3481)
at org.eclipse.swt.SWT.error(SWT.java:3452)
at org.eclipse.swt.widgets.Widget.error(Widget.java:432)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:326)
at org.eclipse.swt.custom.StyledText.append(StyledText.java:1476)
at shiyan.FileDrag$FileThread.run(FileDrag.java:582)
at java.lang.Thread.run(Unknown Source)下面把线程代码贴出来,请各位大侠帮忙看下什么问题,应该怎么解决,小弟非常感谢
//线程类
public class FileThread implements Runnable { // 分块总数
private int blockCount;
// 开始读取的块序号
private int blockNo;
// 缓存大小
private int maxBuffSize = 1024 * 1024;
// 来源文件
private String sourceFile;
// 目标文件
private String targetFile;
public StyledText stytext;
String result="";
/**
* 将sourceFile文件分blockCount块后的第blockNo块复制至sourceFile
*
* @param sourceFile 来源文件全名
* @param targetFile 目标文件全名
* @param blockCount 文件分块读取数
* @param blockNo 开始读取的块序号
*/
public FileThread(String sourceFile, String targetFile, int blockCount,int blockNo,StyledText styledTextUI) {
this.sourceFile = sourceFile;
this.targetFile = targetFile;
this.blockCount = blockCount;
this.blockNo = blockNo;
this.stytext = styledTextUI;
}
public void run() { // 得到来源文件
File file = new File(sourceFile);
// 得到来源文件的大小
long size = file.length();
// 根据文件大小及分块总数算出单个块的大小
long blockLenth = size / blockCount;
// 算出当前开始读取的位置
long startPosition = blockLenth * blockNo;
// 实例化缓存
byte[] buff = new byte[maxBuffSize];
InputStream is = null;
RandomAccessFile raf = null;
try {
// 从源文件得到输入流
is = new FileInputStream(sourceFile);
// 得到目标文件的随机访问对象
// raf = new RandomAccessFile(targetFile, "rw");
// 将目标文件的指针偏移至开始位置
// raf.seek(startPosition);
// 当前读取的字节数
int curReadLength = 0;
// 累计读取字节数的和
int totalReadLength = 0;
// 将来源文件的指针偏移至开始位置
is.skip(startPosition);
// stytext.append("添加上了么");
// 依次分块读取文件
while ((curReadLength = is.read(buff)) > 0
&& totalReadLength < blockLenth) {
// 将缓存中的字节显示
// raf.write(buff, 0, curReadLength);
result =new String(buff,0,curReadLength);
System.out.println(result);
stytext.append(result);
//System.out.println();
// 累计读取的字节数
totalReadLength += curReadLength;
}
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
// 关闭相关资源
try {
if (raf != null) {
raf.close();
}
if (is != null) {
is.close();
}
}
catch (IOException ex) {
ex.printStackTrace();
raf = null;
is = null;
} }
} }//以下是调用线程的两个方法
public void readerFilesThread(String sourceFile, String targetFile, int blockCount,StyledText styledText ) { // 依次分块进行文件COPY
for (int i = 0; i < blockCount; i++) {
// 实例化文件复制对象
FileThread fileThread = new FileThread(sourceFile, targetFile, blockCount, i,styledText);
// 实例化线程
Thread thread = new Thread(fileThread);
// 开始线程
thread.start();
try {
// 加入线程
thread.join();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public void ReaderFile(){
// String str = "";
if (!text.getText().trim().equals("")) {
text.setText("");
}
String name = file.substring(file.lastIndexOf("\\") + 1, file.length());
item1.setText(name);
if (!file.equals(" ")) {
String sourceFile = file;
String targetFile = "";
int blockCount = 5;
long beginTime = System.currentTimeMillis();
this.readerFilesThread(sourceFile, targetFile, blockCount,text);
long endTime = System.currentTimeMillis();
System.out.println("共用时:" + (endTime - beginTime) + "ms");
//坚定拖动事件
this.Actions();
}
}请各位大侠帮忙看下,谢谢了
解决方案 »
- 在DOS下,编译程序,提示“ 软件包 org.htmlparser 不存在”。
- Java中如何调用C# dll中的带有List参数的函数及返回List对象(Java JNI高手,Help!)
- 关于用Scanner提取一个.txt文件中的信息
- applet是什么
- 新手问题!!关于环境配置!!
- 怎样在一个类中调用另一个类中已经定义的变量
- 如何实现多线程中单写多读?
- 谁能告诉我关于jbuilder较好的站点。
- 钱该怎么赚???什么JAVA编译器才是最常用的???
- ArrayList如何传参?
- 菜人JAVA問題,一個小程序。謝謝!!!
- swing中的setFocusableWindowState,在swt里面对应的是什么方法哦。
这个不是空指针,是线程访问错误,SWT不允许非UI线程直接访问UI线程。在非UI线程里,要用这种形式访问UI:display.syncExec(
new Runnable() {
public void run(){
label.setText(text);
}
});参考:
http://www.eclipse.org/swt/faq.php