마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

파일 저장시 이상 현상

0 추천
파일 저장 부분에서 이상한 현상이 발생하여 문의 드립니다.
현재  EditText 에서 값을 입력받아 폴더 생성 후 생성된 폴더내에 파일을 저장하고 있습니다.
그런데 앞서 저장한 파일에 덮어쓰기가 되는 현상이 발생합니다.
예를 들어 아래 소스와 같이
EditText 에 "jang" 이라고 입력
"jang_sg" 이라는 폴더 생성
"jang_sg" 폴더에 데이터를 두번에 걸쳐 파일로 저장 ("jang_sg" 폴더에 M_Sign0.pas, M_Sign1.pas 생성)
생성된 파일의 내용을 확인해 보면
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
이렇게 정상적으로 저장되어 있고요.

다시 EditText 에 "kang" 이라고 입력하여
"kang_sg" 이라는 폴더 생성
"kang_sg" 폴더에 데이터를 한번만 파일로 저장 (M_Sign0.pas 생성) 하여
"kang_sg" 의 M_Sign0.pas 데이터를 확인해 보면  아래와 같이 정상적으로 저장되어 있지만
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20

엉뚱하게 먼저 입력했던 "jang_sg" 폴더내의 M_Sign1.pas 파일의 내용들이
"kang_sg" 의 M_Sign0.pas 내용들로 바뀌어 있습니다.
 
예상하건대 "kang_sg" 의 M_Sign0.pas를 생성하면서 동시에
"jang_sg" 폴더내의 M_Sign1.pas 파일에 덮어쓰기 하는것 같습니다.

AndroidManifest.xml 에 아래와 같이 설정 하였고요.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

도대체 왜 이러는지 원인을 알수 없네요.
혹 경로가 잘못됐나 해서 메세지로 찍어봐도 경로는 이상없습니다.

도움 말씀 부탁드립니다.

public class MainActivity extends Activity implements OnClickListener{

 Button okbtn;
 Button closebtn;
 EditText id;
 
 String ID;
 int count;

 String mSdPath;
 String strSgPw;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
      
        okbtn = (Button)findViewById(R.id.idokbtn);
        closebtn = (Button)findViewById(R.id.closebtn);
        id = (EditText)findViewById(R.id.trueid);

        id.setText("");

        ID = "";
        strSgPw = "_sg";
        count = 0;
       
        okbtn.setOnClickListener(this);
        closebtn.setOnClickListener(this);
      
        //SD카드경로
        String ext = Environment.getExternalStorageState();
        if(ext.equals(Environment.MEDIA_MOUNTED))
        {
         mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        }
        else
        {
         mSdPath = Environment.MEDIA_UNMOUNTED;
        }   
       
        //SD카드에 데이터를 저장할 SignData 폴더를 만든다.
        File dir = new File(mSdPath + "/SignData");
        if(!dir.exists())  //폴더가 없다면 생성
        {     
         dir.mkdir();
        }       
    }
   
    //버튼 클릭 이벤트
    public void onClick(View v) {
  switch(v.getId()){
  case R.id.okbtn: //ok 버튼 클릭
   ID = id.getText().toString();
   if(ID.equals(""))
   {
    MsgBox("ID 입력해 주세요.");
   }
   else
   {
    int num = 5;
    int [] Sign = new int[num*3];
                                                         //버퍼에 데이터 담기.
    if(ID.equals("jang"))  //ID 가 "jang" 이라면
    {
     for(int i=0; i<num; i++ )
     {
      Sign[i*3] = 10;
      Sign[i*3+1] = 10;
      Sign[i*3+2] = 10;
     }
    }
    else
    {
     for(int i=0; i<num; i++ )
     {
      Sign[i*3] = 20;
      Sign[i*3+1] = 20;
      Sign[i*3+2] = 20;
     }
    }
   

    //현재까지 저장된 데이터 개수를 가져온다.
    OnGetSignCount(mSdPath + "/SignData/" + ID + strSgPw + "/TRUE/M_count.pas");

    if(count == 0) //처음 입력이라면 폴더부터 생성
    {
     File dir = new File(mSdPath + "/SignData/" + ID + strSgPw);
           if(!dir.exists())  //ID 폴더 생성
            {     
             dir.mkdir();
           }
           
            dir = new File(mSdPath + "/SignData/" + ID + strSgPw + "/TRUE");
            if(!dir.exists())  // TRUE 폴더 생성
            {     
             dir.mkdir();
            }  
    }  

    //데이터 저장
    SaveSignPasFile(mSdPath + "/SignData/" + ID + strSgPw + "/TRUE/M_Sign"+count+".pas",num,Sign);
    
    Sign = null;
    count++;

    //현재까지 저장된 데이터 개수를 저장한다.
    OnSaveSignCount(mSdPath + "/SignData/" + ID + strSgPw + "/TRUE/M_count.pas");    
   }
   break;

  case R.id.closebtn:  //종료
   finish();
   break;
  }  
 }
  

     //현재까지 저장된 데이터 개수를 가져온다. M_count.pas 파일이 없으면 count=0 을...있으면 그냥 값만 꺼내옴.  
     public void OnGetSignCount(String countFileName)
 {  
       File dir = new File(countFileName);
           if(!dir.exists())
         {     
            count = 0;
        }      
          else
           {
           DataInputStream dis = null;         
        try
        {
           dis = new DataInputStream(new FileInputStream(countFileName));
           count = dis.readInt();
           dis.close();
          }
          catch(FileNotFoundException e)
        {
         ;
        }
        catch(IOException e)
        {
         ;
        }
           }
 }
   
     //서명입력 개수를 저장한다.
     public void OnSaveSignCount(String countFileName )
     {     
      DataOutputStream dos;
  try
  {
   dos= new DataOutputStream(new FileOutputStream(countFileName));
   dos.writeInt(count);
   dos.flush();
   dos.close();
  }
  catch(FileNotFoundException e)
  {
   ;
  }
  catch(SecurityException e)
  {
   ;
  }
  catch(Exception e)
  {
   ;
  }
     }
     
 //데이터 파일로 저장
     public void SaveSignPasFile(String pasFileName,int FSignNum,int [] FSign)
     {
  //데이터를 저장할 경로 출력
  new AlertDialog.Builder(this)
  .setTitle("파일 저장 경로")
  .setMessage(pasFileName)
  .setIcon(R.drawable.ic_launcher)
  .setPositiveButton("확인,null)
  .setCancelable(false)
  .show();

      DataOutputStream dos;
  try
  {
   dos= new DataOutputStream(new FileOutputStream(pasFileName));
   
   dos.writeInt(FSignNum);
   for(int i=0; i<FSignNum*3; i++) dos.writeInt(FSign[i]);  
     
   dos.flush();
   dos.close();
    
  }
  catch(FileNotFoundException e)
  {
   ;
  }
  catch(SecurityException e)
  {
   ;
  }
  catch(Exception e)
  {
   ;
  }
     }
}
soGoodMan (260 포인트) 님이 2016년 9월 6일 질문
soGoodMan님이 2016년 9월 6일 수정
님 코드를 실행해 보면 이상없이 잘 동작하는데요.
먼저 답변 감사드립니다.
작동한다는 의미가 파일 생성이 된다는 말씀이신지?
본문에서도 말씀드렸지만 파일은 정상적으로 생성됩니다.
하지만 관련이 없는 파일의 내용이 바뀐다는게 문제죠.
kang 으로 파일을 생성하고 나면
아무런 관련도 없는  jang_sg 폴더의  M_Sign1.pas 파일의 내용이
kang 의  M_Sign0.pas 내용으로 바뀐다는게 문제입니다.
이상한게 제폰(베가 넘버6) 에서는 이상없고
갤럭시 S5 와 S7 에서 테스트 해보니 저 증상이 발생합니다.
안드로이드 버전을 살펴보니 제폰은 4.4.2 이고요.
S5 와 S7 은 6.0  대 이더군요.
혹 OS 가 버전업 되면서 뭔가 바뀐건지...
도무지 알수가 없는 증상입니다.
또 EditText 에 입력된 값에 따라 발생하는 경우가 있고 아닌 경우가 있습니다.
반드시 "jang"  으로 먼저 파일을 생성하고(2개)
"kang" 으로 생성하고 나면 저 현상이 발생합니다.
값이 비슷해서 인지...
며칠째 이문제 때문에 다른걸 못하고 있네요 ㅜㅜ
파일경로가 다른데 파일을 덮어쓴다는 건 있을 수 없는 일이라고 생각합니다. 천천히 하나 하나씩 디버거를 이용해서 디버깅을 해보시기 바래요. 아주 사소한데서 문제가 있을 수 있습니다.
6.0이라면 런타임에 퍼미션을 체크를 하고 없으면 요청하셔야 할 겁니다. 아래처럼 말이죠.
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
      }

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...