본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-05-12안드로이드 스튜디오(파일 입출력2 sd)

반응형

이름들이 비슷해서 안드로이드 하다 보면 분명히 혼동이 올 거 같아서 다시 한번 자바에서 입출력 배운 것들 정리하고 가는 시간을 갖자 

(해당 메소드들은 전에 공부한 거 찾아보면 있다!) 

 

바이트 단위 스트림 

InputStream  a = new FileInputStream("파일경로" );

OutputStream a = new FileOutputStream("파일경로");

 

버퍼(모와주는 바구니) 서폿 역할

BufferedInputSream b = new BufferedInputSream("a");

BufferedOutputSream b = new BufferedOutputSream("a");

 

필터 (분해 조합) 서폿역활 

DataInputStream c = new DataInputStream("c"); 

DataOutputStream c = new DataOutputStream("c"); 

 

사용 순서

InputStream  a = new FileInputStream("파일경로" );

BufferedInputSream b = new BufferedInputSream("a");

DataInputStream c = new DataInputStream("b"); 

 

또는 바로 사용할 땐

DataInputStream c = new DataInputStream(new BufferedInputSream(InputStream  a =

new FileInputStream("파일경로" )));  

 

문자 단위 스트림 

Reader a = new FileReader("파일 경로");

Writer a = new FileWriter("파일 경로");

 

버퍼(모와주는 바구니) 서폿 역할

BufferedReader b = new BufferedReader(a);

BufferedWriter b = new BufferedWriter(a);

 

안드로이드 스튜디오에서 사용 스트림 

fileOutputStream a = OpenFileOutput(경로 , 권한)   //fileOutputStream 이거 반환 하기에 이렇게 작성 

fileInputStream a = OpenFileInput(경로 , 권한)       // fileOutputStream 이거 반환 하기에 이렇게 작성 


자 본론으로 돌아와서 어제는 기기 내부에 파일을 입출력하는 것을 배웠었다.

오늘은 기기 내부가 아닌 sd 카드에 입출력을 받아보는 것을 배울 것인데 앞서 어제 배운 내용을 가지고 하나 더 실습을 해보도록 하겠다 ~ 

public class MainActivity extends AppCompatActivity {

    EditText editText;
    DatePicker datePicker;
    String filename;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("간단일기장");

        datePicker=findViewById(R.id.datePicker1);
        editText=findViewById(R.id.edtDiary);
        button= findViewById(R.id.btnWrite);

        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_WEEK);
        //처음 시작과 동시에 한번 실행을 할것이고 
        filename = Integer.toString(year) + "_"+Integer.toString(month + 1) + "_"+Integer.toString(day)+".txt";
        String str = readDiary(filename);
        editText.setText(str);
        
        //데이터 피커를 변경했을시에 호출 메소드이다. 
        datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                filename = Integer.toString(year) + "_"+Integer.toString(monthOfYear + 1) + "_"+Integer.toString(dayOfMonth)+".txt";
                String str = readDiary(filename);
                editText.setText(str);
            }
        });
        //1.(저장)저장하기 버튼을 눌럿을때 파일로 저장을 해주기위함
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    //1.(저장)
                    FileOutputStream outputStream = openFileOutput(filename, MODE_PRIVATE);
                    //에디트 텍스트에서 입력한 데이터 가져옴
                    String str = editText.getText().toString();
                    //str에 담긴 정보를 바이트로 쪼개서 저장해줌
                    outputStream.write(str.getBytes());
                    //스트림 닫아주기
                    outputStream.close();
                    Toast.makeText(getApplicationContext(),filename+"이 가 저장됨",Toast.LENGTH_LONG).show();
                 } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }
    //2.(읽기)  읽어오는 메소드 트라이 캣치문으로 조절해줌
    public String readDiary(String filename)  {
        String diarystr = null;
        FileInputStream inFs;
        try{
            //.2(읽기)파일에서 읽어오기 위에서 메소드 호출하며 파일 이름 던져준거로 찾기
            inFs= openFileInput(filename);
            //읽어줄 데이터를 담을 바이트 생성
            byte[] txt = new byte[500];
            //위에 만든 바이트배열으로 읽어 오기
            inFs.read(txt);
            //스트림 닫기
            inFs.close();
            //호출한곳으로 던져줄 데이터 다시 스트링 형으로 만들어준다*.trim은 공백을 없애준다
            diarystr = (new String(txt)).trim();
            //버튼에 텍스트 수정해주기 
            button.setText("수정하기");
            //만약에 해당 파일이 없다면 예외발생할것이고 예외 발생하면 동시에 버튼과 에디트 택스트변경 해줌 
        }catch (IOException e){
            button.setText("새로저장");
            editText.setHint("일기 없음");
        }


        return diarystr;
    }

}

이렇게 보면 12일에 메모를 작성하고 13일로 변경했을 때 일기 없음으로 출력되다가 다시 12일 돌아오면 전에 입력한 것이 나오면서 출력하기로 변경 된 것을 볼 수 있다.

 

SD카드로 접근하기 

들어가기 앞서서 30 버전으로 들어오면서 처리 방법이 달라졌다고 하니 참고 하자! 

우리는 지금 안드로이드 스튜디오에서 제공하는 Device를 사용하다 보니 경로가 위에 노란 부분이지만 다른 곳에서 저렇게 쓸 경우 오류가 난다 그럴 때는 Environment.getExternalStorageDirectory().getAbsolutePath() 메소드를 사용해주면 된다. 외부 저장소의 절대 경로를 자동으로 가져와 주는 메서드이다. 

 

코드를 보면서 이해 

public class MainActivity extends AppCompatActivity {

    EditText edtContents;
    String path;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //유저 퍼미션
        ActivityCompat.requestPermissions(this, new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
        }, 0);

        Button btnRead = findViewById(R.id.btnRead);
        Button btnMkDir = findViewById(R.id.btnMkdir);
        Button btnRmdir = findViewById(R.id.btnRmdir);

        edtContents = findViewById(R.id.edtSD);
        // 경로 찾아주는것 미리 지정
        path = Environment.getExternalStorageDirectory().getAbsolutePath();


        btnRead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {

                    //File.separator 운영체제에 따라 다른 파일구분자를 해결해주는것
                    String filePath = path + File.separator+"sdcard_test.txt";
                    //읽어올 준비 해주기!
                    FileInputStream inputStream = new FileInputStream(filePath);
                    //inputStream.available()  inputStream이 현재 읽어 들일수 있는 바이트
                    //고로 자동으로 설정 해준다.
                    byte[] contents = new byte[inputStream.available()];
                    inputStream.read(contents);
                    //에디트 텍스트에 적어주기
                    edtContents.setText(new String(contents));
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });
        //디렉토리 생성해주기
        btnMkDir.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File myDir = new File(path+File.separator+"myDir");
                myDir.mkdir();

            }
        });
        //디렉토리 제거해주기
        btnRmdir.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File myDir = new File(path+File.separator+"myDir");
                myDir.delete();
            }
        });
    }
}

퍼미션 주기  

SDK 버전 낮춰주기

그리고 이렇게 해주기 전에 읽어 들일 텍스트 파일을 먼저 넣어 주어야 한다.

이렇게 만들어진 택스트 파일을 sd카드에 넣어주었다.

그러고 나서 실행해보면 작동이 되는 것을 볼 수 있다. 여기서 관전 포인트 지금은 없는 디렉토리가 디렉토리 생성 버튼을 누르면 생성될 것이고 삭제까지 될 것이다. 

이렇게 아까 보았던 메시지가 잘 출력되는 것을 볼 수 있고 

처음 디렉터리 생성을 눌럿을경우에 디렉토리 생성되고 삭제 버튼을 눌러서 삭제까지 된 것을 확인할 수 있다. 

이렇게 sd 카드에 접근하는 것도 해보았는데 

 

배운 것을 기반으로 퀴즈가 있다고 하는데.... 오늘 공부했으니.... 퀴즈는 풀겠지... ㅠ ㅠ 

오늘도 열공했다옳!!!!!!!!!!!!!!!!! 

반응형