IT

자산에서 파일을 읽습니다

lottoking 2020. 5. 29. 08:12
반응형

자산에서 파일을 읽습니다


public class Utils {
    public static List<Message> getMessages() {
        //File file = new File("file:///android_asset/helloworld.txt");
        AssetManager assetManager = getAssets();
        InputStream ims = assetManager.open("helloworld.txt");    
     }
}

이 코드를 사용하여 자산에서 파일을 읽으려고합니다. 나는 이것을하기 위해 두 가지 방법을 시도했다. 첫째, 사용시 File수신 방법을 사용할 FileNotFoundExceptionAssetManager getAssets()인식되지 않습니다. 여기에 해결책이 있습니까?


다음은 버퍼링 읽기 확장 / 수정 활동에 필요한 작업을 수행하는 것입니다.

BufferedReader reader = null;
try {
    reader = new BufferedReader(
        new InputStreamReader(getAssets().open("filename.txt")));

    // do reading, usually loop until end of file reading  
    String mLine;
    while ((mLine = reader.readLine()) != null) {
       //process line
       ...
    }
} catch (IOException e) {
    //log the exception
} finally {
    if (reader != null) {
         try {
             reader.close();
         } catch (IOException e) {
             //log the exception
         }
    }
}

편집 : 귀하의 질문이 활동 이외의 방법으로 수행되는 경우 내 대답은 쓸모가 없습니다. 귀하의 질문이 단순히 자산에서 파일을 읽는 방법이라면 대답은 위의 것입니다.

업데이트 :

형식을 지정하는 파일을 열려면 간단히 다음과 같이 InputStreamReader 호출에 형식을 추가하십시오.

BufferedReader reader = null;
try {
    reader = new BufferedReader(
        new InputStreamReader(getAssets().open("filename.txt"), "UTF-8")); 

    // do reading, usually loop until end of file reading 
    String mLine;
    while ((mLine = reader.readLine()) != null) {
       //process line
       ...
    }
} catch (IOException e) {
    //log the exception
} finally {
    if (reader != null) {
         try {
             reader.close();
         } catch (IOException e) {
             //log the exception
         }
    }
}

편집하다

@Stan이 의견에서 말했듯이, 내가주는 코드는 줄을 요약하지 않습니다. mLine모든 패스가 교체됩니다. 내가 쓴 이유 //process line입니다. 파일에는 일종의 데이터 (예 : 연락처 목록)가 포함되어 있으며 각 줄은 별도로 처리해야한다고 가정합니다.

어떤 종류의 처리없이 파일을 단순히로드하려는 경우 mLine각 패스를 사용 StringBuilder()하고 추가 때 각 패스에서 합계 해야합니다.

다른 편집

@Vincent의 의견에 따르면 finally블록을 추가했습니다 .

또한 Java 7 이상 에서는 최신 Java try-with-resourcesAutoCloseableCloseable기능 을 사용하는 데 사용할 수 있습니다 .

문맥

의견에서 @LunarWatcher getAssets()classin context입니다. 따라서 외부에서 호출하는 경우이를 activity참조하고 컨텍스트 인스턴스를 활동에 전달해야합니다.

ContextInstance.getAssets();

이것은 @Maneesh의 답변에 설명되어 있습니다. 그래서 이것이 당신에게 도움이된다면 그의 대답을지지했습니다. 왜냐하면 그것은 그것을 지적한 사람이기 때문입니다.


getAssets()

다른 클래스의 Activity 에서만 작동 Context합니다.

Utils 클래스 생성자 에게 매개 변수로 응용 프로그램 (추악한 방법) 또는 컨텍스트 컨텍스트 참조를 전달하십시오. 이를 사용하면 Utils 클래스에서 getAsset ()을 사용하십시오.


안하는 것보다 늦게하는 것이 낫다.

상황에 따라 파일을 한 줄씩 읽는 데 어려움이있었습니다. 아래 방법은 지금까지 내가 찾은 최고이며 권장합니다.

용법: String yourData = LoadData("YourDataFile.txt");

어디 YourDataFile.txt가 에 거주하는 가정 자산 /

 public String LoadData(String inFile) {
        String tContents = "";

    try {
        InputStream stream = getAssets().open(inFile);

        int size = stream.available();
        byte[] buffer = new byte[size];
        stream.read(buffer);
        stream.close();
        tContents = new String(buffer);
    } catch (IOException e) {
        // Handle exceptions here
    }

    return tContents;

 }

public String ReadFromfile(String fileName, Context context) {
    StringBuilder returnString = new StringBuilder();
    InputStream fIn = null;
    InputStreamReader isr = null;
    BufferedReader input = null;
    try {
        fIn = context.getResources().getAssets()
                .open(fileName, Context.MODE_WORLD_READABLE);
        isr = new InputStreamReader(fIn);
        input = new BufferedReader(isr);
        String line = "";
        while ((line = input.readLine()) != null) {
            returnString.append(line);
        }
    } catch (Exception e) {
        e.getMessage();
    } finally {
        try {
            if (isr != null)
                isr.close();
            if (fIn != null)
                fIn.close();
            if (input != null)
                input.close();
        } catch (Exception e2) {
            e2.getMessage();
        }
    }
    return returnString.toString();
}

AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
    inputStream = assetManager.open("helloworld.txt");
}
catch (IOException e){
    Log.e("message: ",e.getMessage());
}

getAssets() Activity 클래스 내에서 호출 할 때 메소드가 작동합니다.

비 활동 클래스에서이 메소드를 호출하는 경우 Activity 클래스에서 전달 된 컨텍스트에서이 메소드를 호출해야합니다. 아래는 메소드에 액세스 할 수있는 줄입니다.

ContextInstance.getAssets();

ContextInstance Activity 클래스의 이것으로 전달 될 수 있습니다.


파일 읽기 및 쓰기는 항상 장황하고 오류가 발생하기 쉽습니다. 이 답변을 피하고 대신 Okio를 사용하십시오.

public void readLines(File file) throws IOException {
  try (BufferedSource source = Okio.buffer(Okio.source(file))) {
    for (String line; (line = source.readUtf8Line()) != null; ) {
      if (line.contains("square")) {
        System.out.println(line);
      }
    }
  }
}

자산에서 파일을 읽는 방법은 다음과 같습니다.

/**
 * Reads the text of an asset. Should not be run on the UI thread.
 * 
 * @param mgr
 *            The {@link AssetManager} obtained via {@link Context#getAssets()}
 * @param path
 *            The path to the asset.
 * @return The plain text of the asset
 */
public static String readAsset(AssetManager mgr, String path) {
    String contents = "";
    InputStream is = null;
    BufferedReader reader = null;
    try {
        is = mgr.open(path);
        reader = new BufferedReader(new InputStreamReader(is));
        contents = reader.readLine();
        String line = null;
        while ((line = reader.readLine()) != null) {
            contents += '\n' + line;
        }
    } catch (final Exception e) {
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException ignored) {
            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ignored) {
            }
        }
    }
    return contents;
}


MainActivity.java에서

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tvView = (TextView) findViewById(R.id.tvView);

        AssetsReader assetsReader = new AssetsReader(this);
        if(assetsReader.getTxtFile(your_file_title)) != null)
        {
            tvView.setText(assetsReader.getTxtFile(your_file_title)));
        }
    }

또한 모든 작업을 수행하는 별도의 클래스를 만들 수 있습니다

public class AssetsReader implements Readable{

    private static final String TAG = "AssetsReader";


    private AssetManager mAssetManager;
    private Activity mActivity;

    public AssetsReader(Activity activity) {
        this.mActivity = activity;
        mAssetManager = mActivity.getAssets();
    }

    @Override
    public String getTxtFile(String fileName)
    {
        BufferedReader reader = null;
        InputStream inputStream = null;
        StringBuilder builder = new StringBuilder();

        try{
            inputStream = mAssetManager.open(fileName);
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;

            while((line = reader.readLine()) != null)
            {
                Log.i(TAG, line);
                builder.append(line);
                builder.append("\n");
            }
        } catch (IOException ioe){
            ioe.printStackTrace();
        } finally {

            if(inputStream != null)
            {
                try {
                    inputStream.close();
                } catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }

            if(reader != null)
            {
                try {
                    reader.close();
                } catch (IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
        }
        Log.i(TAG, "builder.toString(): " + builder.toString());
        return builder.toString();
    }
}

내 의견으로는 인터페이스를 만드는 것이 낫지 만 필수는 아닙니다.

public interface Readable {
    /**
     * Reads txt file from assets
     * @param fileName
     * @return string
     */
    String getTxtFile(String fileName);
}

파일에서 내용을로드 할 수 있습니다. 파일이 자산 폴더에 있다고 가정하십시오.

public static InputStream loadInputStreamFromAssetFile(Context context, String fileName){
    AssetManager am = context.getAssets();
    try {
        InputStream is = am.open(fileName);
        return is;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static String loadContentFromFile(Context context, String path){
    String content = null;
    try {
        InputStream is = loadInputStreamFromAssetFile(context, path);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        content = new String(buffer, "UTF-8");
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    }
    return content;
}

이제 다음과 같이 함수를 호출하여 컨텐츠를 얻을 수 있습니다.

String json= FileUtil.loadContentFromFile(context, "data.json");

data.json을 고려하면 Application \ app \ src \ main \ assets \ data.json에 저장됩니다.


kotlin을위한 한 줄 솔루션 :

fun readFileText(fileName: String): String {
    return assets.open(fileName).bufferedReader().use { it.readText() }
}

Activity 이외의 다른 클래스를 사용하는 경우 다음과 같이 할 수 있습니다.

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( YourApplication.getInstance().getAssets().open("text.txt"), "UTF-8"));

Kotlin을 사용하면 다음을 수행하여 Android의 자산에서 파일을 읽을 수 있습니다.

try {
    val inputStream:InputStream = assets.open("helloworld.txt")
    val inputString = inputStream.bufferedReader().use{it.readText()}
    Log.d(TAG,inputString)
} catch (e:Exception){
    Log.d(TAG, e.toString())
}

cityfile.txt

   public void getCityStateFromLocal() {
        AssetManager am = getAssets();
        InputStream inputStream = null;
        try {
            inputStream = am.open("city_state.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
        ObjectMapper mapper = new ObjectMapper();
        Map<String, String[]> map = new HashMap<String, String[]>();
        try {
            map = mapper.readValue(getStringFromInputStream(inputStream), new TypeReference<Map<String, String[]>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        ConstantValues.arrayListStateName.clear();
        ConstantValues.arrayListCityByState.clear();
        if (map.size() > 0)
        {
            for (Map.Entry<String, String[]> e : map.entrySet()) {
                CityByState cityByState = new CityByState();
                String key = e.getKey();
                String[] value = e.getValue();
                ArrayList<String> s = new ArrayList<String>(Arrays.asList(value));
                ConstantValues.arrayListStateName.add(key);
                s.add(0,"Select City");
                cityByState.addValue(s);
                ConstantValues.arrayListCityByState.add(cityByState);
            }
        }
        ConstantValues.arrayListStateName.add(0,"Select States");
    }
 // Convert InputStream to String
    public String getStringFromInputStream(InputStream is) {
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb + "";

    }

여기에 얻을 수있는 방법이다 InputStream에있는 파일에 대한 assets없이 폴더를 Context, Activity, Fragment또는 Application. 그로부터 데이터를 얻는 방법은 당신에게 InputStream달려 있습니다. 여기에 다른 답변에 대한 제안이 많이 있습니다.

코 틀린

val is = ClassLoader::class.java.classLoader.getResourceAsStream("assets/your_file.ext")

자바

InputStream is = ClassLoader.class.getClassLoader().getResourceAsStream("assets/your_file.ext");

커스텀 ClassLoader이 진행 중이면 모든 베팅이 해제됩니다 .


@HpTerm 답변 Kotlin 버전 :

private fun getDataFromAssets(): String? {

    var bufferedReader: BufferedReader? = null
    var data: String? = null

    try {
        bufferedReader = BufferedReader(
            InputStreamReader(
                activity?.assets?.open("Your_FILE.html"),     
                "UTF-8"
            )
        )                  //use assets? directly if in activity

       var mLine:String = bufferedReader?.readLine()
        while (mLine != null) {
            data+= mLine
            mLine=bufferedReader.readLine()
        }

    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        try {
            bufferedReader?.close()
        } catch (e: Exception) {
           e.printStackTrace()
        }
    }
    return data
}

참고 URL : https://stackoverflow.com/questions/9544737/read-file-from-assets

반응형