폴더에 있는 파일을 읽어와서 보여주는 간단한 프로그램 입니다.

웹에서 파일을 다운로드 해줘야 하는데 Batch로 파일이 계속 생성되고 있어서 목록을 수작업으로 하려니 귀찮아서 자동으로 파일 목록을 생성하도록 하기위한 기초적인 부분입니다.

 

Windows에서는 C:\\folderName으로 하면 되고 UNIX/LINUX/usr/copycoding 이런식으로 폴더명을 변경하면 됩니다.

 

현재 D:\\temp라는 folder에는 파일과 하부 폴더가 아래 그림과 같이 존재 합니다.

 

 

폴더와 파일을 불러오는 프로그램 소스는 매우 간단 합니다.

 

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
 
public class DirList {
 
        public static void main(String[] args) {
               // TODO Auto-generated method stub
                 String dirName = "D:\\temp";
              File dir = new File(dirName);
      
              File[] files2 = dir.listFiles();
              for(File f: files2){
                    String str = f.getName();
              
                    if(f.isDirectory()){
                        System.out.print(str+"\t");
                        System.out.print("DIR\n");
                    }else{
                        long ltime = f.lastModified();
                        String pattern = "yyyy-MM-dd hh:mm aa";
                               SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
                              
                               Date lastModifiedDate = new Date( ltime );
                               String frmDate = simpleDateFormat.format(lastModifiedDate);
                              
                        System.out.print(str+"/\t"+ frmDate + "/\t" +  f.length()+"bytes\n");
                      
                    }
                  
                }
 
        }
 
}

 

폴더이면 폴더명만 출력하고 파일이면 파일명과 작성일자 그리고 사이즈를 출력 합니다.

이걸 실행하면 아래와 같은 결과가 출력 됩니다.

 

backup_0808.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0809.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0810.txt/      2022-05-16 04:59 오후/ 242bytes
backup_0811.txt/      2022-05-16 04:59 오후/ 242bytes
backup_배치.bat/       2022-05-16 04:59 오후/ 242bytes
연습1   DIR
연습2   DIR

 

 

연습1, 연습2는 폴더인데 이것의 내부에 있는 파일명도 필요하다면 파일 목록 출력하는 부분을 method로 만들어서 호출하면 될것 같고.

Vo하나 만들어서 List<Vo>에 담아 화면에 던지면 끝이네요.

 

 

댓글에 너무 설명이 부족해서 몇자 추가합니다.

 

외부에서 호출할 URI와 Method를 생성 합니다.

@GetMapping("/fine_info")
public String fileInfo(Model model) {

}

Vo는 File과 관련된 어떤 내용을 보여줄지에 따라서 생성합니다.

class FileInfo {
      private String fileName;
      private String fileTime;

       getter/setter 추가...

}

그리고 method내에서

List<FileInfo>를 선언하고 FileInfo의 setter에 값을 하나씩 추가해 주고 화면으로 값을 넘겨 줍니다.

 


앱 개발을 하면서 간단한 키값 정도의 데이터는 데이터베이스를 사용하기 보다는 파일에 저장해서 사용하는게 편한 경우가 있어 파일 쓰기 및 읽기 테스트를 해 봅니다만들어 보는 최종 모습은 좀 엉성하지만 button 하나와 textview 하나 입니다.


android file write read


1. 프로젝트 생성

 

먼저 간단하게 프로젝트를 하나 만들고


android file write read


Empty Activity를 선택 합니다.


android file write read


Name은 적당히 적어주고 package copycoding.tistory.filetest로 하였습니다.



layout은 아이템이 2개밖에 없으니 TextView는 기본으로 생성되는 Hello World를 사용하고 id만 추가해 주었고 버튼은 OnClick을 추가해서 함수를 바로 호출 하도록 했습니다.

 

<TextView

        android:id="@+id/fileContents"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Hello World!"

        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toLeftOf="parent"

        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toTopOf="parent" />

 

    <Button

        android:id="@+id/button"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginStart="76dp"

        android:layout_marginLeft="76dp"

        android:layout_marginTop="108dp"

        android:text="Button"

        app:layout_constraintStart_toStartOf="parent"

        app:layout_constraintTop_toTopOf="parent"

        android:onClick="btnClick"/>

 

프로그램도 일반적인 java로 구현한 파일 읽기 쓰기와 비슷 합니다.

버튼을 클릭 하면 만들어 놓은 writeFile() 함수에 파일명과 데이터를 보내 파일에 쓰기를 하고 readFile()을 이용하여 입력된 내용을 읽어 옵니다그리고 읽어온 내용을 textView에 출력하는 내용 입니다.


public void btnClick(View view) {

try {

writeFile("testFile.txt", "testtttttttt");

            String rFile = readFile("testFile.txt");

            textView.setText(rFile);

        } catch (IOException e) {

            e.printStackTrace();

        }

}

 

writeFile() 함수는 전달받은 내용을 파일에 쓰기를 하고

OutputStreamWriter oStreamWriter = new OutputStreamWriter(openFileOutput(fileName,

                    Context.MODE_PRIVATE));

oStreamWriter.write(msg);

oStreamWriter.close();

 

readFile() 함수는 파일에서 내용을 읽어 옵니다.

InputStream iStream = openFileInput(fileName);

if(iStream != null) {

InputStreamReader iStreamReader = new InputStreamReader(iStream);

    BufferedReader bufferedReader = new BufferedReader(iStreamReader);

    String temp = "";

    StringBuffer sBuffer = new StringBuffer();

    while((temp = bufferedReader.readLine()) != null) {

         sBuffer.append(temp);

}

iStream.close();

fileContents = sBuffer.toString();

 

파일 읽기와 쓰기에 사용된 입출력 함수는 위에서 사용한 함수 이외에 FileInputStream, FileOutputStream 등 다른 함수를 이용해도 되고 본인이 알고 있는 함수를 사용하면 됩니다.

 

프로그램을 실행하고 BUTTON을 눌러서 결과를 확인 합니다.


android file write read



2. 생성 파일 확인

 

결과를 확인했으니 생성된 testFile.txt 파일도 확인해 봅니다파일 탐색기를 이용해 확인을 하려고 하면 파일을 제대로 확인 할 수 없습니다안드로이드 스튜디오에서 제공하는 Device File Explorer를 이용하면 쉽게 확인이 가능 합니다.

 

메뉴에서


View > Tool Windows > Device File Explorer


를 선택 하면 


android file write read


Android Studio 우측에 현재 연결된 핸드폰의 내용을 탐색할 수 있습니다.


android file write read


프로젝트와 관련된 파일들은 package 으로 폴더가 /data/data/ 아래 생성 되는데 현재 만든 프로젝트의 패키지가 copycoding.tistory.filetest 이니 좀더 아래에 생성되어 있겠네요. 스크롤을 아래로 내려서


android file write read


폴더가 생성되어 있으니 확장을 하고 msg를 저장한 testFile.txt 파일을 더블클릭해서 열어 봅니다.


android file write read

 

그러면 저장된 파일 내용을 확인할 수 있습니다.

 

 

3. 전체 소스


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">

    <TextView
       
android:id="@+id/fileContents"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="Hello World!"
       
app:layout_constraintBottom_toBottomOf="parent"
       
app:layout_constraintLeft_toLeftOf="parent"
       
app:layout_constraintRight_toRightOf="parent"
       
app:layout_constraintTop_toTopOf="parent" />

    <Button
       
android:id="@+id/button"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_marginStart="76dp"
       
android:layout_marginLeft="76dp"
       
android:layout_marginTop="108dp"
       
android:text="Button"
       
app:layout_constraintStart_toStartOf="parent"
       
app:layout_constraintTop_toTopOf="parent"
       
android:onClick="btnClick"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.java


package copycoding.tistory.filetest;
import
androidx.appcompat.app.AppCompatActivity;
import
android.content.Context;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.TextView;
import
java.io.BufferedReader;
import
java.io.FileNotFoundException;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.InputStreamReader;
import
java.io.OutputStreamWriter;

public class
MainActivity extends AppCompatActivity {
    TextView
textView;
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);
       
textView = (TextView) findViewById(R.id.fileContents);
   
}
   
private void writeFile(String fileName, String msg) {
       
try {
            OutputStreamWriter oStreamWriter =
new OutputStreamWriter(openFileOutput(fileName,
                   
Context.MODE_PRIVATE));
           
oStreamWriter.write(msg);
           
oStreamWriter.close();
       
} catch(FileNotFoundException e) {
            e.printStackTrace()
;
       
} catch (IOException e) {
            e.printStackTrace()
;
       
}
    }

   
private String readFile(String fileName) throws IOException {
        String fileContents =
"";
        try
{
            InputStream iStream = openFileInput(fileName)
;
            if
(iStream != null) {
                InputStreamReader iStreamReader =
new InputStreamReader(iStream);
                
BufferedReader bufferedReader = new BufferedReader(iStreamReader);
               
String temp = "";
               
StringBuffer sBuffer = new StringBuffer();
                while
((temp = bufferedReader.readLine()) != null) {
                    sBuffer.append(temp)
;
               
}
                iStream.close()
;
               
fileContents = sBuffer.toString();
           
}
        }
catch (FileNotFoundException e) {
            e.printStackTrace()
;
       
}
       
return fileContents;
    
}

    public void btnClick(View view) {
       
try {
            writeFile(
"testFile.txt", "testtttttttt");
           
String rFile = readFile("testFile.txt");
           
textView.setText(rFile);
       
} catch (IOException e) {
            e.printStackTrace()
;
       
}
    }
}

 

- copy coding -


작업환경

 eGovFramework Version : 3.8

Eclipse Version : Oxygen.3a Release (4.7.3a)

JDK Version : 1.8

1. 파일 업로드

 

1.1 화면 구성

 

egovframework에서 파일 업로드 기능을 찾아보면 화면 구현 방법은 2가지로 만들 수 있습니다업로드 파일의 최대 개수를 정하고 필요한 만큼만 선택 계속 선택해서 한번에 묶어 보내는 방법과 각각의 파일을 하나씩만 선택 할 수 있도록 file tag를 사용하여 보내는 방법이 있습니다.  첫 번째 방법은 파일의 개수를 정하고 하단이 파일명으로 늘어나는 것을 감안하여 디자인이 되어야 하고, 두 번째 방법은 사용하지도 않을 수 있는 전송할 파일의 수만큼 미리 입력 화면을 고정해야 하는 단점이 있습니다간단한 화면 구성을 살펴 보면 아래와 같습니다.



egovframework upload download


다중 파일 업로드는 파일선택 버튼이 한 개만 존재 하고 이 버튼을 이용하여 파일을 선택하면 하단에 계속해서 파일 리스트가 추가 됩니다잘못 선택된 파일이 있다면 delete 버튼으로 삭제 합니다그리고 파일 선택이 완료 되었으면 저장 버튼을 이용하여 선택된 파일들을 서버로 전달하면 됩니다.

 

단일 파일 업로드 방식은 필요한 개수만큼 파일선택 버튼을 추가하고 저장버튼을 클릭하여 선택된 파일들을 서버로 전달 합니다.

파일을 선택한 경우의 화면은 아래 이미지 처럼 보입니다.


egovframework upload download


다중파일은 이미지 4개를 선택하고 단일파일은 각각 파일을 선택해 보았습니다.

 

1.2  JSP 파일

 

1.2.1 다중 파일 업로드

 

다중 파일 업로드를 구현 하려면 상단에 js 파일을 하나 추가해야 합니다.


<script type="text/javascript" src="<c:url value='/js/egovframework/com/cmm/fms/EgovMultiFile.js'/>" ></script>


파일을 선택하는 부분은 일반 file tag를 사용하는데 <input type="hidden" name="atchPosblFileNumber" id="atchPosblFileNumber" value="5" /> 이런 식으로 최대 파일 개수를 입력 합니다여기서는 5개로 설정 하였습니다.


egovframework upload download


<input type="hidden" name="savePath" value="Globals.fileTest1Path" /> 이건 파일을 저장하기 위한 위치를 설정하는 부분으로 Server 부분 소스 설명에 나와 있습니다.

 

선택한 파일을 리스트로 보여주는 부분은 javascript로 구현이 되어 있습니다.


egovframework upload download


form 에서 최대 파일 개수를 정하지 않았다면 기본값을 설정할 수도 있고 여기서는 3으로 했습니다.

 

 

1.2.2 단일 파일 업로드

 

단일 파일 업로드는 기존에 사용하는 file tag와 동일 하게 테그 하나에 파일 하나를 추가하는 방식으로 JSP 파일을 작성 합니다.


egovframework upload download


1.3 Server 작업

 

1.3.1 설정


파일을 저장할 위치를 설정 합니다.

Globals.properties

 # 파일 업로드 경로(경로 설정은 반드시 절대경로를 사용해야함, 경로 뒤에 / 붙여 주어야함.)

Globals.fileStorePath =C:/egovframework/upload/

Globals.fileTest1Path =C:/egovframework/upload/filepath1/

Globals.fileTest2Path =C:/egovframework/upload/filepath2/


1.3.2 Controller 생성


임의의 controller를 생성하고 화면에서 호출하는 주소를 입력 합니다.


egovframework upload download


다중 또는 단일 파일 업로드로 화면에서 파일을 보내주면 Server에서는 동일한 로직으로 처리하기 때문에 하나의 함수만 작성하면 됩니다


egovframework upload download


파일을 폴더에 저장한 후에는 결과를 2개의 Table에 반영 합니다.


업로드 정보를 저장하고

select * from COMTNFILE;


egovframework upload download


실제 저장된 파일 정보가 저장 됩니다.

select * from COMTNFILEDETAIL;


egovframework upload download


단일 업로드도 동일한 방법으로 저장이 됩니다. 

 

2. 파일 다운로드

 

2.1 jsp 파일

 

파일 업로드 정보를 담고 있는 테이블에서 ATCH_FILE_IDFILE_SNparam으로 넣어주면 다운로드를 할 수 있습니다.


egovframework upload download


/cmm/fms/FileDown.do에서 넘겨준 param을 이용하여 FileVO에 담아 상세 정보를 이용하여 원래 파일 명을 찾아 다운로드를 진행 합니다.



3. 전체 파일 

3.1 jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

 

 

<script type="text/javascript" src="<c:url value='/js/egovframework/com/cmm/fms/EgovMultiFile.js'/>" ></script>

 

 

<title>Insert title here</title>

<link type="text/css" rel="stylesheet" href="<c:url value='/css/egovframework/com/com.css' />">

</head>

<body>

 

<br>

<br>

<br>

 

<h2>다중 파일 업로드</h2>

<form name="frm" method="post" action="<c:url value='/file/fileUpload.do'/>" enctype="multipart/form-data" >

   <input type="hidden" name="atchPosblFileNumber" id="atchPosblFileNumber" value="5" />

   <input type="hidden" name="savePath" value="Globals.fileTest1Path" />

  

   <table width="400px" cellspacing="0" cellpadding="0" border="1" >

           <tr>

            <td ><input name="file_1" id="egovComFileUploader" type="file" />

                <div id="egovComFileList"></div>

            </td>

           </tr>

           <tr>

            <td align="center">

                <input type="submit" value="저장">

            </td>

           </tr>

        </table>      

</form>

 

<!-- 첨부파일 업로드 가능화일 리스트설 Start..--> 

<script type="text/javascript">

var maxFileNum = document.getElementById('atchPosblFileNumber').value;

if(maxFileNum==null || maxFileNum==""){

        maxFileNum = 3;

}

var multi_selector = new MultiSelector( document.getElementById( 'egovComFileList' ), maxFileNum );

multi_selector.addElement( document.getElementById( 'egovComFileUploader' ) );

</script>

<!-- 첨부파일 업로드 가능화일 리스트 End.--> 

<p>

<h2>단일파일 업로드</h2>

<form id="frm2" action="<c:url value='/file/fileUpload.do'/>" method="post" enctype="multipart/form-data">

        <input type="hidden" name="savePath" value="Globals.fileTest2Path" />

        <table width="400px" cellspacing="0" cellpadding="0" border="1" >

               <tr>

                   <td >

                              <input type="file" name="file1" /><br>

                              <input type="file" name="file2" /><br>

                       </td>

               </tr>

               <tr>

                       <td align="center">

                              <input type="submit" value="저장">

                       </td>

           </tr>

        </table>

 </form>

 

<p>

<p>

<p>

 

 

<a href="javascript:fn_egov_downFile('FILE_000000000000201','0')">

 파일 다운로드

</a>

 

<script type="text/javascript">

 

        function fn_egov_downFile(atchFileId, fileSn){

               window.open("<c:url value='/cmm/fms/FileDown.do?atchFileId="+atchFileId+"&fileSn="+fileSn+"'/>");

        }

</script>

  

 

</body>

</html> 


3.2 Controller


package copycoding.com.util.file.web;

 

import java.util.List;

import java.util.Map;

 

import javax.annotation.Resource;

import javax.servlet.http.HttpServletRequest;

 

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.support.SessionStatus;

import org.springframework.web.multipart.MultipartFile;

import org.springframework.web.multipart.MultipartHttpServletRequest;

 

import egovframework.com.cmm.SessionVO;

import egovframework.com.cmm.service.EgovFileMngService;

import egovframework.com.cmm.service.EgovFileMngUtil;

import egovframework.com.cmm.service.FileVO;

 

@Controller

public class FileUploadDownloadController {

           @Resource(name="EgovFileMngService")

           private EgovFileMngService fileMngService;

          

           @Resource(name="EgovFileMngUtil")

           private EgovFileMngUtil fileUtil;

          

           @RequestMapping(value = "/file/fileUpDownloadTest.do")

           public String daumEditor(ModelMap model) throws Exception {

                     return "copycoding/util/FileUpDownload";

           }

          

           @RequestMapping(value = "/file/fileUpload.do")

           public String uploadSingleFile(

                                final MultipartHttpServletRequest multiRequest,

                                HttpServletRequest request,

                                SessionVO sessionVO,

                                ModelMap model,

                                SessionStatus status) throws Exception{

                      

                                String storePath = request.getParameter("savePath");

                                List<FileVO> result = null;

                                String atchFileId = "";

                                final Map<String, MultipartFile> files = multiRequest.getFileMap();

                               

                                if(!files.isEmpty()){

                                          // 파일 객체, 구분 값, 파일 순번, 파일ID, 저장경로

                                          result = fileUtil.parseFileInf(files, "upfile_", 0, "", storePath);

                                          //파일이 생성되고나면 생성된 첨부파일 ID를 리턴한다.

                                          atchFileId = fileMngService.insertFileInfs(result); 

                                }

                      

                                return null;

           }

}


- copy coding -

작업환경

Ubuntu Desktop : version 18.04 LTS

오류 내용: sudo 명령 안됨.

오류 로그 : xxx is not in the sudoers file. This incident will be reported.


ubuntu sudo error


sudo 명령으로 작업을 하려는데 xxx is not in the sudoers file. This incident will be reported. 메시지와 함께 안되는 경우가 있습니다.


Ubuntu, sudo, sudoers


사용을 하려면 /etc/sudoers 파일에 계정을 등록 해줘야 한다고 하는데 root 권한이 있어야 파일을 열고 등록을 할 수 있습니다.  root 권한이 있으면 걱정을 하지 않을 텐데 없으니 참 답답 합니다그런데 본인이 우분투를 설치 하였는데 root 비번을 잊어버린 경우도 있겠죠.  이런 경우에는 설치시 등록한 계정을 이용하면 됩니다.  설치시 등록한 계정으로 로그인을 하고


Ubuntu, sudo, sudoers


root의 비번을 변경하거나 


$ vi /etc/sudoers

파일을 열고 sudo를 사용할 계정을 등록해 줍니다.


Ubuntu, sudo, sudoers


readonly 파일이므로 일반적인 방법으로 저장이 안되기 때문에 w! 명령으로 강제 저장을 합니다이번에는 sudoers 파일에 신규로 등록한 계정으로 sudo를 사용하여 root 비밀번호를 변경해 보겠습니다.


Ubuntu, sudo, sudoers


이제 sudo 명령이 잘 작동 합니다.


- copy coding -

'Setting' 카테고리의 다른 글

Galuxy S8 개발자 옵션 설정  (0) 2019.09.13
ubuntu subversion 설치 eclipse 연동  (0) 2019.07.11
weblogic 12c war 배포  (0) 2019.07.06
Ubuntu vsftpd 설치  (0) 2019.06.30
Ubuntu에 WebLogic Server 12cR2 설치  (0) 2019.06.26

12

+ Recent posts