मल्टीपार्ट फाइल को फाइल में कैसे बदलें?


89

क्या कोई मुझे बता सकता है कि मल्टीपार्ट फ़ाइल (org.springframework.web.multipart.MultipartFile) फ़ाइल (java.io.File) में बदलने का सबसे अच्छा तरीका क्या है?

मेरी स्प्रिंग mvc वेब परियोजना में मुझे मल्टीपार्ट फ़ाइल के रूप में अपलोड की गई फ़ाइल मिल रही है। मुझे इसे एक फ़ाइल (io) में परिवर्तित करना है, वहाँ पर मैं इस छवि भंडारण सेवा ( क्लाउडिनरी ) को कॉल कर सकता हूँ । वे केवल टाइप (फ़ाइल) लेते हैं।

मैंने बहुत सी खोजें की हैं लेकिन असफल रहा हूँ। यदि कोई अच्छा मानक तरीका जानता है तो कृपया मुझे बताएं? thnx


5
क्या ऐसा कुछ है जो आपको विधि का उपयोग करने से रोकता है MultipartFile.transferTo()?
फजरको

जवाबों:


192

आप विधि MultipartFileका उपयोग करके सामग्री प्राप्त कर सकते हैं getBytesऔर आप फ़ाइल का उपयोग करके लिख सकते हैं Files.newOutputStream():

public void write(MultipartFile file, Path dir) {
    Path filepath = Paths.get(dir.toString(), file.getOriginalFilename());

    try (OutputStream os = Files.newOutputStream(filepath)) {
        os.write(file.getBytes());
    }
}

आप transferTo विधि का भी उपयोग कर सकते हैं :

public void multipartFileToFile(
    MultipartFile multipart, 
    Path dir
) throws IOException {
    Path filepath = Paths.get(dir.toString(), multipart.getOriginalFilename());
    multipart.transferTo(filepath);
}

7
मैं TransferTo फ़ंक्शन का उपयोग करता हूं लेकिन मुझे लगता है कि कोई समस्या है। जैसे यह स्थानीय मशीन के लिए ड्राइव करने के लिए अस्थायी फ़ाइल रखता है।
मोरेज़

@ रॉनी मैं एक ही मुद्दा रहा हूँ। क्या आपको कोई वर्कअराउंड मिला है?
हाफ ब्लड प्रिंस

1
org.apache.commons.io.FileUtils.deleteQuietly (convFile.getParentFile ()); , यह अस्थायी फ़ाइल @Ronnie
कविंदर

5
createNewFIle()यहाँ व्यर्थ और बेकार दोनों है। अब आप new FileOutputStream()(OS के माध्यम से) दोनों बना रहे हैं ताकि बनाई गई फ़ाइल को हटा दें और एक नया बनाएं।
लोर्ने

@Petros Tsialiamanis क्या इसकी जावा में कोई फ़ाइल रूपांतरण आकार सीमा है। मान लीजिए कि मैं 3GB फ़ाइल का उपयोग कर रहा हूं।
रोहित

17

@PetrosTsialiamanis पोस्ट पर छोटा सुधार, new File( multipart.getOriginalFilename())यह सर्वर स्थान में फ़ाइल बनाएगा जहाँ कुछ समय के लिए आपको उपयोगकर्ता के लिए अनुमति संबंधी समस्याओं का सामना करना पड़ेगा, इसके लिए हर उस उपयोगकर्ता को लिखित अनुमति देना संभव नहीं है जो कार्रवाई करता है। System.getProperty("java.io.tmpdir")अस्थायी निर्देशिका बनाएगा जहाँ आपकी फ़ाइल ठीक से बनाई जाएगी। इस तरह से आप अस्थायी फ़ोल्डर बना रहे हैं, जहाँ फ़ाइल बनाई जाती है, बाद में आप फ़ाइल या अस्थायी फ़ोल्डर को हटा सकते हैं।

public  static File multipartToFile(MultipartFile multipart, String fileName) throws IllegalStateException, IOException {
    File convFile = new File(System.getProperty("java.io.tmpdir")+"/"+fileName);
    multipart.transferTo(convFile);
    return convFile;
}

इस विधि को उर कॉमन यूटिलिटी में रखें और उदाहरण के लिए इसका उपयोग करें। Utility.multipartToFile(...)


16

यद्यपि स्वीकृत उत्तर सही है, लेकिन यदि आप अपनी छवि को केवल क्लाउड पर अपलोड करने का प्रयास कर रहे हैं, तो एक बेहतर तरीका है:

Map upload = cloudinary.uploader().upload(multipartFile.getBytes(), ObjectUtils.emptyMap());

जहाँ MultartFile आपका org हैSpringframework.web.multipart.MultipartFile


8

आप Apache Commons IO लाइब्रेरी और FileUtils क्लास का भी उपयोग कर सकते हैं । यदि आप मावेन का उपयोग कर रहे हैं तो आप उपरोक्त निर्भरता का उपयोग करके इसे लोड कर सकते हैं।

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

MultipartFile के लिए स्रोत डिस्क पर सहेजें।

File file = new File(directory, filename);

// Create the file using the touch method of the FileUtils class.
// FileUtils.touch(file);

// Write bytes from the multipart file to disk.
FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());

FileUtils.touch()यहाँ व्यर्थ और बेकार दोनों है। अब आप new FileOutputStream()(OS के माध्यम से) दोनों बना रहे हैं ताकि बनाई गई फ़ाइल को हटा दें और एक नया बनाएं।
लोर्न

आपकी टिप्पणी के लिये धन्यवाद। मैंने विधि के स्रोत की जाँच की FileUtils.writeByteArrayToFile। मुझे लगता है कि यह विधि मौजूद नहीं होने पर फ़ाइल को दोबारा नहीं बना रही है (संस्करण 2.4)। मल्टिपार्टफ़ाइल ऑब्जेक्ट में अपलोड की गई फ़ाइल के बाइट्स शामिल हैं जिन्हें हम फाइल सिस्टम में कहीं स्टोर करना चाहते हैं। मेरा उद्देश्य इस बाइट्स को पसंदीदा स्थान पर संग्रहीत करना है। FileUtils.touch पद्धति को रखने का एकमात्र कारण यह स्पष्ट करना है कि यह एक नई फ़ाइल है। FileUtils.writeByteArrayToFile फ़ाइल बनाता है (और पूर्ण पथ) के मामले में यह मौजूद नहीं है इसलिए FileUtils.touch की आवश्यकता नहीं है।
जॉर्ज सिगुरोग्लोगो

7

MultipartFile.transferTo (फ़ाइल) अच्छा है, लेकिन सभी के बाद अस्थायी फ़ाइल को साफ करने के लिए मत भूलना।

// ask JVM to ask operating system to create temp file
File tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_POSTFIX);

// ask JVM to delete it upon JVM exit if you forgot / can't delete due exception
tempFile.deleteOnExit();

// transfer MultipartFile to File
multipartFile.transferTo(tempFile);

// do business logic here
result = businessLogic(tempFile);

// tidy up
tempFile.delete();

JVM निकास (जो अत्यंत दुर्लभ हो सकता है) विवरण के नीचे दिए गए File.deleteOnExit () के बारे में Razzlero की टिप्पणी देखें।


2
deleteOnExit(), यह केवल तब ही ट्रिगर होगा जब JVM समाप्त हो जाएगा, इसलिए यह अपवादों के दौरान ट्रिगर नहीं होगा। इस वजह से आपको deleteOnExit()सर्वर एप्लिकेशन जैसे लंबे समय तक चलने वाले एप्लिकेशन का उपयोग करने में सावधानी बरतने की आवश्यकता है । सर्वर अनुप्रयोगों के लिए जेवीएम शायद ही कभी बाहर निकल जाएगा। इसलिए आपको deleteOnExit()मेमोरी लीक होने से सावधान रहने की जरूरत है । JVM को उन सभी फाइलों पर नज़र रखने की ज़रूरत है, जिन्हें बाहर निकलने पर हटाने की ज़रूरत होती है, जिन्हें साफ़ नहीं किया जाता क्योंकि JVM समाप्त नहीं होता है।
रज्जेलो

@Razzlero यह इंगित करने के लिए धन्यवाद कि यह केवल JVM निकास पर फ़ाइलें हटाता है। हालाँकि यह मेमोरी लीक नहीं है, यह डिज़ाइन के अनुसार काम करता है।
andrej

5
  private File convertMultiPartToFile(MultipartFile file ) throws IOException
    {
        File convFile = new File( file.getOriginalFilename() );
        FileOutputStream fos = new FileOutputStream( convFile );
        fos.write( file.getBytes() );
        fos.close();
        return convFile;
    }

यह अपवाद देना java.io.FileNotFoundException: multipdf.pdf (अनुमति अस्वीकृत)
नवनाथ

1

यदि इंटरफ़ेस MultipartFileका वर्ग है, तो आप कास्टिंग के द्वारा स्प्रिंग में टेंपफ़ाइल का उपयोग कर सकते हैं CommonsMultipartFile

public File getTempFile(MultipartFile multipartFile)
{
    CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
    FileItem fileItem = commonsMultipartFile.getFileItem();
    DiskFileItem diskFileItem = (DiskFileItem) fileItem;
    String absPath = diskFileItem.getStoreLocation().getAbsolutePath();
    File file = new File(absPath);

    //trick to implicitly save on disk small files (<10240 bytes by default)
    if (!file.exists()) {
        file.createNewFile();
        multipartFile.transferTo(file);
    }

    return file;
}

10240 बाइट से कम फ़ाइलों वाली ट्रिक से छुटकारा पाने के लिए क्लास maxInMemorySizeमें प्रॉपर्टी को 0 पर सेट किया जा सकता है @Configuration @EnableWebMvc। उसके बाद, सभी अपलोड की गई फ़ाइलों को डिस्क पर संग्रहीत किया जाएगा।

@Bean(name = "multipartResolver")
    public CommonsMultipartResolver createMultipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        resolver.setMaxInMemorySize(0);
        return resolver;
    }

2
createNewFIle()यहाँ व्यर्थ और बेकार दोनों है। अब आप new FileOutputStream()(OS के माध्यम से) दोनों बना रहे हैं ताकि बनाई गई फ़ाइल को हटा दें और एक नया बनाएं।
लोर्न

@ ईजेपी हाँ, यह व्यर्थ था, अब मैं संपादन करते समय की गई इस गलती को ठीक करता हूँ। लेकिन createNewFIle () बेकार नहीं है, क्योंकि यदि CommonsMultipartFile 10240 बाइट्स से कम है, तो फ़ाइल सिस्टम में फ़ाइल नहीं बनाई गई है। इसलिए एफएस में किसी भी अनूठे नाम के साथ एक नई फ़ाइल (मैंने डिस्क्लेफाइइटेम का नाम इस्तेमाल किया है) बनाई जानी चाहिए।
एलेक्स78191

@ एलेक्स78191 डिस्क छोटी फ़ाइलों पर स्पष्ट रूप से सहेजने से आपका क्या मतलब है (<डिफ़ॉल्ट रूप से 10240 बाइट्स)। वहाँ वैसे भी सीमा बढ़ाने के लिए है
आनंद टैगोर

@AnandTagore मेरा मतलब है कि MultipartFile की 10240 बाइट्स फ़ाइल सिस्टम में सेव नहीं हो रही हैं, इसलिए फ़ाइलें मैन्युअल रूप से बनाई जानी चाहिए।
15:78 पर एलेक्स78191

0

एलेक्स78191 के जवाब ने मेरे लिए काम किया है।

public File getTempFile(MultipartFile multipartFile)
{

CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
FileItem fileItem = commonsMultipartFile.getFileItem();
DiskFileItem diskFileItem = (DiskFileItem) fileItem;
String absPath = diskFileItem.getStoreLocation().getAbsolutePath();
File file = new File(absPath);

//trick to implicitly save on disk small files (<10240 bytes by default)

if (!file.exists()) {
    file.createNewFile();
    multipartFile.transferTo(file);
}

return file;
}

10240 बाइट्स से अधिक आकार वाली फाइलें अपलोड करने के लिए कृपया अधिकतमInMemorySize को multipartResolver में 1MB पर बदलें।

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size t 20MB -->
<property name="maxUploadSize" value="20971520" />
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" />
<!-- 1MB --> </bean>

maxInMemorySizeफ़ाइल अपलोड आकार पर सीमा से कोई लेना-देना नहीं है। फ़ाइल अपलोड आकार maxUploadSizeसंपत्ति द्वारा निर्धारित किया गया है।
एलेक्स78191

10240 बाइट्स से कम फ़ाइलों वाली चाल से छुटकारा पाने के लिए maxInMemorySizeसेट किया जा सकता है 0
एलेक्स78191

@ एलेक्स78191 मैंने इसे बदल दिया है और इसने मेरे लिए काम किया। मैंने फ़ाइल को परिवर्तित करने के लिए आपके कोड का उपयोग किया था। इसलिए मैंने मेमोरी सीमाओं से छुटकारा पाने के लिए Applicationcontext.xml में गुणों को बदल दिया। और यह काम करता है !!!
आनंद टैगोर

मल्टीपार्ट फाइल से फाइल बनाते समय इसे मेमोरी में रखना चाहिए। तो इसके लिए मुझे मैक्सिममोरी को बढ़ाना होगा।
आनंद टैगोर

0

यदि आप MultipartFile.transferTo () का उपयोग नहीं करना चाहते हैं। आप इस तरह फाइल लिख सकते हैं

    val dir = File(filePackagePath)
    if (!dir.exists()) dir.mkdirs()

    val file = File("$filePackagePath${multipartFile.originalFilename}").apply {
        createNewFile()
    }

    FileOutputStream(file).use {
        it.write(multipartFile.bytes)
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.