本篇将完成对词的统计,使用了讯飞语言云进行解析,还完成了对单个字使用的统计,统计完成可以一键导出数据到sdcard根目录下进行查看。
大概的步骤如下:
词的统计
1、读取文件文字
2、因为讯飞语言云单次解析不能超过70个分词,所以需要对数量进行分组
3、每分一组启动一个IntentService进行网络请求
4、网络请求完毕对文字进行筛选,保存到数据库
5、所有的网络请求完成后显示数据
字的统计
1、读取文件文字
2、对文字进行筛选,保存到数据库
3、完成后显示数据
涉及的技术:
ormlite数据库
Retrofit2.0同步和异步请求
IntentService的使用
效果图展示:
主界面的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<Button
android:id="@+id/button_terms"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="词统计"/>
<Button
android:id="@+id/button_word"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="字统计"/>
<Button
android:id="@+id/button_clear"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清空数据"/>
<Button
android:id="@+id/button_export"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="导出数据"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="结果:"
android:textSize="20dp"/>
<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
主界面类,需要注意的是讯飞语言云单次解析不能超过70个分词,所以这里进行了分组,每组最多50个字,避免请求失败
package com.mwf.analyze.activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.github.angads25.filepicker.controller.DialogSelectionListener;
import com.github.angads25.filepicker.model.DialogConfigs;
import com.github.angads25.filepicker.model.DialogProperties;
import com.github.angads25.filepicker.view.FilePickerDialog;
import com.mwf.analyze.R;
import com.mwf.analyze.bean.AnalyzeBean;
import com.mwf.analyze.dao.AnalyzeDao;
import com.mwf.analyze.services.ParseTermService;
import com.mwf.analyze.services.ParseWordsService;
import com.mwf.analyze.utils.FileUtils;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* 1、打开文件
* 2、开启子线程读取文件数据并分组
* 3、开启IntentService对每组请求数据
* 4、对返回数据进行处理
*/
public class AnalyzePoemActivity extends AppCompatActivity implements View.OnClickListener, ParseTermService.IUpdateUI, ParseTermService.ILoadFinish, ParseWordsService.ILoadWorsdFinish {
public final String TAG = this.getClass().getName();
@BindView(R.id.button_terms)
Button button_terms;
@BindView(R.id.button_word)
Button button_word;
@BindView(R.id.button_export)
Button button_export;
@BindView(R.id.button_clear)
Button button_clear;
@BindView(R.id.txt_content)
TextView mTxtContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analyze_poem);
ButterKnife.bind(this);
getSupportActionBar().hide();
//显示上一次的数据
AnalyzeDao dao = new AnalyzeDao(AnalyzePoemActivity.this);
List<AnalyzeBean> list = dao.queryAll(300, true);
String text;
for (int i = 0; i < list.size(); i++) {
text = mTxtContent.getText().toString();
text += (list.get(i).getName() + " ==" + list.get(i).getAmount() + "个\n");
mTxtContent.setText(text);
}
}
/**
* 打开文件选择器
*/
private void openFile(DialogSelectionListener listener) {
DialogProperties properties = new DialogProperties();
properties.selection_mode = DialogConfigs.SINGLE_MODE;
properties.selection_type = DialogConfigs.FILE_SELECT;
properties.root = new File(DialogConfigs.DEFAULT_DIR);
properties.error_dir = new File(DialogConfigs.DEFAULT_DIR);
properties.offset = new File(DialogConfigs.DEFAULT_DIR);
properties.extensions = null;
FilePickerDialog dialog = new FilePickerDialog(AnalyzePoemActivity.this, properties);
dialog.setTitle("选择一个文件");
dialog.setDialogSelectionListener(listener);
dialog.show();
}
/**
* 词统计
*/
private void parseTerms() {
DialogSelectionListener listener = new DialogSelectionListener() {
@Override
public void onSelectedFilePaths(String[] files) {
if (files != null && files.length >= 0) {
readTermThread(files[0]);
//清空内容
mTxtContent.setText("");
}
}
};
openFile(listener);
}
/**
* 开启线程读取文件内容
*/
private void readTermThread(final String path) {
//每组文字的长度
final int arrayLength = 50;
Thread mThread = new Thread() {
@Override
public void run() {
String string = FileUtils.readTxtFile(path);
if (!TextUtils.isEmpty(string)) {
double total = string.length();
double d = new Double(Math.round(total / arrayLength));
int size = (int) (Math.ceil(d));
Log.e(TAG, "总长度=" + total);
Log.e(TAG, "d=" + d);
Log.e(TAG, "分组=" + size);
//初始化IntentService
Intent intent = new Intent(AnalyzePoemActivity.this, ParseTermService.class);
ParseTermService.setUpdateUI(AnalyzePoemActivity.this);
ParseTermService.setLoadFinish(AnalyzePoemActivity.this);
//分组查询文字
for (int i = 0; i < size; i++) {
String singleString = "";
if (i == size - 1) {
//最后一组长度为总长度
singleString = string.substring(i * arrayLength, string.length());
} else {
//截取每一组的文字
singleString = string.substring(i * arrayLength, (i + 1) * arrayLength);
}
Log.e(TAG, "第" + i + "组");
Log.e(TAG, singleString);
//将每组数据传送给IntentService做处理
intent.putExtra("poemString", singleString);
intent.putExtra("number", i);
intent.putExtra("total", size);
//开启一个IntentService
startService(intent);
}
}
}
};
mThread.start();
}
@Override
public void updateUI(Message message) {
UIHandler.sendMessage(message);
}
/**
* 更新UI操作
*/
private final Handler UIHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
String something = bundle.getString("something");
double total = bundle.getInt("total", 0);
double number = bundle.getInt("number", 0);
double lastPercent = number / total * 100;
DecimalFormat df = new DecimalFormat("#.##");
mTxtContent.setText("完成比例: " + df.format(lastPercent) + "%,请耐心等候!");
}
};
@Override
public void loadFinsh() {
loadFinishHandler.sendEmptyMessage(0);
}
/**
* 数据加载完毕操作
*/
private final Handler loadFinishHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mTxtContent.setText("");
AnalyzeDao dao = new AnalyzeDao(AnalyzePoemActivity.this);
List<AnalyzeBean> list = dao.queryAll(200, false);
String text;
for (int i = 0; i < list.size(); i++) {
text = mTxtContent.getText().toString();
text += (list.get(i).getName() + " ==" + list.get(i).getAmount() + "个\n");
mTxtContent.setText(text);
}
}
};
/**
* 字统计
*/
private void parseWords() {
DialogSelectionListener listener = new DialogSelectionListener() {
@Override
public void onSelectedFilePaths(String[] files) {
if (files != null && files.length >= 0) {
//清空内容
mTxtContent.setText("");
//初始化IntentService
Intent intent = new Intent(AnalyzePoemActivity.this, ParseWordsService.class);
intent.putExtra("filePath", files[0]);
startService(intent);
ParseWordsService.setLoadFinish(AnalyzePoemActivity.this);
}
}
};
openFile(listener);
}
@Override
public void LoadWorsdFinish() {
loadFinishHandler.sendEmptyMessage(0);
}
/**
* 导出数据
*/
private void export() {
AnalyzeDao dao = new AnalyzeDao(AnalyzePoemActivity.this);
List<AnalyzeBean> list = dao.queryAll();
String text = "";
for (int i = 0; i < list.size(); i++) {
text += (list.get(i).getName() + " ==" + list.get(i).getAmount() + "个\n");
}
File file = Environment.getExternalStorageDirectory();
FileUtils.saveTxt(text, AnalyzePoemActivity.this, file.getAbsolutePath());
}
@Override
@OnClick({R.id.button_terms, R.id.button_word, R.id.button_export,R.id.button_clear})
public void onClick(View view) {
if (view.getId() == R.id.button_terms) {
parseTerms();
} else if (view.getId() == R.id.button_word) {
parseWords();
} else if (view.getId() == R.id.button_export) {
export();
}else if (view.getId() == R.id.button_clear) {
//清空数据库
new AnalyzeDao(AnalyzePoemActivity.this).deletedAll();
//清空内容
mTxtContent.setText("");
}
}
}
ParseTermService类,这里使用了IntentService来进行处理,因为它是串联并且是在子线程进行的,所以可以按照顺序来进行请求,也不会阻塞主线程。另外,这里的网络请求也使用了同步请求,避免因为异步请求导致并发操作数据库的情况发生。
IntentService一些优点:
1、如果直接继承Service,不能把耗时或阻塞的代码写在onStartCommand()等回调方法中,因为这些方法是在主线程中运行的,那样会影响主线程运行,影响用户使用。所以一般会在onStartCommand()启动线程来运行耗时任务,这样任务会在后台执行,不会影响主线程。
2、onHandleIntent()方法不是在主线程中运行,而是在单独线程中运行,所以不会影响主线程。相当于IntentService 已经帮我们启动了一个线程,所以我们不用自己去写启动线程的代码。
3、同一时间只会有一个耗时任务被执行,其他的请求还要在后面排队, onHandleIntent()方法不会多线程并发执行
4、当所有startService()请求被执行完成后,IntentService 会自动销毁,所以不需要自己写stopSelf()或stopService()来销毁服务
package com.mwf.analyze.services;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.mwf.analyze.Constant;
import com.mwf.analyze.bean.CloudResultPlainParse;
import com.mwf.analyze.bean.FamousInfoReq;
import com.mwf.analyze.dao.AnalyzeDao;
import com.mwf.analyze.model.FamousInfoModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import retrofit2.Call;
import retrofit2.Response;
/**
* 处理词的服务类
*/
public class ParseTermService extends IntentService {
public final String TAG = this.getClass().getName();
/**
* 更新界面回调
*/
private static IUpdateUI iUpdateUI;
/**
* 结束加载回调
*/
private static ILoadFinish iLoadFinish;
/**
* 网络请求
*/
private FamousInfoModel famousInfoModel;
/**
* 数据库访问
*/
private AnalyzeDao dao;
public ParseTermService() {
super("com.mwf.analyze.services.ParseTermService");
famousInfoModel = FamousInfoModel.getInstance(this);
}
public static void setUpdateUI(IUpdateUI iUpdateUIInterface) {
iUpdateUI = iUpdateUIInterface;
}
public static void setLoadFinish(ILoadFinish iLoadFinishInterface) {
iLoadFinish = iLoadFinishInterface;
}
/**
* 更新界面回调接口
*/
public interface IUpdateUI {
void updateUI(Message message);
}
/**
* 结束加载回调接口
*/
public interface ILoadFinish {
void loadFinsh();
}
/**
* 初始化请求参数
*/
private FamousInfoReq initParams(String text) {
FamousInfoReq mFamousInfoReq = null;
mFamousInfoReq = new FamousInfoReq();
mFamousInfoReq.api_key = Constant.APIKEY;
mFamousInfoReq.text = text;
mFamousInfoReq.pattern = "ws";
mFamousInfoReq.format = "plain";
return mFamousInfoReq;
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//语言云每秒最大调用次数200次,防止调用过多
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
dao = new AnalyzeDao(ParseTermService.this);
//获取需要请求的文字
String requestText = intent.getStringExtra("poemString");
//获取总共的组数
int total = intent.getIntExtra("total", 0);
//当前的组数
int number = intent.getIntExtra("number", 0);
// // 异步
// famousInfoModel.queryLookUp(initParams(requestText)).enqueue(new Callback<String>() {
// @Override
// public void onResponse(Call<String> call, Response<String> response) {
// Log.i(TAG, "请求成功!");
// String result = response.body().trim();
// CloudResultPlainParse parse = new CloudResultPlainParse();
// ArrayList<String> list = parse.parse(result);
// String strList = "";
// for (int i = 0; i < list.size(); i++) {
//// strList+= list.get(i)+"\n";
// strList += list.get(i);
// }
// Message message = new Message();
// Bundle bundle = new Bundle();
// bundle.putString("something", strList);
// message.setData(bundle);
// iUpdateUI.updateUI(message);
// }
//
// @Override
// public void onFailure(Call<String> call, Throwable t) {
// Log.i(TAG, "请求失败!");
// }
// });
// 同步请求可以根据顺序来
Call<String> infoCall = famousInfoModel.queryLookUp(initParams(requestText));
try {
Response<String> response = infoCall.execute();
String result = response.body().trim();
//解析数据
CloudResultPlainParse parse = new CloudResultPlainParse();
ArrayList<String> list = parse.parse(result);
String strList = "";
for (int i = 0; i < list.size(); i++) {
strList += list.get(i) + "\n";
String word = list.get(i);
dbSave(word);
}
//通知界面进行更新
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("something", strList);
bundle.putInt("number", number);
bundle.putInt("total", total);
message.setData(bundle);
iUpdateUI.updateUI(message);
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "请求失败!");
}
}
public void onDestroy() {
Log.i(TAG, " ParseTermService destroy");
iLoadFinish.loadFinsh();
super.onDestroy();
}
/**
* 数字判断
*
* @param str
* @return
*/
public boolean isNumeric(String str) {
if (str.matches("\\d*")) {
return true;
} else {
return false;
}
}
/**
* 标点符号判断
*
* @param str
* @return
*/
public boolean isPunc(String str) {
Pattern patPunc = Pattern.compile("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]$");
Matcher matcher = patPunc.matcher(str);
if (matcher.find()) {
return true;
} else {
return false;
}
}
/**
* 保存到数据库
*/
private void dbSave(String word) {
//空判断
if (TextUtils.isEmpty(word)) {
return;
}
//数字判断
if (isNumeric(word)) {
return;
}
//标点判断
if (isPunc(word)) {
return;
}
//保存到数据库
dao.checkAndCreate(word);
}
}
ParseWordsService类
package com.mwf.analyze.services;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.mwf.analyze.Constant;
import com.mwf.analyze.activity.AnalyzePoemActivity;
import com.mwf.analyze.bean.CloudResultPlainParse;
import com.mwf.analyze.bean.FamousInfoReq;
import com.mwf.analyze.dao.AnalyzeDao;
import com.mwf.analyze.model.FamousInfoModel;
import com.mwf.analyze.utils.FileUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import retrofit2.Call;
import retrofit2.Response;
/**
* 处理词的服务类
*/
public class ParseWordsService extends IntentService {
public final String TAG = this.getClass().getName();
/**
* 结束加载回调
*/
private static ILoadWorsdFinish iLoadFinish;
/**
* 数据库访问
*/
private AnalyzeDao dao;
public ParseWordsService() {
super("com.mwf.analyze.services.ParseWordsService");
}
public static void setLoadFinish(ILoadWorsdFinish iLoadWordsFinishInterface) {
iLoadFinish = iLoadWordsFinishInterface;
}
/**
* 结束加载回调接口
*/
public interface ILoadWorsdFinish {
void LoadWorsdFinish();
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.i(TAG, "onHandleIntent");
dao = new AnalyzeDao(ParseWordsService.this);
//获取文件地址
String filePath = intent.getStringExtra("filePath");
if (!TextUtils.isEmpty(filePath)) {
String string = FileUtils.readTxtFile(filePath);
//转单个字符
char[] chars = new char[string.length()];
chars = string.toCharArray();
for (int i = 0; i < string.length(); i++) {
String text = String.valueOf(chars[i]);
// Log.i(TAG, text);
dbSave(text);
}
}
}
public void onDestroy() {
Log.i(TAG, " ParseTermService destroy");
iLoadFinish.LoadWorsdFinish();
super.onDestroy();
}
/**
* 数字判断
*
* @param str
* @return
*/
public boolean isNumeric(String str) {
if (str.matches("\\d*")) {
return true;
} else {
return false;
}
}
/**
* 标点符号判断
*
* @param str
* @return
*/
public boolean isPunc(String str) {
Pattern patPunc = Pattern.compile("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]$");
Matcher matcher = patPunc.matcher(str);
if (matcher.find()) {
return true;
} else {
return false;
}
}
/**
* 保存到数据库
*/
private void dbSave(String word) {
//空判断
if (TextUtils.isEmpty(word)) {
return;
}
//数字判断
if (isNumeric(word)) {
return;
}
//标点判断
if (isPunc(word)) {
return;
}
//保存到数据库
dao.checkAndCreate(word);
}
}
数据库工具类
package com.mwf.analyze.utils;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.mwf.analyze.bean.AnalyzeBean;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* 数据库工具类
*/
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
/**
* 数据库名称
*/
private static final String TABLE_NAME = "android_analyze.db";
private Map<String, Dao> daos = new HashMap<String, Dao>();
private DatabaseHelper(Context context)
{
super(context, TABLE_NAME, null, 2);
}
@Override
public void onCreate(SQLiteDatabase database,
ConnectionSource connectionSource)
{
try
{
TableUtils.createTable(connectionSource, AnalyzeBean.class);
} catch (SQLException e)
{
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase database,
ConnectionSource connectionSource, int oldVersion, int newVersion)
{
try
{
TableUtils.dropTable(connectionSource, AnalyzeBean.class, true);
onCreate(database, connectionSource);
} catch (SQLException e)
{
e.printStackTrace();
}
}
private static DatabaseHelper instance;
/**
* 单例获取该Helper
*/
public static synchronized DatabaseHelper getHelper(Context context)
{
context = context.getApplicationContext();
if (instance == null)
{
synchronized (DatabaseHelper.class)
{
if (instance == null)
instance = new DatabaseHelper(context);
}
}
return instance;
}
public synchronized Dao getDao(Class clazz) throws SQLException
{
Dao dao = null;
String className = clazz.getSimpleName();
if (daos.containsKey(className))
{
dao = daos.get(className);
}
if (dao == null)
{
dao = super.getDao(clazz);
daos.put(className, dao);
}
return dao;
}
/**
* 释放资源
*/
@Override
public void close()
{
super.close();
for (String key : daos.keySet())
{
Dao dao = daos.get(key);
dao = null;
}
}
}
数据库操作类,这里做了一个判断,如果有存在的词或者字让它数量加一,如果没有存在则新建一个
package com.mwf.analyze.dao;
import android.content.Context;
import com.j256.ormlite.dao.Dao;
import com.mwf.analyze.bean.AnalyzeBean;
import com.mwf.analyze.utils.DatabaseHelper;
import java.sql.SQLException;
import java.util.List;
/**
* 数据库操作类
*/
public class AnalyzeDao {
public final String TAG = this.getClass().getName();
private Context context;
private Dao<AnalyzeBean, Integer> daoOpe;
private DatabaseHelper helper;
public AnalyzeDao(Context context) {
this.context = context;
try {
helper = DatabaseHelper.getHelper(context);
daoOpe = helper.getDao(AnalyzeBean.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 增加
*/
private void add(AnalyzeBean user) {
try {
daoOpe.create(user);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 检查已经存在字段
* 已经存在数量加一
* 没有存在新增一个
*/
public void checkAndCreate(String word) {
AnalyzeBean bean;
try {
bean = daoOpe.queryBuilder().orderBy("id", false).where().eq("name", word).queryForFirst();
if (bean == null) {
bean = new AnalyzeBean();
bean.setAmount(1);
bean.setName(word);
//没有同样的直接新建一个
daoOpe.create(bean);
} else {
//有同样的数量加1并更新
int amount = bean.getAmount() + 1;
bean.setAmount(amount);
daoOpe.update(bean);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 查询所有数据
*/
public List<AnalyzeBean> queryAll() {
List<AnalyzeBean> list = null;
try {
list = daoOpe.queryBuilder().orderBy("amount", false).query();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
/**
* 根据指定数量查询所有数据
* @param limit 限制数量
* @param orderBy false降序 true升序
* @return
*/
public List<AnalyzeBean> queryAll(int limit,boolean orderBy) {
List<AnalyzeBean> list = null;
try {
list = daoOpe.queryBuilder().orderBy("amount", orderBy).limit(limit).query();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
/**
* 删除所有数据
*/
public void deletedAll() {
try {
daoOpe.delete(queryAll());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
数据库实体类:
package com.mwf.analyze.bean;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
* 数据库实体类
*/
@DatabaseTable(tableName = "tb_analyze")
public class AnalyzeBean {
public AnalyzeBean() {
}
@DatabaseField(generatedId = true)
private int id;
/**
* 名称
*/
@DatabaseField(columnName = "name")
private String name;
/**
* 总数
*/
@DatabaseField(columnName = "amount")
private int amount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
文件操作类,默认保存到SDCard根目录
package com.mwf.analyze.utils;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import static android.R.attr.phoneNumber;
import static android.content.ContentValues.TAG;
/**
* 文件管理工具
*/
public class FileUtils {
/**
* 功能:Java读取txt文件的内容
* 步骤:1:先获得文件句柄
* 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取
* 3:读取到输入流后,需要读取生成字节流
* 4:一行一行的输出。readline()。
* 备注:需要考虑的是异常情况
* @param filePath
*/
public static String readTxtFile(String filePath){
try {
String encoding="GBK";
// String encoding="UTF-8";
File file=new File(filePath);
if(file.isFile() && file.exists()){ //判断文件是否存在
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
String result="";
while((lineTxt = bufferedReader.readLine()) != null){
System.out.println(lineTxt);
result+=lineTxt;
}
read.close();
return result;
}else{
System.out.println("找不到指定的文件");
return null;
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
return null;
}
}
public static boolean saveTxt(String content,Context context,String path){
//sd卡检测
String sdStatus = Environment.getExternalStorageState();
if(!sdStatus.equals(Environment.MEDIA_MOUNTED)){
Toast.makeText(context, "SD 卡不可用", Toast.LENGTH_SHORT).show();
return false;
}
//检测文件夹是否存在
File file = new File(path);
file.exists();
file.mkdirs();
String p = path+File.separator+"myexport.txt";
FileOutputStream outputStream = null;
try {
//创建文件,并写入内容
outputStream = new FileOutputStream(new File(p));
String msg = new String(content);
outputStream.write(msg.getBytes("GBK"));
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(outputStream!=null){
try {
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(context, "导出成功", Toast.LENGTH_SHORT).show();
}
}
return true;
}
}
AndroidManifest类
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mwf.analyze">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.WelcomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".activity.MainActivity">
</activity>
<activity android:name=".activity.AnalyzePoemActivity">
</activity>
<service android:name=".services.ParseTermService"/>
<service android:name=".services.ParseWordsService"/>
</application>
</manifest>
项目地址: 玩转数据统计