文件操作
文件操作的實質:
使用流進行文件讀寫
使用方式:
- (1) 使用文件系統
- (2) 使用raw資源文件
- (3) 使用外部存儲設備
使用文件系統進行文件操作
- (1) 獲取輸入(openFileInput) / 輸出流(openFileOutput)
- (2) 進行文件讀/寫
- (3) 關閉輸入/輸出流
使用raw資源文件(raw資源文件夾下文件不會被編譯,保持原數據)
- (1) 獲取輸入
- (2) 進行文件讀
- (3) 關閉輸入
注意:raw裏面的文件只能讀取,不能修改
使用外部存儲設備
- (1) 獲取外部存儲設備的狀態
- (2) 創建輸入輸出流進行讀寫
- (3) 關閉流
ContentProvider:四大組件之一
- URI:https://www. baidu. com/
- 什麼是ContentProvider?
用於提供外部應用訪問本應用數據庫的接口 - 自定義ContentProvider
- 什麼是ContentResoIver?
用於訪問其他應用程序數據的類 - 使用ContentResoIver
- UriMatcher
代碼部分:
part1:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="showFileOperator"
android:text="演示文件操作"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="showContentProvider"
android:text="演示ContentProvider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
raw_demo.txt
activity_file_operator.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FileOperatorActivity">
<EditText
android:id="@+id/et_input"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_marginTop="80dp"
android:ems="10"
android:hint="請輸入"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_out"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="@+id/et_input"
app:layout_constraintStart_toStartOf="@+id/et_input"
app:layout_constraintTop_toBottomOf="@+id/et_input" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:onClick="write"
android:text="寫入"
app:layout_constraintStart_toStartOf="@+id/et_input"
app:layout_constraintTop_toBottomOf="@+id/tv_out" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="read"
android:text="讀取"
app:layout_constraintEnd_toEndOf="@+id/et_input"
app:layout_constraintTop_toTopOf="@+id/button2" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:onClick="readRaw"
android:text="raw文件讀取"
app:layout_constraintStart_toStartOf="@+id/button2"
app:layout_constraintTop_toBottomOf="@+id/button2" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:onClick="writeExternal"
android:text="外部文件寫入"
app:layout_constraintStart_toStartOf="@+id/button4"
app:layout_constraintTop_toBottomOf="@+id/button4" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="readExternal"
android:text="外部文件讀取"
app:layout_constraintEnd_toEndOf="@+id/button3"
app:layout_constraintTop_toTopOf="@+id/button5" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
FileOperatorActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileOperatorActivity extends AppCompatActivity {
private EditText et_input;
private TextView tv_out;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_operator);
et_input = findViewById(R.id.et_input);
tv_out = findViewById(R.id.tv_out);
}
/**
* 演示文件寫入
* @param view
*/
public void write(View view){
String content = et_input.getText().toString();
FileOutputStream out = null;
try {
out = openFileOutput("demo.txt", MODE_PRIVATE);
out.write(content.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 演示文件讀取
* @param view
*/
public void read(View view){
FileInputStream input = null;
try {
input = openFileInput("demo.txt");
int i = input.read();
StringBuffer content = new StringBuffer();
while(i != -1) {
content.append((char) i);
i = input.read();
}
tv_out.setText(content.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 演示raw文件夾下文件讀取
* @param view
*/
public void readRaw(View view){
InputStream inputStream = getResources().openRawResource(R.raw.raw_demo);
try {
int i = inputStream.read();
StringBuffer content = new StringBuffer();
while(i != -1) {
content.append((char)i);
i = inputStream.read();
}
tv_out.setText(content.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 演示外部文件寫入
* @param view
*/
public void writeExternal(View view) {
//獲取外部設備狀態,判斷外部存儲設備是否可用
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
//就是輸入輸出流的使用
//獲取路徑
File file = getExternalFilesDir(null);
File demo = new File(file,"demo.txt");
String content = et_input.getText().toString();
FileOutputStream out = null;
try {
out = new FileOutputStream(demo);
out.write(content.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(this, "寫入完成", Toast.LENGTH_SHORT).show();
}
}
/**
* 演示外部文件讀取
* @param view
*/
public void readExternal(View view) {
//判斷存儲設備是否可用
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
File file = new File(getExternalFilesDir(null),"demo.txt");
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(file);
int i = fileInputStream.read();
StringBuffer content = new StringBuffer();
while(i != -1) {
content.append((char)i);
i = fileInputStream.read();
}
tv_out.setText(content.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
效果圖:
寫入-讀取:
RAW文件讀取:
外部文件寫入-外部文件讀取:
part2:
MainAcitivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 跳轉文件操作演示
* @param view
*/
public void showFileOperator(View view){
Intent intent = new Intent(this, FileOperatorActivity.class);
startActivity(intent);
}
/**
* 演示ContentProvider
* @param view
*/
public void showContentProvider(View view) {
/*
*
* 1.獲取ContentResolver
* 2.執行操作
* */
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.example.day12.demo");
resolver.delete(uri, null, null);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.day12">
<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=".FileOperatorActivity"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
authorities:就是URI
name:指向自定義的ContentProvider
exported:是否允許外部訪問
-->
<provider
android:authorities="com.example.day12.demo"
android:name="com.example.day12.MyContentProvider"
android:exported="true"/>
</application>
</manifest>
MyContentProvider.java
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class MyContentProvider extends ContentProvider {
/*
* https://www.baidu.com/
* https://:協議名稱
* www.baidu.com:地址
* 以上兩部分組成URI
*
* ContentProvider就是通過URI進行訪問的
* content://xxxxxxxxx
* */
/**
* 創建時調用,用於初始化必要的數據
* @return
*/
@Override
public boolean onCreate() {
Log.i("demo", "onCreate方法被調用了");
return false;
}
/**
* 查詢數據庫
* @param uri
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return
*/
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
/**
* 獲取請求類型的
* @param uri
* @return
*/
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
/**
* 向數據庫插入數據
* @param uri
* @param values
* @return
*/
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
/**
* 從數據庫刪除數據
* @param uri
* @param selection
* @param selectionArgs
* @return
*/
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
Log.i("demo", "delete方法被調用了");
return 0;
}
/**
* 更新數據庫數據
* @param uri
* @param values
* @param selection
* @param selectionArgs
* @return
*/
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
}