Recursive file search for designated extension - java

I am using SMBClient to connect to my SMB server with Java.
How can I recursively scan my entire SMB share to get a listing of all files with an .mp4 extension?
This is my code that only scans the one designated directory:
private void btnFileCountActionPerformed(java.awt.event.ActionEvent evt) {
SMBClient client = new SMBClient();
try (Connection connection = client.connect("192.168.X.XXX")) {
AuthenticationContext ac = new AuthenticationContext("XXXXXXX#hotmail.com", "XXXXXX".toCharArray(), "Mastafin");
Session session = connection.authenticate(ac);
try (DiskShare share = (DiskShare) session.connectShare("Folder With Spaces")) {
for (FileIdBothDirectoryInformation f : share.list("LOTS OF SUBDIRS TO SCAN", "*.mp4")) {
System.out.println("File : " + f.getFileName());
}
} catch (Exception e) {
System.out.println(e);
}
} catch (Exception e) {
System.out.println(e);
}
}

Here are some fairly straightforward tweaks to your code to get it to fill an ArrayList recursively. It isn't necessarily the most efficient way of doing this, as it gathers all filenames, and then throws away the ones that don't end with .mp4, but it should give you a straightforward place to start building from.
private void btnFileCountActionPerformed(java.awt.event.ActionEvent evt) {
try (SMBClient client = new SMBClient()) {
try (Connection connection = client.connect(SERVER)) {
AuthenticationContext ac = new AuthenticationContext(USERNAME, PASSWORD.toCharArray(), WORKGROUP);
try (Session session = connection.authenticate(ac)) {
try (DiskShare share = (DiskShare) session.connectShare(SHARE)) {
List<String> files = new ArrayList<>();
listFiles(share, START_DIR, files);
files.removeIf(name -> !name.toLowerCase().endsWith(".mp4"));
files.forEach(System.out::println);
}
}
}
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
private void listFiles(DiskShare share, String path, Collection<String> files) {
List<String> dirs = new ArrayList<>();
String extPath = path.isEmpty() ? path : path + "\\";
for (FileIdBothDirectoryInformation f : share.list(path)) {
if ((f.getFileAttributes() & FileAttributes.FILE_ATTRIBUTE_DIRECTORY.getValue()) != 0) {
if (!isSpecialDir(f.getFileName())) {
dirs.add(f.getFileName());
}
} else {
files.add(extPath + f.getFileName());
}
}
dirs.forEach(dir -> listFiles(share, extPath + dir, files));
}
private static boolean isSpecialDir(String fileName) {
return fileName.equals(".") || fileName.equals("..");
}

Related

Why can't my web client accept an image from my web server?

I this is my java HTTP server:
public class WebServer implements Runnable {
public static final int PORT = 80;
#Override
public void run() {
HttpServer $server;
try {
$server = HttpServer.create(new InetSocketAddress(80), 0);
} catch (IOException _e) {
throw new RuntimeException(_e);
}
$server.createContext("/", _httpExchange ->
{
String $uri = _httpExchange.getRequestURI().toString();
$uri = $uri.startsWith("/") ? $uri.replaceFirst("/", "") : $uri;
if ($uri.equals("")) {
sendFile("test.html", _httpExchange);
}
else if ($uri.matches(".*\\.[^/.]+")) {
sendFile($uri, _httpExchange);
}
else {
sendFile($uri + ".html", _httpExchange);
}
});
$server.start();
System.out.println("Server started at " + getPrivateIp() + " on port " + PORT);
}
private static String getPrivateIp() {
try (final DatagramSocket datagramSocket = new DatagramSocket()) {
datagramSocket.connect(InetAddress.getByName("8.8.8.8"), 12345);
return datagramSocket.getLocalAddress().getHostAddress();
} catch (UnknownHostException | SocketException _e) {
throw new RuntimeException(_e);
}
}
public static void sendFile(String _name, HttpExchange _exchange) throws IOException {
try {
InputStream $stream = WebServer.class.getResourceAsStream(_name);
if ($stream == null) {
_exchange.sendResponseHeaders(404, 0);
_exchange.close();
return;
}
Scanner $scanner = new Scanner($stream).useDelimiter("\\A");
String $response = $scanner.next();
_exchange.getResponseBody();
_exchange.sendResponseHeaders(200, $response.getBytes().length);
_exchange.getResponseBody().write($response.getBytes());
_exchange.close();
} catch (Exception _ex) {
throw new RuntimeException(_ex);
}
}
}
When I run it, and then open my website, everything is ok, but I cannot see any images. In the network tab, it says that the image was accepted, but it's not shown. I tried using Files.copy() in sendFile() method, but it didn't work - it didn't show the website, nor the image! (Not even when I did localhost/image.jpg).
In the network tab, it also shows that the MIME type is img/jpeg, which is correct, so it's not because of that...
Using wget, I get a normal looking .jpg file, but if I open it, it's corrupted...
Does someone know how to fix this?
Thanks.
Solved it!
You just check if the request wants .png or .jpg file (or you can just check the MIME type), and if it does, then you have to use ImageIO class
public static void sendFile(String _name, HttpExchange _exchange) {
try {
InputStream $stream = WebServer.class.getResourceAsStream(_name);
if ($stream == null) {
_exchange.sendResponseHeaders(404, 0);
_exchange.close();
return;
}
if (_name.matches(".*?\\.(png|PNG|jpg|JPG|jpeg|JPEG)")) {
BufferedImage $image = ImageIO.read($stream);
if (_name.toLowerCase().endsWith("png")) {
_exchange.sendResponseHeaders(200, getImageSize($image, "png"));
ImageIO.write($image, "png", _exchange.getResponseBody());
}
else {
_exchange.sendResponseHeaders(200, getImageSize($image,"jpeg"));
ImageIO.write($image, "jpeg", _exchange.getResponseBody());
}
$stream.close();
_exchange.close();
return;
}
Scanner $scanner = new Scanner($stream).useDelimiter("$");
String $response = $scanner.next();
_exchange.getResponseBody();
_exchange.sendResponseHeaders(200, $response.length());
_exchange.getResponseBody().write($response.getBytes());
_exchange.close();
} catch (Exception _ex) {
throw new RuntimeException(_ex);
}
}

Why can't I add text to a file in Java? [duplicate]

This question already has answers here:
How to append text to an existing file in Java?
(31 answers)
Closed 3 years ago.
It seems that its creating a new file always I try to write or read.
Each line starts with the name of the player, if exists the player should add the score at the end, if not creates a new line and write the info.
.......................
public class JogadorData {
private String nome_player;
private Scanner is;
private FileWriter os;
// this file exists
private final String path = "src/Data/JogadorData";
public JogadorData(String nome_player) {
this.nome_player = nome_player;
try {
is = new Scanner(new File(path));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
os = new FileWriter(path);
} catch (IOException e) {
e.printStackTrace();
}
}
public void escreverScore(String score) {
if (jogadorNovo(nome_player)) {
try {
os.write(nome_player + " " + score);
} catch (IOException e) {
e.printStackTrace();
}
}
else {
escreverResultadoJogadorExistente(score);
}
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// returns true if it is a new player
private boolean jogadorNovo(String nome_player) {
while (is.hasNextLine()) {
String linha = is.nextLine();
String[] info = linha.split(" ");
if (info[0].equals(nome_player)) {
return false;
}
}
return true;
}
}
....................................
....................................
Test:
public class TESTE {
public static void main(String[] args) {
JogadorData jogador = new JogadorData("Manelina");
jogador.escreverScore("100");
// System.out.println(jogador.lerMelhorResultado());
}
}
The example below is a simplified read/write to file from what you have, done in similar format to what you are trying to do. What this code does is reads every line from the file you are loading from via Files#readAllLines, then runs through each line, (put your logic where I commented the if statement, and then output.add appends the new version of the line you are modifying, storing it in the array list "output", after which the file is saved to the path defined by Files#write
List<String> output = new ArrayList<>();
List<String> lines = Files.readAllLines(Paths.get("Path/To/File.txt"));
for (String line : lines) {
//... if (playerExists(line))
output.add(line + " " + score);
}
Files.write(Paths.get("Path/To/Save/File.txt"), output);

JSP - Running a program with main method and nested static class

I'm a novice when it comes to JSPs and JAVA.
How do I get the output from the below code to display on a jsp, considering that it runs everything from the main and contains non-public methods, a nested static class etc?
I know that we are not supposed to use java code on jsp but my first step in this proof on concept exercise is to get the code running and returning data from a backend then I can set about using EL etc.
I can run the program, with the correct config settings, from within Eclipse and all works fine with the output appearing on the console but I'm really not sure how to access it from within a jsp.
How do I access the static class and static methods from a jsp if they aren't public?
All help greatly appreciated.
public class CustomDestinationDataProvider
{
static class MyDestinationDataProvider implements DestinationDataProvider
{
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName)
{
try
{
//read the destination from DB
Properties p = secureDBStorage.get(destinationName);
if(p!=null)
{
//check if all is correct, for example
if(p.isEmpty())
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
return p;
}
return null;
}
catch(RuntimeException re)
{
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener)
{
this.eL = eventListener;
}
public boolean supportsEvents()
{
return true;
}
//implementation that saves the properties in a very secure way
void changeProperties(String destName, Properties properties)
{
synchronized(secureDBStorage)
{
if(properties==null)
{
if(secureDBStorage.remove(destName)!=null)
eL.deleted(destName);
}
else
{
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
} // end of MyDestinationDataProvider
//business logic
void executeCalls(String destName)
{
JCoDestination dest;
try
{
dest = JCoDestinationManager.getDestination(destName);
dest.ping();
System.out.println("Destination " + destName + " works");
step4WorkWithTable(dest);
}
catch(JCoException e)
{
e.printStackTrace();
System.out.println("Execution on destination " + destName+ " failed");
}
}
static Properties getDestinationPropertiesFromUI()
{
//adapt parameters in order to configure a valid destination
Properties connectProperties = new Properties();
// Add code here to set config settings
return connectProperties;
}
public static void main(String[] args)
{
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
//register the provider with the JCo environment;
//catch IllegalStateException if an instance is already registered
try
{
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
}
catch(IllegalStateException providerAlreadyRegisteredException)
{
//somebody else registered its implementation,
//stop the execution
throw new Error(providerAlreadyRegisteredException);
}
String destName = "????";
CustomDestinationDataProvider test = new CustomDestinationDataProvider();
//set properties for the destination and ...
myProvider.changeProperties(destName, getDestinationPropertiesFromUI());
//... work with it
test.executeCalls(destName);
}
public static void step4WorkWithTable(JCoDestination dest) throws JCoException
{
JCoFunction function = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST");
if(function == null)
throw new RuntimeException("BAPI_COMPANYCODE_GETLIST not found in SAP.");
try
{
function.execute(dest);
}
catch(AbapException e)
{
System.out.println(e.toString());
return;
}
JCoStructure returnStructure = function.getExportParameterList().getStructure("RETURN");
if (! (returnStructure.getString("TYPE").equals("")||returnStructure.getString("TYPE").equals("S")) )
{
throw new RuntimeException(returnStructure.getString("MESSAGE"));
}
JCoTable codes = function.getTableParameterList().getTable("COMPANYCODE_LIST");
for (int i = 0; i < codes.getNumRows(); i++)
{
codes.setRow(i);
System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME"));
}
//move the table cursor to first row
codes.firstRow();
for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow())
{
function = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
if (function == null)
throw new RuntimeException("BAPI_COMPANYCODE_GETDETAIL not found in SAP.");
function.getImportParameterList().setValue("COMPANYCODEID", codes.getString("COMP_CODE"));
//We do not need the addresses, so set the corresponding parameter to inactive.
//Inactive parameters will be either not generated or at least converted.
function.getExportParameterList().setActive("COMPANYCODE_ADDRESS",false);
try
{
function.execute(dest);
}
catch (AbapException e)
{
System.out.println(e.toString());
return;
}
returnStructure = function.getExportParameterList().getStructure("RETURN");
if (! (returnStructure.getString("TYPE").equals("") ||
returnStructure.getString("TYPE").equals("S") ||
returnStructure.getString("TYPE").equals("W")) )
{
throw new RuntimeException(returnStructure.getString("MESSAGE"));
}
JCoStructure detail = function.getExportParameterList().getStructure("COMPANYCODE_DETAIL");
System.out.println(detail.getString("COMP_CODE") + '\t' +
detail.getString("COUNTRY") + '\t' +
detail.getString("CITY"));
}//for
}
}

How to filter a particular directory and copy the rest of the folders in java

I am trying to copy folders and files which is working fine but I need help on how to filter a single folder and copy the rest of the folders. For example, I have directories like carsfolder and truckfolder in(C:\vehicle\carsfolder and C:\vehicle\truckfolder). When I use the below code it copies both carsfolder and truckfolder but I wanted to copy only carsfolder. How can I do that. Your help is highly appreciated.(Using Swing and Java 1.6)
class CopyTask extends SwingWorker<Void, Integer>
{
private File source;
private File target;
private long totalBytes = 0;
private long copiedBytes = 0;
public CopyTask(File src, File dest)
{
this.source = src;
this.target = dest;
progressAll.setValue(0);
}
#Override
public Void doInBackground() throws Exception
{
ta.append("Retrieving info ... "); //append to TextArea
retrieveTotalBytes(source);
ta.append("Done!\n");
copyFiles(source, target);
return null;
}
#Override
public void process(List<Integer> chunks)
{
for(int i : chunks)
{
}
}
#Override
public void done()
{
setProgress(100);
}
private void retrieveTotalBytes(File sourceFile)
{
try
{
File[] files = sourceFile.listFiles();
for(File file : files)
{
if(file.isDirectory()) retrieveTotalBytes(file);
else totalBytes += file.length();
}
}
catch(Exception ee)
{
}
}
private void copyFiles(File sourceFile, File targetFile) throws IOException
{
if(sourceFile.isDirectory())
{
try{
if(!targetFile.exists()) targetFile.mkdirs();
String[] filePaths = sourceFile.list();
for(String filePath : filePaths)
{
File srcFile = new File(sourceFile, filePath);
File destFile = new File(targetFile, filePath);
copyFiles(srcFile, destFile);
}
}
catch(Exception ie)
{
}
}
else
{
try
{
ta.append("Copying " + sourceFile.getAbsolutePath() + " to " + targetFile.getAbsolutePath() );
bis = new BufferedInputStream(new FileInputStream(sourceFile));
bos = new BufferedOutputStream(new FileOutputStream(targetFile));
long fileBytes = sourceFile.length();
long soFar = 0;
int theByte;
while((theByte = bis.read()) != -1)
{
bos.write(theByte);
setProgress((int) (copiedBytes++ * 100 / totalBytes));
publish((int) (soFar++ * 100 / fileBytes));
}
bis.close();
bos.close();
publish(100);
ta.append(" Done!\n");
}
catch(Exception excep)
{
setProgress(0);
bos.flush();
bis.close();
bos.close();
}
finally{
try {
bos.flush();
}
catch (Exception e) {
}
try {
bis.close();
}
catch (Exception e) {
}
try {
bos.close();
}
catch (Exception e) {
}
}
}
}
}
Maybe you can introduce a regex or list of regexes that specify which files and dirs to exclude?
For example, to exclude truckfolder, use a "exclusion" regex like "C:\\vehicle\\truckfolder.*".
Then, in your code, before you copy anything, check to make sure the absolute path of the sourcefile doesn't match the exclusion regex(s).

A properties file I created in the 1st run gets blanked in the 2nd run

Okay, I'm trying to create a custom client for Minecraft (don't worry, my question has nothing to do with Minecraft in particular), and I added an abstract class to manage a configuration file using Java's built-in Properties system. I have a method that loads a properties file or creates it if it doesn't already exist. This method is called at the beginning of all my other methods (although it only does anything the first time its called).
The properties file gets created just fine when I run Minecraft the first time, but somehow when I run it the second time, the file gets blanked out. I'm not sure where or why or how I'm wiping the file clean, can someone please help me? Here's my code; the offending method is loadConfig():
package net.minecraft.src;
import java.util.*;
import java.util.regex.*;
import java.io.*;
/**
* Class for managing my custom client's properties
*
* #author oxguy3
*/
public abstract class OxProps
{
public static boolean configloaded = false;
private static Properties props = new Properties();
private static String[] usernames;
public static void loadConfig() {
System.out.println("loadConfig() called");
if (!configloaded) {
System.out.println("loading config for the first time");
File cfile = new File("oxconfig.properties");
boolean configisnew;
if (!cfile.exists()) {
System.out.println("cfile failed exists(), creating blank file");
try {
configisnew = cfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
configisnew=true;
}
} else {
System.out.println("cfile passed exists(), proceding");
configisnew=false;
}
FileInputStream cin = null;
FileOutputStream cout = null;
try {
cin = new FileInputStream(cfile);
cout = new FileOutputStream(cfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!configisnew) { //if the config already existed
System.out.println("config already existed");
try {
props.load(cin);
} catch (IOException e) {
e.printStackTrace();
}
} else { //if it doesn't exist, and therefore needs to be created
System.out.println("creating new config");
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
try {
props.store(cout, "OXGUY3'S CUSTOM CLIENT\n\ncloak_url is the URL to get custom cloaks from\nnames are the usernames to give cloaks to\n");
cout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
String names = props.getProperty("names");
System.out.println("names: "+names);
try {
usernames = Pattern.compile(", ").split(names);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("usernames: "+Arrays.toString(usernames));
configloaded=true;
}
}
public static boolean checkUsername(String username) {
loadConfig();
System.out.println("Checking username...");
for (int i=0; i<usernames.length; i++) {
System.out.println("comparing "+username+" with config value "+usernames[i]);
if (username.startsWith(usernames[i])){
System.out.println("we got a match!");
return true;
}
}
System.out.println("no match found");
return false;
}
public static String getCloakUrl() {
loadConfig();
return props.getProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
}
}
If it's too hard to read here, it's also on Pastebin: http://pastebin.com/9UscXWap
Thanks!
You are unconditionally creating new FileOutputStream(cfile). This will overwrite the existing file with an empty one. You should only invoke the FileOutputStream constructor when writing a new config file.
if (configloaded)
return;
File cfile = new File("oxconfig.properties");
try {
if (cfile.createNewFile()) {
try {
FileOutputStream cout = new FileOutputStream(cfile);
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://...");
...
cout.flush();
} finally {
cout.close();
}
} else {
FileInputStream cin = new FileInputStream(cfile);
try {
props.load(cin);
} finally {
cin.close();
}
}
configloaded=true;
} catch(IOException ex) {
e.printStackTrace();
}

Categories