ファイルの読み書き2
androidにファイルを格納できる場所には、内部ストレージ/外部ストレージがあります.内部リポジトリは、各アプリケーションが提供するリポジトリであり、アプリケーションを削除すると、一緒に削除されます.他のアプリケーションの内部リポジトリにアクセスできません. 外部ストレージは、「パブリックスペース/アプリケーション専用スペース」に分けられます.ちょっと複雑なので、すぐにブログのリンクを見てください。
ACCESS BUFFER:高速・小読み取り(バッファ使用のためか?) ACCESS RANDOM:ブロック単位で読み込みます.前後ナビゲーション ACCESS STREAMING:順番に読み取る.時々前方探索 ACCESS UNKOWN:データへのアクセス方法が分からない場合、 これで、inputStreamを開き、ファイルを読み込み、inputStreamを閉じると、try-catch上で実行されます.
1.ファイルを開いて正常に読み込みますが、Streamを閉じるときにエラーが発生しました
2.ファイルが見つかりません
3.ファイルが見つかりましたが読み込まれませんでした
4.ファイルが見つからないためFileStreamを閉じようとしたが、ファイルを閉じることができなかった
try-catchをそれぞれ処理します.
ソース
注意:FileReaderはInputStreamReaderを継承します.したがって、inputStreamReaderのようにcharに基づいて読み取ります.-bufferReaderの使用
byteで読み込む場合は、FileInputStream-BufferedInputStreamの使用
しかし、今はassetsフォルダのcsvファイルを読みたいだけです。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val am = resources.assets //resource Manager : Provides access to an application's raw asset files
try {
val inputStream = am.open("food_1.csv", AssetManager.ACCESS_BUFFER)
// accessMode를 이용해서 asset 읽기. 내용을 읽기 위해 inputStream 을 리턴
val br = BufferedReader((InputStreamReader(inputStream, Charset.forName("UTF-16"))))
//리턴받은 InputStream(데이터가 전송되는 통로, 1byte 씩만 읽어옴. 한글 처리 x)의 byte를 "UTF-16"방식으로 처리 하겠다. - 한글 처리위해
//괄호 안에서 처리한 inputstreamReader을 char 단위로 buffer을 이용해 읽겠다. - char로 처리 되어 있으므로 BufferdReader로 읽을 수 있음
//(BufferdReader는 char 단위로 처리. BufferedInputStream은 byte 단위로처리)
val list = br.use(BufferedReader::readLines)
//br의 메소드인 readLines로 모든 라인을 읽어오자
//보다시피 한줄 한줄이 리스트 요소로 들어간다.
br.close()
//stream을 닫고 memory leak 이 일어나지 않게 한다.
} catch (e: IOException) {
e.printStackTrace();
}
}
AssetManager.Open()メソッドのaccessMode
1.ファイルを開いて正常に読み込みますが、Streamを閉じるときにエラーが発生しました
2.ファイルが見つかりません
3.ファイルが見つかりましたが読み込まれませんでした
4.ファイルが見つからないためFileStreamを閉じようとしたが、ファイルを閉じることができなかった
try-catchをそれぞれ処理します.
内部/外部リポジトリのファイルの読み込み
ソース
注意:FileReaderはInputStreamReaderを継承します.したがって、inputStreamReaderのようにcharに基づいて読み取ります.-bufferReaderの使用
byteで読み込む場合は、FileInputStream-BufferedInputStreamの使用
ローカル(コンピュータ上)ファイルの読み込み
fun main() {
val br = BufferedReader(//char 단위로 처리.
(InputStreamReader( //inputStream의 byte단위를 char단위로 변환시키는 중개자
FileInputStream("파일이 있는 위치/파일이름.확장자"), //파일을 바이트 단위로 읽어서 inputStream 만듬
Charset.forName("UTF-16")
))
)
//여기서 의문점이 생겼다.
//FileInputStream(바이트 단위의 스트림)을 만들고 InputStreamReader로 byte >char 단위로 스트림을 변환하는
//이중 처리를 하는 이유가 궁금했다.
//FileReader를 이용하면 바로 char 단위로 파일을 읽는 inputStream을 만들 수 있는데 말이다.
//하지만 직접 해보니..
//FileReader는 인코딩을 지정할 수가 없다!(자바 11에서는 가능하다고함. 하지만 나는 1.8을 쓰고있지.)
//그래서 굳이 이중처리를 해야함에도 불구하고,
//FileInputStream로 바이트단위 but, 인코딩 지정가능 스트림 >> InputStreamReader로 char단위 스트림
//이렇게 스트림을 만들어 주는 것 같다!!!
// val br = BufferedReader((FileReader("파일위치/파일이름.확장자")))
val list = br.use(BufferedReader::readLines)
br.close()
list.forEach {
println(it)
}
}
ファイルをローカルに書き込み
private fun writeCSV() {
try {
val map = mapOf("키" to "맵")
val bw =
BufferedWriter(FileWriter(("파일위치/파일이름.확장자"), true))
//fileWriter/BufferedWriter - char 단위로 파일 작성
//append - true : 기존 파일 내용 냅두고 그 다음줄 부터 쓴다. false : 기존 파일 내용 날리고 덮어쓴다(새로쓴다)
//바이트 단위로 파일을 쓰고싶다면 > FileOutputStream . BufferedOutputStream 이용
val iterator = map.iterator()
while (iterator.hasNext()) {
val word = iterator.next()
bw.write("${word.key},${word.value}")
bw.newLine()
bw.flush()
//버퍼의 내용을 파일에 write 한다.
//flush()를 호출하지 않는다면 내용이 버퍼에만 남고 파일에는 쓰이지 않는 상황이 됨.
}
bw.close()
//close 호출은 스트림을 닫는 역할.
// 스트림을 닫으면 그 스트림을 다시 이용하여 파일에 쓰는 것이 불가능
} catch (e: Exception) {
println(e)
}
}
Reference
この問題について(ファイルの読み書き2), 我々は、より多くの情報をここで見つけました https://velog.io/@nagosooo/파일-읽고-쓰기-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol